Re: [PATCH v2 13/40] vfio: Add support for Shared Virtual Addressing

2018-05-25 Thread Xu Zaibo

Hi,

On 2018/5/25 17:47, Jean-Philippe Brucker wrote:

On 25/05/18 03:39, Xu Zaibo wrote:

Hi,

On 2018/5/24 23:04, Jean-Philippe Brucker wrote:

On 24/05/18 13:35, Xu Zaibo wrote:

Right, sva_init() must be called once for any device that intends to use
bind(). For the second process though, group->sva_enabled will be true
so we won't call sva_init() again, only bind().

Well, while I create mediated devices based on one parent device to support 
multiple
processes(a new process will create a new 'vfio_group' for the corresponding 
mediated device,
and 'sva_enabled' cannot work any more), in fact, *sva_init and *sva_shutdown 
are basically
working on parent device, so, as a result, I just only need sva initiation and 
shutdown on the
parent device only once. So I change the two as following:

@@ -551,8 +565,18 @@ int iommu_sva_device_init(struct device *dev, unsigned 
long features,
if (features & ~IOMMU_SVA_FEAT_IOPF)
   return -EINVAL;

+/* If already exists, do nothing  */
+mutex_lock(>iommu_param->lock);
+if (dev->iommu_param->sva_param) {
+mutex_unlock(>iommu_param->lock);
+return 0;
+}
+mutex_unlock(>iommu_param->lock);

   if (features & IOMMU_SVA_FEAT_IOPF) {
   ret = iommu_register_device_fault_handler(dev, iommu_queue_iopf,


@@ -621,6 +646,14 @@ int iommu_sva_device_shutdown(struct device *dev)
   if (!domain)
   return -ENODEV;

+/* If any other process is working on the device, shut down does nothing. 
*/
+mutex_lock(>iommu_param->lock);
+if (!list_empty(>iommu_param->sva_param->mm_list)) {
+mutex_unlock(>iommu_param->lock);
+return 0;
+}
+mutex_unlock(>iommu_param->lock);

I don't think iommu-sva.c is the best place for this, it's probably
better to implement an intermediate layer (the mediating driver), that
calls iommu_sva_device_init() and iommu_sva_device_shutdown() once. Then
vfio-pci would still call these functions itself, but for mdev the
mediating driver keeps a refcount of groups, and calls device_shutdown()
only when freeing the last mdev.

A device driver (non mdev in this example) expects to be able to free
all its resources after sva_device_shutdown() returns. Imagine the
mm_list isn't empty (mm_exit() is running late), and instead of waiting
in unbind_dev_all() below, we return 0 immediately. Then the calling
driver frees its resources, and the mm_exit callback along with private
data passed to bind() disappear. If a mm_exit() is still running in
parallel, then it will try to access freed data and corrupt memory. So
in this function if mm_list isn't empty, the only thing we can do is wait.


I still don't understand why we should 'unbind_dev_all', is it possible
to do a 'unbind_dev_pasid'?

Not in sva_device_shutdown(), it needs to clean up everything. For
example you want to physically unplug the device, or assign it to a VM.
To prevent any leak sva_device_shutdown() needs to remove all bonds. In
theory there shouldn't be any, since either the driver did unbind_dev(),
or all process exited. This is a safety net.


Then we can do other things instead of waiting that user may not like. :)

They may not like it, but it's for their own good :) At the moment we're
waiting that:

* All exit_mm() callback for this device have finished. If we don't wait
   then the caller will free the private data passed to bind and the
   mm_exit() callback while they are still being used.

* All page requests targeting this device are dealt with. If we don't
   wait then some requests, that are lingering in the IOMMU PRI queue,
   may hit the next contexts bound to this device, possibly in a
   different VM. It may not be too risky (though probably exploitable in
   some way), but is incredibly messy.

All of this is bounded in time, and normally should be over pretty fast
unless the device driver's exit_mm() does something strange. If the
driver did the right thing, there shouldn't be any wait here (although
there may be one in unbind_dev() for the same reasons - prevent use
after free).


I guess there may be some misunderstandings :).

From the current patches, '/iommu_sva_device_shutdown/' is called by 
'/vfio_iommu_sva_shutdown/', which
is mainly used by '/vfio_iommu_type1_detach_group/' that is finally 
called by processes' release of vfio facilitiy
automatically or called by 'VFIO_GROUP_UNSET_CONTAINER' manually in the 
processes.


So, just image that 2 processes is working on the device with IOPF 
feature, and the 2 do the following to enable SVA:


/1.open("/dev/vfio/vfio") ;//
//
//   2.open the group of the devcie by calling open("/dev/vfio/x"), but 
now, //
// I think the second processes will fail to open the group because 
current VFIO thinks that one group only can be used by one process/vm,
 at present, I use mediated device to create more groups on the 
parent device to support multiple processes;//

/ //

/3.VFIO_GROUP_SET_CONTAINER;/

/

Re: [PATCH v2 03/40] iommu/sva: Manage process address spaces

2018-05-25 Thread Kenneth Lee
On Fri, May 25, 2018 at 09:39:59AM +0100, Jonathan Cameron wrote:
> Date: Fri, 25 May 2018 09:39:59 +0100
> From: Jonathan Cameron 
> To: Ilias Apalodimas 
> CC: Jean-Philippe Brucker ,
>  "xieyishe...@huawei.com" , "k...@vger.kernel.org"
>  , "linux-...@vger.kernel.org"
>  , "xuza...@huawei.com" ,
>  Will Deacon , "ok...@codeaurora.org"
>  , "linux...@kvack.org" ,
>  "yi.l@intel.com" , "ashok@intel.com"
>  , "t...@semihalf.com" ,
>  "j...@8bytes.org" , "robdcl...@gmail.com"
>  , "bhara...@xilinx.com" ,
>  "linux-a...@vger.kernel.org" ,
>  "liudongdo...@huawei.com" , "rfr...@cavium.com"
>  , "devicet...@vger.kernel.org"
>  , "kevin.t...@intel.com"
>  , Jacob Pan ,
>  "alex.william...@redhat.com" ,
>  "rgum...@xilinx.com" , "thunder.leiz...@huawei.com"
>  , "linux-arm-ker...@lists.infradead.org"
>  , "shunyong.y...@hxt-semitech.com"
>  , "dw...@infradead.org"
>  , "liub...@huawei.com" ,
>  "jcro...@codeaurora.org" ,
>  "iommu@lists.linux-foundation.org" ,
>  Robin Murphy , "christian.koe...@amd.com"
>  , "nwatt...@codeaurora.org"
>  , "baolu...@linux.intel.com"
>  , liguo...@hisilicon.com,
>  kenneth-lee-2...@foxmail.com
> Subject: Re: [PATCH v2 03/40] iommu/sva: Manage process address spaces
> Message-ID: <20180525093959.4...@huawei.com>
> 
> +CC Kenneth Lee
> 
> On Fri, 25 May 2018 09:33:11 +0300
> Ilias Apalodimas  wrote:
> 
> > On Thu, May 24, 2018 at 04:04:39PM +0100, Jean-Philippe Brucker wrote:
> > > On 24/05/18 12:50, Ilias Apalodimas wrote:  
> > > >> Interesting, I hadn't thought about this use-case before. At first I
> > > >> thought you were talking about mdev devices assigned to VMs, but I 
> > > >> think
> > > >> you're referring to mdevs assigned to userspace drivers instead? Out of
> > > >> curiosity, is it only theoretical or does someone actually need this?  
> > > > 
> > > > There has been some non upstreamed efforts to have mdev and produce 
> > > > userspace
> > > > drivers. Huawei is using it on what they call "wrapdrive" for crypto 
> > > > devices and
> > > > we did a proof of concept for ethernet interfaces. At the time we 
> > > > choose not to
> > > > involve the IOMMU for the reason you mentioned, but having it there 
> > > > would be
> > > > good.  
> > > 
> > > I'm guessing there were good reasons to do it that way but I wonder, is
> > > it not simpler to just have the kernel driver create a /dev/foo, with a
> > > standard ioctl/mmap/poll interface? Here VFIO adds a layer of
> > > indirection, and since the mediating driver has to implement these
> > > operations already, what is gained?  
> > The best reason i can come up with is "common code". You already have one 
> > API
> > doing that for you so we replicate it in a /dev file?
> > The mdev approach still needs extentions to support what we tried to do (i.e
> > mdev bus might need yo have access on iommu_ops), but as far as i undestand 
> > it's
> > a possible case.

Hi, Jean, Please allow me to share my understanding here:
https://zhuanlan.zhihu.com/p/35489035

The reason we do not use the /dev/foo scheme is that the devices to be
shared are programmable accelerators. We cannot fix up the kernel driver for 
them.
> > > 
> > > Thanks,
> > > Jean  
> 
> 

-- 
-Kenneth Lee (Hisilicon)


___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 07/40] iommu: Add a page fault handler

2018-05-25 Thread Jacob Pan
On Thu, 24 May 2018 12:44:38 +0100
Jean-Philippe Brucker  wrote:

> On 23/05/18 00:35, Jacob Pan wrote:
>  +/* Insert *before* the last fault */
>  +list_move(>head, >faults);
>  +}
>  +
> >>> If you already sorted the group list with last fault at the end,
> >>> why do you need a separate entry to track the last fault?
> >>
> >> Not sure I understand your question, sorry. Do you mean why the
> >> iopf_group.last_fault? Just to avoid one more kzalloc.
> >>  
> > kind of :) what i thought was that why can't the last_fault
> > naturally be the last entry in your group fault list? then there is
> > no need for special treatment in terms of allocation of the last
> > fault. just my preference.  
> 
> But we need a kzalloc for the last fault anyway, so I thought I'd just
> piggy-back on the group allocation. And if I don't add the last fault
> at the end of group->faults, then it's iopf_handle_group that requires
> special treatment. I'm still not sure I understood your question
> though, could you send me a patch that does it?
> 
>  +
>  +queue->flush(queue->flush_arg, dev);
>  +
>  +/*
>  + * No need to clear the partial list. All PRGs
>  containing the PASID that
>  + * needs to be decommissioned are whole (the device
>  driver made sure of
>  + * it before this function was called). They have been
>  submitted to the
>  + * queue by the above flush().
>  + */
> >>> So you are saying device driver need to make sure LPIG PRQ is
> >>> submitted in the flush call above such that partial list is
> >>> cleared?
> >>
> >> Not exactly, it's the IOMMU driver that makes sure all LPIG in its
> >> queues are submitted by the above flush call. In more details the
> >> flow is:
> >>
> >> * Either device driver calls unbind()/sva_device_shutdown(), or the
> >> process exits.
> >> * If the device driver called, then it already told the device to
> >> stop using the PASID. Otherwise we use the mm_exit() callback to
> >> tell the device driver to stop using the PASID.
Sorry I still need more clarification. For the PASID termination
initiated by vfio unbind, I don't see device driver given a chance to
stop PASID. Seems just call __iommu_sva_unbind_device() which already
assume device stopped issuing DMA with the PASID.
So it is the vfio unbind caller responsible for doing driver callback
to stop DMA on a given PASID?

> >> * In either case, when receiving a stop request from the driver,
> >> the device sends the LPIGs to the IOMMU queue.
> >> * Then, the flush call above ensures that the IOMMU reports the
> >> LPIG with iommu_report_device_fault.
> >> * While submitting all LPIGs for this PASID to the work queue,
> >> ipof_queue_fault also picked up all partial faults, so the partial
> >> list is clean.
> >>
> >> Maybe I should improve this comment?
> >>  
> > thanks for explaining. LPIG submission is done by device
> > asynchronously w.r.t. driver stopping/decommission PASID.  
> 
> Hmm, it should really be synchronous, otherwise there is no way to
> know when the PASID can be decommissioned. We need a guarantee such
> as the one in 6.20.1 of the PCIe spec, "Managing PASID TLP Prefix
> Usage":
> 
> "When the stop request mechanism indicates completion, the Function
> has:
> * Completed all Non-Posted Requests associated with this PASID.
> * Flushed to the host all Posted Requests addressing host memory in
> all TCs that were used by the PASID."
> 
> That's in combination with "The function shall [...] finish
> transmitting any multi-page Page Request Messages for this PASID
> (i.e. send the Page Request Message with the L bit Set)." from the
> ATS spec.
> 
I am not contesting on the device side, what I meant was from the
host IOMMU driver perspective, LPIG is received via IOMMU host queue,
therefore asynchronous. Not sure about ARM, but on VT-d LPIG submission
could meet queue full condition. So per VT-d spec, iommu will generate a
successful auto response to the device. At this point, assume we
already stopped the given PASID on the device, there might not be
another LPIG sent for the device. Therefore, you could have a partial
list. I think we can just drop the requests in the partial list for
that PASID until the PASID gets re-allocated.


> (If I remember correctly a PRI Page Request is a Posted Request.) Only
> after this stop request completes can the driver call unbind(), or
> return from exit_mm(). Then we know that if there was a LPIG for that
> PASID, it is in the IOMMU's PRI queue (or already completed) once we
> call flush().
> 
agreed.
> > so if we were to use this
> > flow on vt-d, which does not stall page request queue, then we
> > should use the iommu model specific flush() callback to ensure LPIG
> > is received? There could be queue full condition and retry. I am
> > just trying to 

Re: [PATCH v6 0/7] vfio/type1: Add support for valid iova list management

2018-05-25 Thread Alex Williamson
On Fri, 25 May 2018 08:45:36 +
Shameerali Kolothum Thodi  wrote:

> Yes, the above changes related to list empty cases looks fine to me. 

Thanks Shameer, applied to my next branch with the discussed fixes for
v4.18 (modulo patch 4/7 which Joerg already pushed for v4.17).  Thanks,

Alex
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/7] core, dma-direct: add a flag 32-bit dma limits

2018-05-25 Thread Christoph Hellwig
On Fri, May 25, 2018 at 04:50:12PM +0200, Greg Kroah-Hartman wrote:
> On Fri, May 25, 2018 at 04:35:06PM +0200, Christoph Hellwig wrote:
> > Various PCI bridges (VIA PCI, Xilinx PCIe) limit DMA to only 32-bits
> > even if the device itself supports more.  Add a single bit flag to
> > struct device (to be moved into the dma extension once we around it)
> 
> "once we around it"?  I don't understand, sorry.

Should be "once we get around it", which in proper grammar should
probably be "once we get to it".  Anyway, the point is that right
now struct device is bloated with a lot of fields for dma/iommu
purposes and we need to clean this up.  It's been on my TODO list
for a while.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/7] core, dma-direct: add a flag 32-bit dma limits

2018-05-25 Thread Greg Kroah-Hartman
On Fri, May 25, 2018 at 04:35:06PM +0200, Christoph Hellwig wrote:
> Various PCI bridges (VIA PCI, Xilinx PCIe) limit DMA to only 32-bits
> even if the device itself supports more.  Add a single bit flag to
> struct device (to be moved into the dma extension once we around it)

"once we around it"?  I don't understand, sorry.

> to flag such devices and reject larger DMA to them.
> 
> Signed-off-by: Christoph Hellwig 
> ---
>  include/linux/device.h | 3 +++
>  lib/dma-direct.c   | 6 ++
>  2 files changed, 9 insertions(+)

For the patch, no objection from me:

Reviewed-by: Greg Kroah-Hartman 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 7/7] x86: switch the VIA 32-bit DMA quirk to use the struct device flag

2018-05-25 Thread Christoph Hellwig
Instead of globally disabling > 32bit DMA using the arch_dma_supported
hook walk the PCI bus under the actually affected bridge and mark every
device with the dma_32bit_limit flag.  This also gets rid of the
arch_dma_supported hook entirely.

Signed-off-by: Christoph Hellwig 
---
 arch/x86/include/asm/dma-mapping.h |  3 ---
 arch/x86/kernel/pci-dma.c  | 27 ++-
 include/linux/dma-mapping.h| 11 ---
 3 files changed, 10 insertions(+), 31 deletions(-)

diff --git a/arch/x86/include/asm/dma-mapping.h 
b/arch/x86/include/asm/dma-mapping.h
index 89ce4bfd241f..eb4e1352e403 100644
--- a/arch/x86/include/asm/dma-mapping.h
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -30,9 +30,6 @@ static inline const struct dma_map_ops 
*get_arch_dma_ops(struct bus_type *bus)
return dma_ops;
 }
 
-int arch_dma_supported(struct device *dev, u64 mask);
-#define arch_dma_supported arch_dma_supported
-
 bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp);
 #define arch_dma_alloc_attrs arch_dma_alloc_attrs
 
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index b5cbef974bd1..0d6fd0d1c14f 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -15,7 +15,7 @@
 #include 
 #include 
 
-static int forbid_dac __read_mostly;
+static bool disable_dac_quirk __read_mostly;
 
 const struct dma_map_ops *dma_ops = _direct_ops;
 EXPORT_SYMBOL(dma_ops);
@@ -129,7 +129,7 @@ static __init int iommu_setup(char *p)
if (!strncmp(p, "nodac", 5))
pr_warn("nodac option ignored.\n");
if (!strncmp(p, "usedac", 6)) {
-   forbid_dac = -1;
+   disable_dac_quirk = true;
return 1;
}
 #ifdef CONFIG_SWIOTLB
@@ -154,19 +154,6 @@ static __init int iommu_setup(char *p)
 }
 early_param("iommu", iommu_setup);
 
-int arch_dma_supported(struct device *dev, u64 mask)
-{
-#ifdef CONFIG_PCI
-   if (mask > 0x && forbid_dac > 0) {
-   dev_info(dev, "PCI: Disallowing DAC for device\n");
-   return 0;
-   }
-#endif
-
-   return 1;
-}
-EXPORT_SYMBOL(arch_dma_supported);
-
 static int __init pci_iommu_init(void)
 {
struct iommu_table_entry *p;
@@ -190,11 +177,17 @@ rootfs_initcall(pci_iommu_init);
 #ifdef CONFIG_PCI
 /* Many VIA bridges seem to corrupt data for DAC. Disable it here */
 
+static int via_no_dac_cb(struct pci_dev *pdev, void *data)
+{
+   pdev->dev.dma_32bit_limit = true;
+   return 0;
+}
+
 static void via_no_dac(struct pci_dev *dev)
 {
-   if (forbid_dac == 0) {
+   if (!disable_dac_quirk) {
dev_info(>dev, "disabling DAC on VIA PCI bridge\n");
-   forbid_dac = 1;
+   pci_walk_bus(dev->subordinate, via_no_dac_cb, NULL);
}
 }
 DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID,
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index f8ab1c0f589e..0249bce7c5e7 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -572,14 +572,6 @@ static inline int dma_mapping_error(struct device *dev, 
dma_addr_t dma_addr)
return 0;
 }
 
-/*
- * This is a hack for the legacy x86 forbid_dac and iommu_sac_force. Please
- * don't use this in new code.
- */
-#ifndef arch_dma_supported
-#define arch_dma_supported(dev, mask)  (1)
-#endif
-
 static inline void dma_check_mask(struct device *dev, u64 mask)
 {
if (sme_active() && (mask < (((u64)sme_get_me_mask() << 1) - 1)))
@@ -592,9 +584,6 @@ static inline int dma_supported(struct device *dev, u64 
mask)
 
if (!ops)
return 0;
-   if (!arch_dma_supported(dev, mask))
-   return 0;
-
if (!ops->dma_supported)
return 1;
return ops->dma_supported(dev, mask);
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 6/7] x86: remove the explicit nodac and allowdac option

2018-05-25 Thread Christoph Hellwig
This is something drivers should decide (modulo chipset quirks like
for VIA), which as far as I can tell is how things have been handled
for the last 15 years.

Note that we keep the usedac option for now, as it is used in the wild
to override the too generic VIA quirk.

Signed-off-by: Christoph Hellwig 
---
 Documentation/x86/x86_64/boot-options.txt | 5 -
 arch/x86/kernel/pci-dma.c | 4 ++--
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/Documentation/x86/x86_64/boot-options.txt 
b/Documentation/x86/x86_64/boot-options.txt
index 341588ec4e29..8d109ef67ab6 100644
--- a/Documentation/x86/x86_64/boot-options.txt
+++ b/Documentation/x86/x86_64/boot-options.txt
@@ -236,11 +236,6 @@ IOMMU (input/output memory management unit)
 nomergeDon't do scatter-gather (SG) merging.
 noaperture Ask the IOMMU not to touch the aperture for AGP.
 noagp  Don't initialize the AGP driver and use full aperture.
-allowdac   Allow double-address cycle (DAC) mode, i.e. DMA >4GB.
-   DAC is used with 32-bit PCI to push a 64-bit address in
-   two cycles. When off all DMA over >4GB is forced through
-   an IOMMU or software bounce buffering.
-nodac  Forbid DAC mode, i.e. DMA >4GB.
 panic  Always panic when IOMMU overflows.
 calgaryUse the Calgary IOMMU if it is available
 
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 91dff954b745..b5cbef974bd1 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -125,9 +125,9 @@ static __init int iommu_setup(char *p)
if (!strncmp(p, "forcesac", 8))
pr_warn("forcesac option ignored.\n");
if (!strncmp(p, "allowdac", 8))
-   forbid_dac = 0;
+   pr_warn("allowdac option ignored.\n");
if (!strncmp(p, "nodac", 5))
-   forbid_dac = 1;
+   pr_warn("nodac option ignored.\n");
if (!strncmp(p, "usedac", 6)) {
forbid_dac = -1;
return 1;
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 5/7] x86: remove the experimental forcesac boot option

2018-05-25 Thread Christoph Hellwig
Limiting the dma mask to avoid PCI (pre-PCIe) DAC cycles while paying
the huge overhead of an IOMMU is rather pointless, and this seriously
gets in the way of dma mapping work.

Signed-off-by: Christoph Hellwig 
---
 .../admin-guide/kernel-parameters.txt |  1 -
 Documentation/x86/x86_64/boot-options.txt |  4 +---
 arch/x86/kernel/pci-dma.c | 21 +--
 drivers/net/ethernet/sfc/efx.c|  5 ++---
 drivers/net/ethernet/sfc/falcon/efx.c |  5 ++---
 5 files changed, 6 insertions(+), 30 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index f2040d46f095..cc0ac035b8fe 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1705,7 +1705,6 @@
nopanic
merge
nomerge
-   forcesac
soft
pt  [x86, IA-64]
nobypass[PPC/POWERNV]
diff --git a/Documentation/x86/x86_64/boot-options.txt 
b/Documentation/x86/x86_64/boot-options.txt
index 153b3a57fba2..341588ec4e29 100644
--- a/Documentation/x86/x86_64/boot-options.txt
+++ b/Documentation/x86/x86_64/boot-options.txt
@@ -208,7 +208,7 @@ IOMMU (input/output memory management unit)
   Kernel boot message: "PCI-DMA: Using Calgary IOMMU"
 
  iommu=[][,noagp][,off][,force][,noforce][,leak[=]
-   [,memaper[=]][,merge][,forcesac][,fullflush][,nomerge]
+   [,memaper[=]][,merge][,fullflush][,nomerge]
[,noaperture][,calgary]
 
   General iommu options:
@@ -235,8 +235,6 @@ IOMMU (input/output memory management unit)
(experimental).
 nomergeDon't do scatter-gather (SG) merging.
 noaperture Ask the IOMMU not to touch the aperture for AGP.
-forcesac   Force single-address cycle (SAC) mode for masks <40bits
-   (experimental).
 noagp  Don't initialize the AGP driver and use full aperture.
 allowdac   Allow double-address cycle (DAC) mode, i.e. DMA >4GB.
DAC is used with 32-bit PCI to push a 64-bit address in
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 77625b60a510..91dff954b745 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -20,8 +20,6 @@ static int forbid_dac __read_mostly;
 const struct dma_map_ops *dma_ops = _direct_ops;
 EXPORT_SYMBOL(dma_ops);
 
-static int iommu_sac_force __read_mostly;
-
 #ifdef CONFIG_IOMMU_DEBUG
 int panic_on_overflow __read_mostly = 1;
 int force_iommu __read_mostly = 1;
@@ -125,7 +123,7 @@ static __init int iommu_setup(char *p)
if (!strncmp(p, "nomerge", 7))
iommu_merge = 0;
if (!strncmp(p, "forcesac", 8))
-   iommu_sac_force = 1;
+   pr_warn("forcesac option ignored.\n");
if (!strncmp(p, "allowdac", 8))
forbid_dac = 0;
if (!strncmp(p, "nodac", 5))
@@ -165,23 +163,6 @@ int arch_dma_supported(struct device *dev, u64 mask)
}
 #endif
 
-   /* Tell the device to use SAC when IOMMU force is on.  This
-  allows the driver to use cheaper accesses in some cases.
-
-  Problem with this is that if we overflow the IOMMU area and
-  return DAC as fallback address the device may not handle it
-  correctly.
-
-  As a special case some controllers have a 39bit address
-  mode that is as efficient as 32bit (aic79xx). Don't force
-  SAC for these.  Assume all masks <= 40 bits are of this
-  type. Normally this doesn't make any difference, but gives
-  more gentle handling of IOMMU overflow. */
-   if (iommu_sac_force && (mask >= DMA_BIT_MASK(40))) {
-   dev_info(dev, "Force SAC with mask %Lx\n", mask);
-   return 0;
-   }
-
return 1;
 }
 EXPORT_SYMBOL(arch_dma_supported);
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index a4ebd8715494..661828e8fdcf 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1289,9 +1289,8 @@ static int efx_init_io(struct efx_nic *efx)
 
pci_set_master(pci_dev);
 
-   /* Set the PCI DMA mask.  Try all possibilities from our
-* genuine mask down to 32 bits, because some architectures
-* (e.g. x86_64 with iommu_sac_force set) will allow 40 bit
+   /* Set the PCI DMA mask.  Try all possibilities from our genuine mask
+* down to 32 bits, because some architectures will allow 40 bit
 * masks event though they reject 46 bit masks.
 */
while (dma_mask > 0x7fffUL) {
diff --git a/drivers/net/ethernet/sfc/falcon/efx.c 
b/drivers/net/ethernet/sfc/falcon/efx.c
index 3d6c91e96589..dd5530a4f8c8 100644
--- 

[PATCH 4/7] x86: remove a stray reference to pci-nommu.c

2018-05-25 Thread Christoph Hellwig
This is just the minimal workaround.  The file file is mostly either stale
and/or duplicative of Documentation/admin-guide/kernel-parameters.txt,
but that is much more work than I'm willing to do right now.

Signed-off-by: Christoph Hellwig 
---
 Documentation/x86/x86_64/boot-options.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/x86/x86_64/boot-options.txt 
b/Documentation/x86/x86_64/boot-options.txt
index b297c48389b9..153b3a57fba2 100644
--- a/Documentation/x86/x86_64/boot-options.txt
+++ b/Documentation/x86/x86_64/boot-options.txt
@@ -187,9 +187,9 @@ PCI
 
 IOMMU (input/output memory management unit)
 
- Currently four x86-64 PCI-DMA mapping implementations exist:
+ Multiple x86-64 PCI-DMA mapping implementations exist, for example:
 
-   1. : use no hardware/software IOMMU at all
+   1. : use no hardware/software IOMMU at all
   (e.g. because you have < 3 GB memory).
   Kernel boot message: "PCI-DMA: Disabling IOMMU"
 
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 2/7] ia64: remove the dead iommu_sac_force variable

2018-05-25 Thread Christoph Hellwig
Looks like copy and paste from x86 that never actually got used.

Signed-off-by: Christoph Hellwig 
---
 arch/ia64/kernel/pci-dma.c | 19 ---
 1 file changed, 19 deletions(-)

diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c
index b5df084c0af4..50b6ad282a90 100644
--- a/arch/ia64/kernel/pci-dma.c
+++ b/arch/ia64/kernel/pci-dma.c
@@ -18,8 +18,6 @@
 dma_addr_t bad_dma_address __read_mostly;
 EXPORT_SYMBOL(bad_dma_address);
 
-static int iommu_sac_force __read_mostly;
-
 int no_iommu __read_mostly;
 #ifdef CONFIG_IOMMU_DEBUG
 int force_iommu __read_mostly = 1;
@@ -61,23 +59,6 @@ int iommu_dma_supported(struct device *dev, u64 mask)
if (mask < DMA_BIT_MASK(24))
return 0;
 
-   /* Tell the device to use SAC when IOMMU force is on.  This
-  allows the driver to use cheaper accesses in some cases.
-
-  Problem with this is that if we overflow the IOMMU area and
-  return DAC as fallback address the device may not handle it
-  correctly.
-
-  As a special case some controllers have a 39bit address
-  mode that is as efficient as 32bit (aic79xx). Don't force
-  SAC for these.  Assume all masks <= 40 bits are of this
-  type. Normally this doesn't make any difference, but gives
-  more gentle handling of IOMMU overflow. */
-   if (iommu_sac_force && (mask >= DMA_BIT_MASK(40))) {
-   dev_info(dev, "Force SAC with mask %llx\n", mask);
-   return 0;
-   }
-
return 1;
 }
 EXPORT_SYMBOL(iommu_dma_supported);
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 3/7] ia64: remove iommu_dma_supported

2018-05-25 Thread Christoph Hellwig
The generic dma_direct_supported helper already used by intel-iommu on
x86 does a better job than the ia64 reimplementation.

Signed-off-by: Christoph Hellwig 
---
 arch/ia64/kernel/pci-dma.c  | 13 -
 drivers/iommu/intel-iommu.c |  2 --
 2 files changed, 15 deletions(-)

diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c
index 50b6ad282a90..3c2884bef3d4 100644
--- a/arch/ia64/kernel/pci-dma.c
+++ b/arch/ia64/kernel/pci-dma.c
@@ -51,18 +51,6 @@ iommu_dma_init(void)
return;
 }
 
-int iommu_dma_supported(struct device *dev, u64 mask)
-{
-   /* Copied from i386. Doesn't make much sense, because it will
-  only work for pci_alloc_coherent.
-  The caller just has to use GFP_DMA in this case. */
-   if (mask < DMA_BIT_MASK(24))
-   return 0;
-
-   return 1;
-}
-EXPORT_SYMBOL(iommu_dma_supported);
-
 void __init pci_iommu_alloc(void)
 {
dma_ops = _dma_ops;
@@ -71,7 +59,6 @@ void __init pci_iommu_alloc(void)
intel_dma_ops.sync_sg_for_cpu = machvec_dma_sync_sg;
intel_dma_ops.sync_single_for_device = machvec_dma_sync_single;
intel_dma_ops.sync_sg_for_device = machvec_dma_sync_sg;
-   intel_dma_ops.dma_supported = iommu_dma_supported;
 
/*
 * The order of these functions is important for
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 749d8f235346..5e0bef3754d1 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -3841,9 +3841,7 @@ const struct dma_map_ops intel_dma_ops = {
.map_page = intel_map_page,
.unmap_page = intel_unmap_page,
.mapping_error = intel_mapping_error,
-#ifdef CONFIG_X86
.dma_supported = dma_direct_supported,
-#endif
 };
 
 static inline int iommu_domain_cache_init(void)
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


refactor 32-bit dma limit quirks

2018-05-25 Thread Christoph Hellwig
Hi all,

x86 currently has some quirks to force lower dma masks.  They are mostly
useful for certain VIA systems that otherwise corrupt data, but otherwise
don't make much sense given that the modern DMA APIs do the right thing
automatically.

This series dumps a few of these old kernel command lines (including their
not really working version on ia64), and moves the VIA quirk to a flag
in struct device so that it can be apply generically.  This will be needed
to support Xylinx root ports with a similar issue that show up in common
RISC-V boards.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 1/7] core, dma-direct: add a flag 32-bit dma limits

2018-05-25 Thread Christoph Hellwig
Various PCI bridges (VIA PCI, Xilinx PCIe) limit DMA to only 32-bits
even if the device itself supports more.  Add a single bit flag to
struct device (to be moved into the dma extension once we around it)
to flag such devices and reject larger DMA to them.

Signed-off-by: Christoph Hellwig 
---
 include/linux/device.h | 3 +++
 lib/dma-direct.c   | 6 ++
 2 files changed, 9 insertions(+)

diff --git a/include/linux/device.h b/include/linux/device.h
index 477956990f5e..fa317e45f5e6 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -904,6 +904,8 @@ struct dev_links_info {
  * @offline:   Set after successful invocation of bus type's .offline().
  * @of_node_reused: Set if the device-tree node is shared with an ancestor
  *  device.
+ * @dma_32bit_limit: bridge limited to 32bit DMA even if the device itself
+ * indicates support for a higher limit in the dma_mask field.
  *
  * At the lowest level, every device in a Linux system is represented by an
  * instance of struct device. The device structure contains the information
@@ -992,6 +994,7 @@ struct device {
booloffline_disabled:1;
booloffline:1;
boolof_node_reused:1;
+   booldma_32bit_limit:1;
 };
 
 static inline struct device *kobj_to_dev(struct kobject *kobj)
diff --git a/lib/dma-direct.c b/lib/dma-direct.c
index bbfb229aa067..0151a7b2bc87 100644
--- a/lib/dma-direct.c
+++ b/lib/dma-direct.c
@@ -165,6 +165,12 @@ int dma_direct_supported(struct device *dev, u64 mask)
if (mask < DMA_BIT_MASK(32))
return 0;
 #endif
+   /*
+* Various PCI/PCIe bridges have broken support for > 32bit DMA even
+* if the device itself might support it.
+*/
+   if (dev->dma_32bit_limit && mask > DMA_BIT_MASK(32))
+   return 0;
return 1;
 }
 
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


RE: [PATCH v2 39/40] iommu/arm-smmu-v3: Add support for PRI

2018-05-25 Thread Bharat Kumar Gogada
> 
> For PCI devices that support it, enable the PRI capability and handle PRI Page
> Requests with the generic fault handler. It is enabled on demand by
> iommu_sva_device_init().
> 
> Signed-off-by: Jean-Philippe Brucker 
> 
> ---
> v1->v2:
> * Terminate the page request and disable PRI if no handler is registered
> * Enable and disable PRI in sva_device_init/shutdown, instead of
>   add/remove_device
> ---
>  drivers/iommu/arm-smmu-v3.c | 192 +++---
> --
>  1 file changed, 145 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
> index 6cb69ace371b..0edbb8d19579 100644
> --- a/drivers/iommu/arm-smmu-v3.c
> +++ b/drivers/iommu/arm-smmu-v3.c
> @@ -248,6 +248,7 @@
>  #define STRTAB_STE_1_S1COR   GENMASK_ULL(5, 4)
>  #define STRTAB_STE_1_S1CSH   GENMASK_ULL(7, 6)
> 
> +#define STRTAB_STE_1_PPAR(1UL << 18)
>  #define STRTAB_STE_1_S1STALLD(1UL << 27)
> 
>  #define STRTAB_STE_1_EATSGENMASK_ULL(29, 28)
> @@ -309,6 +310,9 @@
>  #define CMDQ_PRI_0_SID   GENMASK_ULL(63, 32)
>  #define CMDQ_PRI_1_GRPID GENMASK_ULL(8, 0)
>  #define CMDQ_PRI_1_RESP  GENMASK_ULL(13, 12)
> +#define CMDQ_PRI_1_RESP_FAILURE
>   FIELD_PREP(CMDQ_PRI_1_RESP, 0UL)
> +#define CMDQ_PRI_1_RESP_INVALID
>   FIELD_PREP(CMDQ_PRI_1_RESP, 1UL)
> +#define CMDQ_PRI_1_RESP_SUCCESS
>   FIELD_PREP(CMDQ_PRI_1_RESP, 2UL)
> 
>  #define CMDQ_RESUME_0_SIDGENMASK_ULL(63, 32)
>  #define CMDQ_RESUME_0_ACTION_RETRY   (1UL << 12)
> @@ -383,12 +387,6 @@ module_param_named(disable_ats_check,
> disable_ats_check, bool, S_IRUGO);
> MODULE_PARM_DESC(disable_ats_check,
>   "By default, the SMMU checks whether each incoming transaction
> marked as translated is allowed by the stream configuration. This option
> disables the check.");
> 
> -enum pri_resp {
> - PRI_RESP_DENY = 0,
> - PRI_RESP_FAIL = 1,
> - PRI_RESP_SUCC = 2,
> -};
> -
>  enum arm_smmu_msi_index {
>   EVTQ_MSI_INDEX,
>   GERROR_MSI_INDEX,
> @@ -471,7 +469,7 @@ struct arm_smmu_cmdq_ent {
>   u32 sid;
>   u32 ssid;
>   u16 grpid;
> - enum pri_resp   resp;
> + enum page_response_code resp;
>   } pri;
> 
>   #define CMDQ_OP_RESUME  0x44
> @@ -556,6 +554,7 @@ struct arm_smmu_strtab_ent {
>   struct arm_smmu_s2_cfg  *s2_cfg;
> 
>   boolcan_stall;
> + boolprg_resp_needs_ssid;
>  };
> 
>  struct arm_smmu_strtab_cfg {
> @@ -907,14 +906,18 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd,
> struct arm_smmu_cmdq_ent *ent)
>   cmd[0] |= FIELD_PREP(CMDQ_PRI_0_SID, ent->pri.sid);
>   cmd[1] |= FIELD_PREP(CMDQ_PRI_1_GRPID, ent->pri.grpid);
>   switch (ent->pri.resp) {
> - case PRI_RESP_DENY:
> - case PRI_RESP_FAIL:
> - case PRI_RESP_SUCC:
> + case IOMMU_PAGE_RESP_FAILURE:
> + cmd[1] |= CMDQ_PRI_1_RESP_FAILURE;
> + break;
> + case IOMMU_PAGE_RESP_INVALID:
> + cmd[1] |= CMDQ_PRI_1_RESP_INVALID;
> + break;
> + case IOMMU_PAGE_RESP_SUCCESS:
> + cmd[1] |= CMDQ_PRI_1_RESP_SUCCESS;
>   break;
>   default:
>   return -EINVAL;
>   }
> - cmd[1] |= FIELD_PREP(CMDQ_PRI_1_RESP, ent->pri.resp);
>   break;
>   case CMDQ_OP_RESUME:
>   cmd[0] |= FIELD_PREP(CMDQ_RESUME_0_SID, ent-
> >resume.sid); @@ -1114,8 +1117,15 @@ static int
> arm_smmu_page_response(struct device *dev,
>   cmd.resume.sid  = sid;
>   cmd.resume.stag = resp->page_req_group_id;
>   cmd.resume.resp = resp->resp_code;
> + } else if (master->can_fault) {
> + cmd.opcode  = CMDQ_OP_PRI_RESP;
> + cmd.substream_valid = resp->pasid_present &&
> +   master->ste.prg_resp_needs_ssid;
> + cmd.pri.sid = sid;
> + cmd.pri.ssid= resp->pasid;
> + cmd.pri.grpid   = resp->page_req_group_id;
> + cmd.pri.resp= resp->resp_code;
>   } else {
> - /* TODO: put PRI response here */
>   return -ENODEV;
>   }
> 
> @@ -1236,6 +1246,9 @@ static void arm_smmu_write_strtab_ent(struct
> arm_smmu_device *smmu, u32 sid,
>FIELD_PREP(STRTAB_STE_1_S1CSH,
> ARM_SMMU_SH_ISH) |
>FIELD_PREP(STRTAB_STE_1_STRW, strw));
> 
> + if (ste->prg_resp_needs_ssid)

Re: [PATCH] drm/rockchip: vop: fix irq disabled after vop driver probed

2018-05-25 Thread Heiko Stuebner
Hi Marc,

Am Freitag, 25. Mai 2018, 13:07:02 CEST schrieb Marc Zyngier:
> [Thanks Robin for pointing me to that patch.]
> 
> Hi Heiko,
> 
> On 24/05/18 23:06, Heiko Stübner wrote:
> > From: Sandy Huang 
> > 
> > The vop irq is shared between vop and iommu and irq probing in the
> > iommu driver moved to the probe function recently. This can in some
> > cases lead to a stall if the irq is triggered while the vop driver
> > still has it disabled.
> > 
> > But there is no real need to disable the irq, as the vop can simply
> > also track its enabled state and ignore irqs in that case.
> > 
> > So remove the enable/disable handling and add appropriate condition
> > to the irq handler.
> > 
> > Signed-off-by: Sandy Huang 
> > [added an actual commit message]
> > Signed-off-by: Heiko Stuebner 
> > ---
> > Hi Ezequiel,
> > 
> > this patch came from a discussion I had with Rockchip people over the
> > iommu changes and resulting issues back in april, but somehow was
> > forgotten and not posted to the lists. Correcting that now.
> > 
> > So removing the enable/disable voodoo on the shared interrupt is
> > the preferred way.
> > 
> >  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 ++---
> >  1 file changed, 7 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
> > b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> > index 510cdf0..61493d4 100644
> > --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> > @@ -549,8 +549,6 @@ static int vop_enable(struct drm_crtc *crtc)
> >  
> > spin_unlock(>reg_lock);
> >  
> > -   enable_irq(vop->irq);
> > -
> > drm_crtc_vblank_on(crtc);
> >  
> > return 0;
> > @@ -596,8 +594,6 @@ static void vop_crtc_atomic_disable(struct drm_crtc 
> > *crtc,
> >  
> > vop_dsp_hold_valid_irq_disable(vop);
> >  
> > -   disable_irq(vop->irq);
> > -
> > vop->is_enabled = false;
> >  
> > /*
> > @@ -1168,6 +1164,13 @@ static irqreturn_t vop_isr(int irq, void *data)
> > int ret = IRQ_NONE;
> >  
> > /*
> > +* since the irq is shared with iommu, iommu irq is enabled before vop
> > +* enable, so before vop enable we do nothing.
> > +*/
> > +   if (!vop->is_enabled)
> > +   return IRQ_NONE;
> > +
> 
> What guarantee do we have that the IOMMU will actually service that
> interrupt? Can't we get into a situation where the interrupt gets
> ignored by both drivers and subsequently disabled by the core irq code
> as being spurious?
> 
> From what I understood of the way things are plugged together on the
> rockchip platforms, each individual VOP is behind a single IOMMU, hence
> there there is hardly any point in handling IOMMU interrupts if the VOP
> is off.

Yeah, which is probably the reason that patch fell through the cracks
initially. I resurrected it from the internal discussion because of the issue
described below.

> But I'm missing the actual reason behind this patch. Could you enlighten me?

Recently the iommu driver moved the irq request from the iommu enablement
to its probe function. With that change Ezequiel got various stalls, see
https://lkml.org/lkml/2018/5/24/1347


Heiko


___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [RFC PATCH v2 00/12] get rid of GFP_ZONE_TABLE/BAD

2018-05-25 Thread Matthew Wilcox
On Thu, May 24, 2018 at 05:29:43PM +0200, Michal Hocko wrote:
> > ie if we had more,
> > could we solve our pain by making them more generic?
> 
> Well, if you have more you will consume more bits in the struct pages,
> right?

Not necessarily ... the zone number is stored in the struct page
currently, so either two or three bits are used right now.  In my
proposal, one can infer the zone of a page from its PFN, except for
ZONE_MOVABLE.  So we could trim down to just one bit per struct page
for 32-bit machines while using 3 bits on 64-bit machines, where there
is plenty of space.

> > it more-or-less sucks that the devices with 28-bit DMA limits are forced
> > to allocate from the low 16MB when they're perfectly capable of using the
> > low 256MB.
> 
> Do we actually care all that much about those? If yes then we should
> probably follow the ZONE_DMA (x86) path and use a CMA region for them.
> I mean most devices should be good with very limited addressability or
> below 4G, no?

Sure.  One other thing I meant to mention was the media devices
(TV capture cards and so on) which want a vmalloc_32() allocation.
On 32-bit machines right now, we allocate from LOWMEM, when we really
should be allocating from the 1GB-4GB region.  32-bit machines generally
don't have a ZONE_DMA32 today.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 7/8] iommu: Remove IOMMU_OF_DECLARE

2018-05-25 Thread Will Deacon
On Thu, May 24, 2018 at 12:50:23PM -0500, Rob Herring wrote:
> Now that we use the driver core to stop deferred probe for missing
> drivers, IOMMU_OF_DECLARE can be removed.
> 
> This is slightly less optimal than having a list of built-in drivers in
> that we'll now defer probe twice before giving up. This shouldn't have a
> significant impact on boot times as past discussions about deferred
> probe have given no evidence of deferred probe having a substantial
> impact.
> 
> Cc: Will Deacon 
> Cc: Robin Murphy 
> Cc: Joerg Roedel 
> Cc: Marek Szyprowski 
> Cc: Kukjin Kim 
> Cc: Krzysztof Kozlowski 
> Cc: Rob Clark 
> Cc: Heiko Stuebner 
> Cc: Frank Rowand 
> Cc: linux-arm-ker...@lists.infradead.org
> Cc: iommu@lists.linux-foundation.org
> Cc: linux-samsung-...@vger.kernel.org
> Cc: linux-arm-...@vger.kernel.org
> Cc: linux-rockc...@lists.infradead.org
> Cc: devicet...@vger.kernel.org
> Signed-off-by: Rob Herring 
> ---
>  drivers/iommu/arm-smmu-v3.c|  2 --
>  drivers/iommu/arm-smmu.c   |  7 ---
>  drivers/iommu/exynos-iommu.c   |  2 --
>  drivers/iommu/ipmmu-vmsa.c |  3 ---
>  drivers/iommu/msm_iommu.c  |  2 --
>  drivers/iommu/of_iommu.c   | 19 +--
>  drivers/iommu/qcom_iommu.c |  2 --
>  drivers/iommu/rockchip-iommu.c |  2 --
>  include/linux/of_iommu.h   |  4 
>  9 files changed, 1 insertion(+), 42 deletions(-)
> 
> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
> index 1d647104bccc..22bdabd3d8e0 100644
> --- a/drivers/iommu/arm-smmu-v3.c
> +++ b/drivers/iommu/arm-smmu-v3.c
> @@ -2915,8 +2915,6 @@ static struct platform_driver arm_smmu_driver = {
>  };
>  module_platform_driver(arm_smmu_driver);
>  
> -IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3");
> -
>  MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
>  MODULE_AUTHOR("Will Deacon ");
>  MODULE_LICENSE("GPL v2");
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index 69e7c60792a8..9dd7cbaa3b0c 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -2211,13 +2211,6 @@ static struct platform_driver arm_smmu_driver = {
>  };
>  module_platform_driver(arm_smmu_driver);
>  
> -IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1");
> -IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2");
> -IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400");
> -IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401");
> -IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500");
> -IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2");
> -
>  MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
>  MODULE_AUTHOR("Will Deacon ");
>  MODULE_LICENSE("GPL v2");

For the SMMU drivers:

Acked-by: Will Deacon 

Will
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] drm/rockchip: vop: fix irq disabled after vop driver probed

2018-05-25 Thread Marc Zyngier
[Thanks Robin for pointing me to that patch.]

Hi Heiko,

On 24/05/18 23:06, Heiko Stübner wrote:
> From: Sandy Huang 
> 
> The vop irq is shared between vop and iommu and irq probing in the
> iommu driver moved to the probe function recently. This can in some
> cases lead to a stall if the irq is triggered while the vop driver
> still has it disabled.
> 
> But there is no real need to disable the irq, as the vop can simply
> also track its enabled state and ignore irqs in that case.
> 
> So remove the enable/disable handling and add appropriate condition
> to the irq handler.
> 
> Signed-off-by: Sandy Huang 
> [added an actual commit message]
> Signed-off-by: Heiko Stuebner 
> ---
> Hi Ezequiel,
> 
> this patch came from a discussion I had with Rockchip people over the
> iommu changes and resulting issues back in april, but somehow was
> forgotten and not posted to the lists. Correcting that now.
> 
> So removing the enable/disable voodoo on the shared interrupt is
> the preferred way.
> 
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 ++---
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
> b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 510cdf0..61493d4 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -549,8 +549,6 @@ static int vop_enable(struct drm_crtc *crtc)
>  
>   spin_unlock(>reg_lock);
>  
> - enable_irq(vop->irq);
> -
>   drm_crtc_vblank_on(crtc);
>  
>   return 0;
> @@ -596,8 +594,6 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
>  
>   vop_dsp_hold_valid_irq_disable(vop);
>  
> - disable_irq(vop->irq);
> -
>   vop->is_enabled = false;
>  
>   /*
> @@ -1168,6 +1164,13 @@ static irqreturn_t vop_isr(int irq, void *data)
>   int ret = IRQ_NONE;
>  
>   /*
> +  * since the irq is shared with iommu, iommu irq is enabled before vop
> +  * enable, so before vop enable we do nothing.
> +  */
> + if (!vop->is_enabled)
> + return IRQ_NONE;
> +

What guarantee do we have that the IOMMU will actually service that
interrupt? Can't we get into a situation where the interrupt gets
ignored by both drivers and subsequently disabled by the core irq code
as being spurious?

From what I understood of the way things are plugged together on the
rockchip platforms, each individual VOP is behind a single IOMMU, hence
there there is hardly any point in handling IOMMU interrupts if the VOP
is off.

But I'm missing the actual reason behind this patch. Could you enlighten me?

Thanks,

M.
-- 
Jazz is not dead. It just smells funny...
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: [PATCH v2 13/40] vfio: Add support for Shared Virtual Addressing

2018-05-25 Thread Jean-Philippe Brucker
On 25/05/18 03:39, Xu Zaibo wrote:
> Hi,
> 
> On 2018/5/24 23:04, Jean-Philippe Brucker wrote:
>> On 24/05/18 13:35, Xu Zaibo wrote:
 Right, sva_init() must be called once for any device that intends to use
 bind(). For the second process though, group->sva_enabled will be true
 so we won't call sva_init() again, only bind().
>>> Well, while I create mediated devices based on one parent device to support 
>>> multiple
>>> processes(a new process will create a new 'vfio_group' for the 
>>> corresponding mediated device,
>>> and 'sva_enabled' cannot work any more), in fact, *sva_init and 
>>> *sva_shutdown are basically
>>> working on parent device, so, as a result, I just only need sva initiation 
>>> and shutdown on the
>>> parent device only once. So I change the two as following:
>>>
>>> @@ -551,8 +565,18 @@ int iommu_sva_device_init(struct device *dev, unsigned 
>>> long features,
>>>if (features & ~IOMMU_SVA_FEAT_IOPF)
>>>   return -EINVAL;
>>>
>>> +/* If already exists, do nothing  */
>>> +mutex_lock(>iommu_param->lock);
>>> +if (dev->iommu_param->sva_param) {
>>> +mutex_unlock(>iommu_param->lock);
>>> +return 0;
>>> +}
>>> +mutex_unlock(>iommu_param->lock);
>>>
>>>   if (features & IOMMU_SVA_FEAT_IOPF) {
>>>   ret = iommu_register_device_fault_handler(dev, iommu_queue_iopf,
>>>
>>>
>>> @@ -621,6 +646,14 @@ int iommu_sva_device_shutdown(struct device *dev)
>>>   if (!domain)
>>>   return -ENODEV;
>>>
>>> +/* If any other process is working on the device, shut down does 
>>> nothing. */
>>> +mutex_lock(>iommu_param->lock);
>>> +if (!list_empty(>iommu_param->sva_param->mm_list)) {
>>> +mutex_unlock(>iommu_param->lock);
>>> +return 0;
>>> +}
>>> +mutex_unlock(>iommu_param->lock);
>> I don't think iommu-sva.c is the best place for this, it's probably
>> better to implement an intermediate layer (the mediating driver), that
>> calls iommu_sva_device_init() and iommu_sva_device_shutdown() once. Then
>> vfio-pci would still call these functions itself, but for mdev the
>> mediating driver keeps a refcount of groups, and calls device_shutdown()
>> only when freeing the last mdev.
>>
>> A device driver (non mdev in this example) expects to be able to free
>> all its resources after sva_device_shutdown() returns. Imagine the
>> mm_list isn't empty (mm_exit() is running late), and instead of waiting
>> in unbind_dev_all() below, we return 0 immediately. Then the calling
>> driver frees its resources, and the mm_exit callback along with private
>> data passed to bind() disappear. If a mm_exit() is still running in
>> parallel, then it will try to access freed data and corrupt memory. So
>> in this function if mm_list isn't empty, the only thing we can do is wait.
>>
> I still don't understand why we should 'unbind_dev_all', is it possible 
> to do a 'unbind_dev_pasid'?

Not in sva_device_shutdown(), it needs to clean up everything. For
example you want to physically unplug the device, or assign it to a VM.
To prevent any leak sva_device_shutdown() needs to remove all bonds. In
theory there shouldn't be any, since either the driver did unbind_dev(),
or all process exited. This is a safety net.

> Then we can do other things instead of waiting that user may not like. :)

They may not like it, but it's for their own good :) At the moment we're
waiting that:

* All exit_mm() callback for this device have finished. If we don't wait
  then the caller will free the private data passed to bind and the
  mm_exit() callback while they are still being used.

* All page requests targeting this device are dealt with. If we don't
  wait then some requests, that are lingering in the IOMMU PRI queue,
  may hit the next contexts bound to this device, possibly in a
  different VM. It may not be too risky (though probably exploitable in
  some way), but is incredibly messy.

All of this is bounded in time, and normally should be over pretty fast
unless the device driver's exit_mm() does something strange. If the
driver did the right thing, there shouldn't be any wait here (although
there may be one in unbind_dev() for the same reasons - prevent use
after free).

Thanks,
Jean
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 25/25] MIPS: remove unneeded includes from dma-mapping.h

2018-05-25 Thread Christoph Hellwig
Keep this file as light as possible as it gets pulled into every
driver using dma mapping APIs.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/include/asm/dma-mapping.h | 8 
 arch/mips/mti-malta/malta-setup.c   | 1 +
 2 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/arch/mips/include/asm/dma-mapping.h 
b/arch/mips/include/asm/dma-mapping.h
index 143250986e17..1c6e0c8ef483 100644
--- a/arch/mips/include/asm/dma-mapping.h
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -2,14 +2,6 @@
 #ifndef _ASM_DMA_MAPPING_H
 #define _ASM_DMA_MAPPING_H
 
-#include 
-#include 
-#include 
-
-#ifndef CONFIG_SGI_IP27 /* Kludge to fix 2.6.39 build for IP27 */
-#include 
-#endif
-
 extern const struct dma_map_ops jazz_dma_ops;
 extern const struct dma_map_ops mips_swiotlb_ops;
 
diff --git a/arch/mips/mti-malta/malta-setup.c 
b/arch/mips/mti-malta/malta-setup.c
index 4d5cdfeee3db..7cb7d5a42087 100644
--- a/arch/mips/mti-malta/malta-setup.c
+++ b/arch/mips/mti-malta/malta-setup.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 24/25] MIPS: remove the old dma-default implementation

2018-05-25 Thread Christoph Hellwig
Now unused.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/Kconfig |   5 +-
 arch/mips/include/asm/dma-mapping.h   |   3 -
 .../include/asm/mach-generic/dma-coherence.h  |  73 
 arch/mips/mm/Makefile |   1 -
 arch/mips/mm/dma-default.c| 379 --
 5 files changed, 1 insertion(+), 460 deletions(-)
 delete mode 100644 arch/mips/include/asm/mach-generic/dma-coherence.h
 delete mode 100644 arch/mips/mm/dma-default.c

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 9ac3c6260b68..ad5a542bf094 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -72,9 +72,6 @@ config MIPS
select SYSCTL_EXCEPTION_TRACE
select VIRT_TO_BUS
 
-config MIPS_DMA_DEFAULT
-   bool
-
 menu "Machine selection"
 
 choice
@@ -1113,7 +1110,7 @@ config DMA_NONCOHERENT
select NEED_DMA_MAP_STATE
select DMA_NONCOHERENT_MMAP
select DMA_NONCOHERENT_CACHE_SYNC
-   select DMA_NONCOHERENT_OPS if !MIPS_DMA_DEFAULT
+   select DMA_NONCOHERENT_OPS
 
 config SYS_HAS_EARLY_PRINTK
bool
diff --git a/arch/mips/include/asm/dma-mapping.h 
b/arch/mips/include/asm/dma-mapping.h
index caf97f739897..143250986e17 100644
--- a/arch/mips/include/asm/dma-mapping.h
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -11,7 +11,6 @@
 #endif
 
 extern const struct dma_map_ops jazz_dma_ops;
-extern const struct dma_map_ops mips_default_dma_map_ops;
 extern const struct dma_map_ops mips_swiotlb_ops;
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
@@ -20,8 +19,6 @@ static inline const struct dma_map_ops 
*get_arch_dma_ops(struct bus_type *bus)
return _dma_ops;
 #elif defined(CONFIG_SWIOTLB)
return _swiotlb_ops;
-#elif defined(CONFIG_MIPS_DMA_DEFAULT)
-   return _default_dma_map_ops;
 #elif defined(CONFIG_DMA_NONCOHERENT_OPS)
return _noncoherent_ops;
 #else
diff --git a/arch/mips/include/asm/mach-generic/dma-coherence.h 
b/arch/mips/include/asm/mach-generic/dma-coherence.h
deleted file mode 100644
index 8ad7a40ca786..
--- a/arch/mips/include/asm/mach-generic/dma-coherence.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2006  Ralf Baechle 
- *
- */
-#ifndef __ASM_MACH_GENERIC_DMA_COHERENCE_H
-#define __ASM_MACH_GENERIC_DMA_COHERENCE_H
-
-struct device;
-
-static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
-   size_t size)
-{
-   return virt_to_phys(addr);
-}
-
-static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
-   struct page *page)
-{
-   return page_to_phys(page);
-}
-
-static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
-   dma_addr_t dma_addr)
-{
-   return dma_addr;
-}
-
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
-   size_t size, enum dma_data_direction direction)
-{
-}
-
-static inline int plat_dma_supported(struct device *dev, u64 mask)
-{
-   /*
-* we fall back to GFP_DMA when the mask isn't all 1s,
-* so we can't guarantee allocations that must be
-* within a tighter range than GFP_DMA..
-*/
-   if (mask < DMA_BIT_MASK(24))
-   return 0;
-
-   return 1;
-}
-
-static inline int plat_device_is_coherent(struct device *dev)
-{
-#ifdef CONFIG_DMA_PERDEV_COHERENT
-   return dev->archdata.dma_coherent;
-#else
-   switch (coherentio) {
-   default:
-   case IO_COHERENCE_DEFAULT:
-   return hw_coherentio;
-   case IO_COHERENCE_ENABLED:
-   return 1;
-   case IO_COHERENCE_DISABLED:
-   return 0;
-   }
-#endif
-}
-
-#ifndef plat_post_dma_flush
-static inline void plat_post_dma_flush(struct device *dev)
-{
-}
-#endif
-
-#endif /* __ASM_MACH_GENERIC_DMA_COHERENCE_H */
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index c6146c3805dc..6922f393af19 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -17,7 +17,6 @@ obj-$(CONFIG_32BIT)   += ioremap.o pgtable-32.o
 obj-$(CONFIG_64BIT)+= pgtable-64.o
 obj-$(CONFIG_HIGHMEM)  += highmem.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
-obj-$(CONFIG_MIPS_DMA_DEFAULT) += dma-default.o
 obj-$(CONFIG_DMA_NONCOHERENT)  += dma-noncoherent.o
 obj-$(CONFIG_SWIOTLB)  += dma-swiotlb.o
 
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
deleted file mode 100644
index 10b56e8a2076..
--- a/arch/mips/mm/dma-default.c
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000  Ani Joshi 

RE: [External] Re: [RFC PATCH v2 00/12] get rid of GFP_ZONE_TABLE/BAD

2018-05-25 Thread Huaisheng HS1 Ye
From: Michal Hocko [mailto:mho...@kernel.org]
Sent: Thursday, May 24, 2018 8:19 PM> 
> > Let me try to reply your questions.
> > Exactly, GFP_ZONE_TABLE is too complicated. I think there are two advantages
> > from the series of patches.
> >
> > 1. XOR operation is simple and efficient, GFP_ZONE_TABLE/BAD need to do 
> > twice
> > shift operations, the first is for getting a zone_type and the second is for
> > checking the to be returned type is a correct or not. But with these patch 
> > XOR
> > operation just needs to use once. Because the bottom 3 bits of GFP bitmask 
> > have
> > been used to represent the encoded zone number, we can say there is no bad 
> > zone
> > number if all callers could use it without buggy way. Of course, the 
> > returned
> > zone type in gfp_zone needs to be no more than ZONE_MOVABLE.
> 
> But you are losing the ability to check for wrong usage. And it seems
> that the sad reality is that the existing code do screw up.

In my opinion, originally there shouldn't be such many wrong combinations of 
these bottom 3 bits. For any user, whether or driver and fs, they should make a 
decision that which zone is they preferred. Matthew's idea is great, because 
with it the user must offer an unambiguous flag to gfp zone bits.

Ideally, before any user wants to modify the address zone modifier, they should 
clear it firstly, then ORing the GFP zone flag which comes from the zone they 
prefer.
With these patches, we can loudly announce that, the bottom 3 bits of zone mask 
couldn't accept internal ORing operations.
The operations like __GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM is illegal. The 
current GFP_ZONE_TABLE is precisely the root of this problem, that is 
__GFP_DMA, __GFP_DMA32 and __GFP_HIGHMEM are formatted as 0x1, 0x2 and 0x4.

> 
> > 2. GFP_ZONE_TABLE has limit with the amount of zone types. Current 
> > GFP_ZONE_TABLE
> > is 32 bits, in general, there are 4 zone types for most ofX86_64 platform, 
> > they
> > are ZONE_DMA, ZONE_DMA32, ZONE_NORMAL and ZONE_MOVABLE. If we want to 
> > expand the
> > amount of zone types to larger than 4, the zone shift should be 3.
> 
> But we do not want to expand the number of zones IMHO. The existing zoo
> is quite a maint. pain.
> 
> That being said. I am not saying that I am in love with GFP_ZONE_TABLE.
> It always makes my head explode when I look there but it seems to work
> with the current code and it is optimized for it. If you want to change
> this then you should make sure you describe reasons _why_ this is an
> improvement. And I would argue that "we can have more zones" is a
> relevant one.

Yes, GFP_ZONE_TABLE is too complicated. The patches have 4 advantages as below.

* The address zone modifiers have new operation method, that is, user should 
decide which zone is preferred at first, then give the encoded zone number to 
bottom 3 bits in GFP mask. That is much direct and clear than before.

* No bad zone combination, because user should choose just one address zone 
modifier always.
* Better performance and efficiency, current gfp_zone has to take shifting 
operation twice for GFP_ZONE_TABLE and GFP_ZONE_BAD. With these patches, 
gfp_zone() just needs one XOR.
* Up to 8 zones can be used. At least it isn't a disadvantage, right?

Sincerely,
Huaisheng Ye
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v1] arch/x86/kernel/pci-dma: Remove useless parameter of arch_dma_alloc_attrs

2018-05-25 Thread Christoph Hellwig
Thanks,

applied to the dma-mapping tree.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 23/25] MIPS: bmips: use generic dma noncoherent ops

2018-05-25 Thread Christoph Hellwig
Provide phys_to_dma/dma_to_phys helpers, and the special
arch_sync_dma_for_cpu_all hook, everything else is generic

Signed-off-by: Christoph Hellwig 
---
 arch/mips/Kconfig |  3 +-
 arch/mips/bmips/dma.c | 32 ++-
 arch/mips/include/asm/bmips.h | 16 --
 .../include/asm/mach-bmips/dma-coherence.h| 54 ---
 4 files changed, 21 insertions(+), 84 deletions(-)
 delete mode 100644 arch/mips/include/asm/mach-bmips/dma-coherence.h

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 25a3c3262554..9ac3c6260b68 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -209,6 +209,8 @@ config ATH79
 
 config BMIPS_GENERIC
bool "Broadcom Generic BMIPS kernel"
+   select ARCH_HAS_SYNC_DMA_FOR_CPU_ALL
+   select ARCH_HAS_PHYS_TO_DMA
select BOOT_RAW
select NO_EXCEPT_FILL
select USE_OF
@@ -221,7 +223,6 @@ config BMIPS_GENERIC
select BCM7120_L2_IRQ
select BRCMSTB_L2_IRQ
select IRQ_MIPS_CPU
-   select MIPS_DMA_DEFAULT
select DMA_NONCOHERENT
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
diff --git a/arch/mips/bmips/dma.c b/arch/mips/bmips/dma.c
index 04790f4e1805..02ba0e38748d 100644
--- a/arch/mips/bmips/dma.c
+++ b/arch/mips/bmips/dma.c
@@ -17,7 +17,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 /*
  * BCM338x has configurable address translation windows which allow the
@@ -40,7 +40,7 @@ static struct bmips_dma_range *bmips_dma_ranges;
 
 #define FLUSH_RAC  0x100
 
-static dma_addr_t bmips_phys_to_dma(struct device *dev, phys_addr_t pa)
+dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t pa)
 {
struct bmips_dma_range *r;
 
@@ -52,17 +52,7 @@ static dma_addr_t bmips_phys_to_dma(struct device *dev, 
phys_addr_t pa)
return pa;
 }
 
-dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
-{
-   return bmips_phys_to_dma(dev, virt_to_phys(addr));
-}
-
-dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
-{
-   return bmips_phys_to_dma(dev, page_to_phys(page));
-}
-
-unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr)
+phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
 {
struct bmips_dma_range *r;
 
@@ -74,6 +64,22 @@ unsigned long plat_dma_addr_to_phys(struct device *dev, 
dma_addr_t dma_addr)
return dma_addr;
 }
 
+void arch_sync_dma_for_cpu_all(struct device *dev)
+{
+   void __iomem *cbr = BMIPS_GET_CBR();
+   u32 cfg;
+
+   if (boot_cpu_type() != CPU_BMIPS3300 &&
+   boot_cpu_type() != CPU_BMIPS4350 &&
+   boot_cpu_type() != CPU_BMIPS4380)
+   return;
+
+   /* Flush stale data out of the readahead cache */
+   cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG);
+   __raw_writel(cfg | 0x100, cbr + BMIPS_RAC_CONFIG);
+   __raw_readl(cbr + BMIPS_RAC_CONFIG);
+}
+
 static int __init bmips_init_dma_ranges(void)
 {
struct device_node *np =
diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h
index b3e2975f83d3..bf6a8afd7ad2 100644
--- a/arch/mips/include/asm/bmips.h
+++ b/arch/mips/include/asm/bmips.h
@@ -123,22 +123,6 @@ static inline void bmips_write_zscm_reg(unsigned int 
offset, unsigned long data)
barrier();
 }
 
-static inline void bmips_post_dma_flush(struct device *dev)
-{
-   void __iomem *cbr = BMIPS_GET_CBR();
-   u32 cfg;
-
-   if (boot_cpu_type() != CPU_BMIPS3300 &&
-   boot_cpu_type() != CPU_BMIPS4350 &&
-   boot_cpu_type() != CPU_BMIPS4380)
-   return;
-
-   /* Flush stale data out of the readahead cache */
-   cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG);
-   __raw_writel(cfg | 0x100, cbr + BMIPS_RAC_CONFIG);
-   __raw_readl(cbr + BMIPS_RAC_CONFIG);
-}
-
 #endif /* !defined(__ASSEMBLY__) */
 
 #endif /* _ASM_BMIPS_H */
diff --git a/arch/mips/include/asm/mach-bmips/dma-coherence.h 
b/arch/mips/include/asm/mach-bmips/dma-coherence.h
deleted file mode 100644
index d29781f02285..
--- a/arch/mips/include/asm/mach-bmips/dma-coherence.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2006 Ralf Baechle 
- * Copyright (C) 2009 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef __ASM_MACH_BMIPS_DMA_COHERENCE_H
-#define __ASM_MACH_BMIPS_DMA_COHERENCE_H
-
-#include 
-#include 
-#include 
-
-struct device;
-
-extern dma_addr_t plat_map_dma_mem(struct 

[PATCH 22/25] dma-noncoherent: add a arch_sync_dma_for_cpu_all hook

2018-05-25 Thread Christoph Hellwig
The MIPS bmips platform needs a global flush when transferring ownership
back to the CPU.  Add a hook for that to the dma-noncoherent
implementation.

Signed-off-by: Christoph Hellwig 
---
 include/linux/dma-noncoherent.h | 8 
 lib/dma-noncoherent.c   | 8 ++--
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/include/linux/dma-noncoherent.h b/include/linux/dma-noncoherent.h
index 10b2654d549b..a0aa00cc909d 100644
--- a/include/linux/dma-noncoherent.h
+++ b/include/linux/dma-noncoherent.h
@@ -44,4 +44,12 @@ static inline void arch_sync_dma_for_cpu(struct device *dev,
 }
 #endif /* ARCH_HAS_SYNC_DMA_FOR_CPU */
 
+#ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL
+void arch_sync_dma_for_cpu_all(struct device *dev);
+#else
+static inline void arch_sync_dma_for_cpu_all(struct device *dev)
+{
+}
+#endif /* CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL */
+
 #endif /* _LINUX_DMA_NONCOHERENT_H */
diff --git a/lib/dma-noncoherent.c b/lib/dma-noncoherent.c
index 79e9a757387f..031fe235d958 100644
--- a/lib/dma-noncoherent.c
+++ b/lib/dma-noncoherent.c
@@ -49,11 +49,13 @@ static int dma_noncoherent_map_sg(struct device *dev, 
struct scatterlist *sgl,
return nents;
 }
 
-#ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU
+#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \
+defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
 static void dma_noncoherent_sync_single_for_cpu(struct device *dev,
dma_addr_t addr, size_t size, enum dma_data_direction dir)
 {
arch_sync_dma_for_cpu(dev, dma_to_phys(dev, addr), size, dir);
+   arch_sync_dma_for_cpu_all(dev);
 }
 
 static void dma_noncoherent_sync_sg_for_cpu(struct device *dev,
@@ -64,6 +66,7 @@ static void dma_noncoherent_sync_sg_for_cpu(struct device 
*dev,
 
for_each_sg(sgl, sg, nents, i)
arch_sync_dma_for_cpu(dev, sg_phys(sg), sg->length, dir);
+   arch_sync_dma_for_cpu_all(dev);
 }
 
 static void dma_noncoherent_unmap_page(struct device *dev, dma_addr_t addr,
@@ -89,7 +92,8 @@ const struct dma_map_ops dma_noncoherent_ops = {
.sync_sg_for_device = dma_noncoherent_sync_sg_for_device,
.map_page   = dma_noncoherent_map_page,
.map_sg = dma_noncoherent_map_sg,
-#ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU
+#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \
+defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
.sync_single_for_cpu= dma_noncoherent_sync_single_for_cpu,
.sync_sg_for_cpu= dma_noncoherent_sync_sg_for_cpu,
.unmap_page = dma_noncoherent_unmap_page,
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 21/25] MIPS: jazz: split dma mapping operations from dma-default

2018-05-25 Thread Christoph Hellwig
Jazz actually has a very basic IOMMU, so split the ops into a separate
implementation from the generic default support (which is about to go
away anyway).

Signed-off-by: Christoph Hellwig 
---
 arch/mips/include/asm/dma-mapping.h   |   5 +-
 .../include/asm/mach-jazz/dma-coherence.h |  60 
 arch/mips/jazz/Kconfig|   3 -
 arch/mips/jazz/jazzdma.c  | 141 +-
 4 files changed, 144 insertions(+), 65 deletions(-)
 delete mode 100644 arch/mips/include/asm/mach-jazz/dma-coherence.h

diff --git a/arch/mips/include/asm/dma-mapping.h 
b/arch/mips/include/asm/dma-mapping.h
index e32a7b439816..caf97f739897 100644
--- a/arch/mips/include/asm/dma-mapping.h
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -10,12 +10,15 @@
 #include 
 #endif
 
+extern const struct dma_map_ops jazz_dma_ops;
 extern const struct dma_map_ops mips_default_dma_map_ops;
 extern const struct dma_map_ops mips_swiotlb_ops;
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
-#ifdef CONFIG_SWIOTLB
+#if defined(CONFIG_MACH_JAZZ)
+   return _dma_ops;
+#elif defined(CONFIG_SWIOTLB)
return _swiotlb_ops;
 #elif defined(CONFIG_MIPS_DMA_DEFAULT)
return _default_dma_map_ops;
diff --git a/arch/mips/include/asm/mach-jazz/dma-coherence.h 
b/arch/mips/include/asm/mach-jazz/dma-coherence.h
deleted file mode 100644
index dc347c25c343..
--- a/arch/mips/include/asm/mach-jazz/dma-coherence.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2006  Ralf Baechle 
- */
-#ifndef __ASM_MACH_JAZZ_DMA_COHERENCE_H
-#define __ASM_MACH_JAZZ_DMA_COHERENCE_H
-
-#include 
-
-struct device;
-
-static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, 
size_t size)
-{
-   return vdma_alloc(virt_to_phys(addr), size);
-}
-
-static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
-   struct page *page)
-{
-   return vdma_alloc(page_to_phys(page), PAGE_SIZE);
-}
-
-static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
-   dma_addr_t dma_addr)
-{
-   return vdma_log2phys(dma_addr);
-}
-
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
-   size_t size, enum dma_data_direction direction)
-{
-   vdma_free(dma_addr);
-}
-
-static inline int plat_dma_supported(struct device *dev, u64 mask)
-{
-   /*
-* we fall back to GFP_DMA when the mask isn't all 1s,
-* so we can't guarantee allocations that must be
-* within a tighter range than GFP_DMA..
-*/
-   if (mask < DMA_BIT_MASK(24))
-   return 0;
-
-   return 1;
-}
-
-static inline void plat_post_dma_flush(struct device *dev)
-{
-}
-
-static inline int plat_device_is_coherent(struct device *dev)
-{
-   return 0;
-}
-
-#endif /* __ASM_MACH_JAZZ_DMA_COHERENCE_H */
diff --git a/arch/mips/jazz/Kconfig b/arch/mips/jazz/Kconfig
index d3ae3e0356f6..06838f80a5d7 100644
--- a/arch/mips/jazz/Kconfig
+++ b/arch/mips/jazz/Kconfig
@@ -3,7 +3,6 @@ config ACER_PICA_61
bool "Support for Acer PICA 1 chipset"
depends on MACH_JAZZ
select DMA_NONCOHERENT
-   select MIPS_DMA_DEFAULT
select SYS_SUPPORTS_LITTLE_ENDIAN
help
  This is a machine with a R4400 133/150 MHz CPU. To compile a Linux
@@ -15,7 +14,6 @@ config MIPS_MAGNUM_4000
bool "Support for MIPS Magnum 4000"
depends on MACH_JAZZ
select DMA_NONCOHERENT
-   select MIPS_DMA_DEFAULT
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_LITTLE_ENDIAN
help
@@ -28,7 +26,6 @@ config OLIVETTI_M700
bool "Support for Olivetti M700-10"
depends on MACH_JAZZ
select DMA_NONCOHERENT
-   select MIPS_DMA_DEFAULT
select SYS_SUPPORTS_LITTLE_ENDIAN
help
  This is a machine with a R4000 100 MHz CPU. To compile a Linux
diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c
index d626a9a391cc..446fc8c92e1e 100644
--- a/arch/mips/jazz/jazzdma.c
+++ b/arch/mips/jazz/jazzdma.c
@@ -16,6 +16,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -86,6 +88,7 @@ static int __init vdma_init(void)
printk(KERN_INFO "VDMA: R4030 DMA pagetables initialized.\n");
return 0;
 }
+arch_initcall(vdma_init);
 
 /*
  * Allocate DMA pagetables using a simple first-fit algorithm
@@ -556,4 +559,140 @@ int vdma_get_enable(int channel)
return enable;
 }
 
-arch_initcall(vdma_init);
+static void *jazz_dma_alloc(struct device *dev, size_t size,
+   dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
+{
+   void *ret;
+
+   ret = dma_direct_alloc(dev, size, dma_handle, gfp, attrs);
+   if (!ret)
+ 

[PATCH 20/25] MIPS: ath25: use generic dma noncoherent ops

2018-05-25 Thread Christoph Hellwig
Provide phys_to_dma/dma_to_phys helpers only if PCI support is
enabled, everything else is generic.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/Kconfig |  1 -
 arch/mips/ath25/Kconfig   |  1 +
 .../include/asm/mach-ath25/dma-coherence.h| 71 ---
 arch/mips/pci/pci-ar2315.c| 24 +++
 4 files changed, 25 insertions(+), 72 deletions(-)
 delete mode 100644 arch/mips/include/asm/mach-ath25/dma-coherence.h

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index bde16399a8fe..25a3c3262554 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -176,7 +176,6 @@ config ATH25
select DMA_NONCOHERENT
select IRQ_MIPS_CPU
select IRQ_DOMAIN
-   select MIPS_DMA_DEFAULT
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_32BIT_KERNEL
diff --git a/arch/mips/ath25/Kconfig b/arch/mips/ath25/Kconfig
index 7070b4bcd01d..2c1dfd06c366 100644
--- a/arch/mips/ath25/Kconfig
+++ b/arch/mips/ath25/Kconfig
@@ -12,6 +12,7 @@ config SOC_AR2315
 config PCI_AR2315
bool "Atheros AR2315 PCI controller support"
depends on SOC_AR2315
+   select ARCH_HAS_PHYS_TO_DMA
select HW_HAS_PCI
select PCI
default y
diff --git a/arch/mips/include/asm/mach-ath25/dma-coherence.h 
b/arch/mips/include/asm/mach-ath25/dma-coherence.h
deleted file mode 100644
index 124755d4f079..
--- a/arch/mips/include/asm/mach-ath25/dma-coherence.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2006  Ralf Baechle 
- * Copyright (C) 2007  Felix Fietkau 
- *
- */
-#ifndef __ASM_MACH_ATH25_DMA_COHERENCE_H
-#define __ASM_MACH_ATH25_DMA_COHERENCE_H
-
-#include 
-
-/*
- * We need some arbitrary non-zero value to be programmed to the BAR1 register
- * of PCI host controller to enable DMA. The same value should be used as the
- * offset to calculate the physical address of DMA buffer for PCI devices.
- */
-#define AR2315_PCI_HOST_SDRAM_BASEADDR 0x2000
-
-static inline dma_addr_t ath25_dev_offset(struct device *dev)
-{
-#ifdef CONFIG_PCI
-   extern struct bus_type pci_bus_type;
-
-   if (dev && dev->bus == _bus_type)
-   return AR2315_PCI_HOST_SDRAM_BASEADDR;
-#endif
-   return 0;
-}
-
-static inline dma_addr_t
-plat_map_dma_mem(struct device *dev, void *addr, size_t size)
-{
-   return virt_to_phys(addr) + ath25_dev_offset(dev);
-}
-
-static inline dma_addr_t
-plat_map_dma_mem_page(struct device *dev, struct page *page)
-{
-   return page_to_phys(page) + ath25_dev_offset(dev);
-}
-
-static inline unsigned long
-plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr)
-{
-   return dma_addr - ath25_dev_offset(dev);
-}
-
-static inline void
-plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, size_t size,
-  enum dma_data_direction direction)
-{
-}
-
-static inline int plat_dma_supported(struct device *dev, u64 mask)
-{
-   return 1;
-}
-
-static inline int plat_device_is_coherent(struct device *dev)
-{
-   return 0;
-}
-
-static inline void plat_post_dma_flush(struct device *dev)
-{
-}
-
-#endif /* __ASM_MACH_ATH25_DMA_COHERENCE_H */
diff --git a/arch/mips/pci/pci-ar2315.c b/arch/mips/pci/pci-ar2315.c
index b4fa6413c4e5..c539d0d2b0cf 100644
--- a/arch/mips/pci/pci-ar2315.c
+++ b/arch/mips/pci/pci-ar2315.c
@@ -149,6 +149,13 @@
 #define AR2315_PCI_HOST_SLOT   3
 #define AR2315_PCI_HOST_DEVID  ((0xff18 << 16) | PCI_VENDOR_ID_ATHEROS)
 
+/*
+ * We need some arbitrary non-zero value to be programmed to the BAR1 register
+ * of PCI host controller to enable DMA. The same value should be used as the
+ * offset to calculate the physical address of DMA buffer for PCI devices.
+ */
+#define AR2315_PCI_HOST_SDRAM_BASEADDR 0x2000
+
 /* ??? access BAR */
 #define AR2315_PCI_HOST_MBAR0  0x1000
 /* RAM access BAR */
@@ -167,6 +174,23 @@ struct ar2315_pci_ctrl {
struct resource io_res;
 };
 
+static inline dma_addr_t ar2315_dev_offset(struct device *dev)
+{
+   if (dev && dev_is_pci(dev))
+   return AR2315_PCI_HOST_SDRAM_BASEADDR;
+   return 0;
+}
+
+dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+   return paddr + ar2315_dev_offset(dev);
+}
+
+phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
+{
+   return dma_addr - ar2315_dev_offset(dev);
+}
+
 static inline struct ar2315_pci_ctrl *ar2315_pci_bus_to_apc(struct pci_bus 
*bus)
 {
struct pci_controller *hose = bus->sysdata;
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 19/25] MIPS: IP32: use generic dma noncoherent ops

2018-05-25 Thread Christoph Hellwig
Provide phys_to_dma/dma_to_phys helpers, everything else is generic.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/Kconfig |  2 +-
 .../include/asm/mach-ip32/dma-coherence.h | 92 ---
 arch/mips/sgi-ip32/Makefile   |  2 +-
 arch/mips/sgi-ip32/ip32-dma.c | 37 
 4 files changed, 39 insertions(+), 94 deletions(-)
 delete mode 100644 arch/mips/include/asm/mach-ip32/dma-coherence.h
 create mode 100644 arch/mips/sgi-ip32/ip32-dma.c

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 3140955bc77c..bde16399a8fe 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -720,6 +720,7 @@ config SGI_IP28
 
 config SGI_IP32
bool "SGI IP32 (O2)"
+   select ARCH_HAS_PHYS_TO_DMA
select FW_ARC
select FW_ARC32
select BOOT_ELF32
@@ -728,7 +729,6 @@ config SGI_IP32
select DMA_NONCOHERENT
select HW_HAS_PCI
select IRQ_MIPS_CPU
-   select MIPS_DMA_DEFAULT
select R5000_CPU_SCACHE
select RM7000_CPU_SCACHE
select SYS_HAS_CPU_R5000
diff --git a/arch/mips/include/asm/mach-ip32/dma-coherence.h 
b/arch/mips/include/asm/mach-ip32/dma-coherence.h
deleted file mode 100644
index 7bdf212587a0..
--- a/arch/mips/include/asm/mach-ip32/dma-coherence.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2006  Ralf Baechle 
- *
- */
-#ifndef __ASM_MACH_IP32_DMA_COHERENCE_H
-#define __ASM_MACH_IP32_DMA_COHERENCE_H
-
-#include 
-
-struct device;
-
-/*
- * Few notes.
- * 1. CPU sees memory as two chunks: 0-256M@0x0, and the rest @0x4000+256M
- * 2. PCI sees memory as one big chunk @0x0 (or we could use 0x4000 for
- *native-endian)
- * 3. All other devices see memory as one big chunk at 0x4000
- * 4. Non-PCI devices will pass NULL as struct device*
- *
- * Thus we translate differently, depending on device.
- */
-
-#define RAM_OFFSET_MASK 0x3fffUL
-
-static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
-   size_t size)
-{
-   dma_addr_t pa = virt_to_phys(addr) & RAM_OFFSET_MASK;
-
-   if (dev == NULL)
-   pa += CRIME_HI_MEM_BASE;
-
-   return pa;
-}
-
-static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
-   struct page *page)
-{
-   dma_addr_t pa;
-
-   pa = page_to_phys(page) & RAM_OFFSET_MASK;
-
-   if (dev == NULL)
-   pa += CRIME_HI_MEM_BASE;
-
-   return pa;
-}
-
-/* This is almost certainly wrong but it's what dma-ip32.c used to use */
-static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
-   dma_addr_t dma_addr)
-{
-   unsigned long addr = dma_addr & RAM_OFFSET_MASK;
-
-   if (dma_addr >= 256*1024*1024)
-   addr += CRIME_HI_MEM_BASE;
-
-   return addr;
-}
-
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
-   size_t size, enum dma_data_direction direction)
-{
-}
-
-static inline int plat_dma_supported(struct device *dev, u64 mask)
-{
-   /*
-* we fall back to GFP_DMA when the mask isn't all 1s,
-* so we can't guarantee allocations that must be
-* within a tighter range than GFP_DMA..
-*/
-   if (mask < DMA_BIT_MASK(24))
-   return 0;
-
-   return 1;
-}
-
-static inline void plat_post_dma_flush(struct device *dev)
-{
-}
-
-static inline int plat_device_is_coherent(struct device *dev)
-{
-   return 0;   /* IP32 is non-coherent */
-}
-
-#endif /* __ASM_MACH_IP32_DMA_COHERENCE_H */
diff --git a/arch/mips/sgi-ip32/Makefile b/arch/mips/sgi-ip32/Makefile
index 60f0227425e7..4745cd94df11 100644
--- a/arch/mips/sgi-ip32/Makefile
+++ b/arch/mips/sgi-ip32/Makefile
@@ -4,4 +4,4 @@
 #
 
 obj-y  += ip32-berr.o ip32-irq.o ip32-platform.o ip32-setup.o ip32-reset.o \
-  crime.o ip32-memory.o
+  crime.o ip32-memory.o ip32-dma.o
diff --git a/arch/mips/sgi-ip32/ip32-dma.c b/arch/mips/sgi-ip32/ip32-dma.c
new file mode 100644
index ..fa7b17cb5385
--- /dev/null
+++ b/arch/mips/sgi-ip32/ip32-dma.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2006  Ralf Baechle 
+ */
+#include 
+#include 
+
+/*
+ * Few notes.
+ * 1. CPU sees memory as two chunks: 0-256M@0x0, and the rest @0x4000+256M
+ * 2. PCI sees memory as one big chunk @0x0 (or we could use 0x4000 for
+ *native-endian)
+ * 3. All other devices see memory as one big chunk at 0x4000
+ * 4. Non-PCI devices will pass NULL as struct device*
+ *
+ * Thus we translate differently, depending on device.
+ */
+
+#define RAM_OFFSET_MASK 0x3fffUL
+
+dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+   dma_addr_t dma_addr = paddr & 

[PATCH 18/25] MIPS: loongson64: use generic dma noncoherent ops

2018-05-25 Thread Christoph Hellwig
Provide phys_to_dma/dma_to_phys helpers, everything else is generic.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/Kconfig |  1 +
 .../asm/mach-loongson64/dma-coherence.h   | 69 ---
 arch/mips/loongson64/Kconfig  |  2 -
 arch/mips/loongson64/common/Makefile  |  1 +
 arch/mips/loongson64/common/dma.c | 16 +
 5 files changed, 18 insertions(+), 71 deletions(-)
 delete mode 100644 arch/mips/include/asm/mach-loongson64/dma-coherence.h
 create mode 100644 arch/mips/loongson64/common/dma.c

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index b39b430c92a3..3140955bc77c 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1822,6 +1822,7 @@ config CPU_LOONGSON2
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_HUGEPAGES
+   select ARCH_HAS_PHYS_TO_DMA
 
 config CPU_LOONGSON1
bool
diff --git a/arch/mips/include/asm/mach-loongson64/dma-coherence.h 
b/arch/mips/include/asm/mach-loongson64/dma-coherence.h
deleted file mode 100644
index 651dd2eb3ee5..
--- a/arch/mips/include/asm/mach-loongson64/dma-coherence.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2006, 07  Ralf Baechle 
- * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
- * Author: Fuxin Zhang, zhan...@lemote.com
- *
- */
-#ifndef __ASM_MACH_LOONGSON64_DMA_COHERENCE_H
-#define __ASM_MACH_LOONGSON64_DMA_COHERENCE_H
-
-#ifdef CONFIG_SWIOTLB
-#include 
-#endif
-
-struct device;
-
-static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
- size_t size)
-{
-   return virt_to_phys(addr) | 0x8000;
-}
-
-static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
-  struct page *page)
-{
-   return page_to_phys(page) | 0x8000;
-}
-
-static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
-   dma_addr_t dma_addr)
-{
-#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT)
-   return (dma_addr > 0x8fff) ? dma_addr : (dma_addr & 0x0fff);
-#else
-   return dma_addr & 0x7fff;
-#endif
-}
-
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
-   size_t size, enum dma_data_direction direction)
-{
-}
-
-static inline int plat_dma_supported(struct device *dev, u64 mask)
-{
-   /*
-* we fall back to GFP_DMA when the mask isn't all 1s,
-* so we can't guarantee allocations that must be
-* within a tighter range than GFP_DMA..
-*/
-   if (mask < DMA_BIT_MASK(24))
-   return 0;
-
-   return 1;
-}
-
-static inline int plat_device_is_coherent(struct device *dev)
-{
-   return 0;
-}
-
-static inline void plat_post_dma_flush(struct device *dev)
-{
-}
-
-#endif /* __ASM_MACH_LOONGSON64_DMA_COHERENCE_H */
diff --git a/arch/mips/loongson64/Kconfig b/arch/mips/loongson64/Kconfig
index a785bf8da3f3..c865b4b9b775 100644
--- a/arch/mips/loongson64/Kconfig
+++ b/arch/mips/loongson64/Kconfig
@@ -13,7 +13,6 @@ config LEMOTE_FULOONG2E
select CSRC_R4K
select SYS_HAS_CPU_LOONGSON2E
select DMA_NONCOHERENT
-   select MIPS_DMA_DEFAULT
select BOOT_ELF32
select BOARD_SCACHE
select HW_HAS_PCI
@@ -45,7 +44,6 @@ config LEMOTE_MACH2F
select CS5536
select CSRC_R4K if ! MIPS_EXTERNAL_TIMER
select DMA_NONCOHERENT
-   select MIPS_DMA_DEFAULT
select GENERIC_ISA_DMA_SUPPORT_BROKEN
select HAVE_CLK
select HW_HAS_PCI
diff --git a/arch/mips/loongson64/common/Makefile 
b/arch/mips/loongson64/common/Makefile
index 684624f61f5a..57ee03022941 100644
--- a/arch/mips/loongson64/common/Makefile
+++ b/arch/mips/loongson64/common/Makefile
@@ -6,6 +6,7 @@
 obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \
 bonito-irq.o mem.o machtype.o platform.o serial.o
 obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_CPU_LOONGSON2) += dma.o
 
 #
 # Serial port support
diff --git a/arch/mips/loongson64/common/dma.c 
b/arch/mips/loongson64/common/dma.c
new file mode 100644
index ..95ede4b0fbbb
--- /dev/null
+++ b/arch/mips/loongson64/common/dma.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+#include 
+
+dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+   return paddr | 0x8000;
+}
+
+phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
+{
+#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT)
+   if (dma_addr > 0x8fff)
+   return dma_addr;
+#endif
+   return dma_addr & 0x0fff;
+}
-- 
2.17.0

___
iommu mailing list

[PATCH 17/25] MIPS: use generic dma noncoherent ops for simple noncoherent platforms

2018-05-25 Thread Christoph Hellwig
Convert everything not overriding dma-coherence.h to the generic
noncoherent ops.  The new dma-noncoherent.c file duplicates a lot of
the code in dma-default.c, but that file will be gone by the end of
this series.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/Kconfig   |  24 +---
 arch/mips/include/asm/dma-mapping.h |   2 +
 arch/mips/loongson32/Kconfig|   2 -
 arch/mips/mm/Makefile   |   1 +
 arch/mips/mm/dma-noncoherent.c  | 208 
 arch/mips/pic32/Kconfig |   1 -
 arch/mips/txx9/Kconfig  |   1 -
 arch/mips/vr41xx/Kconfig|   5 -
 8 files changed, 216 insertions(+), 28 deletions(-)
 create mode 100644 arch/mips/mm/dma-noncoherent.c

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 934696595ad6..b39b430c92a3 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -96,7 +96,6 @@ config MIPS_GENERIC
select IRQ_MIPS_CPU
select LIBFDT
select MIPS_CPU_SCACHE
-   select MIPS_DMA_DEFAULT
select MIPS_GIC
select MIPS_L1_CACHE_SHIFT_7
select NO_EXCEPT_FILL
@@ -140,7 +139,6 @@ config MIPS_ALCHEMY
select CEVT_R4K
select CSRC_R4K
select IRQ_MIPS_CPU
-   select MIPS_DMA_DEFAULT
select DMA_MAYBE_COHERENT   # Au1000,1500,1100 aren't, rest is
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_32BIT_KERNEL
@@ -156,7 +154,6 @@ config AR7
select CEVT_R4K
select CSRC_R4K
select IRQ_MIPS_CPU
-   select MIPS_DMA_DEFAULT
select NO_EXCEPT_FILL
select SWAP_IO_SPACE
select SYS_HAS_CPU_MIPS32_R1
@@ -199,7 +196,6 @@ config ATH79
select COMMON_CLK
select CLKDEV_LOOKUP
select IRQ_MIPS_CPU
-   select MIPS_DMA_DEFAULT
select MIPS_MACHINE
select SYS_HAS_CPU_MIPS32_R2
select SYS_HAS_EARLY_PRINTK
@@ -257,7 +253,6 @@ config BCM47XX
select HW_HAS_PCI
select IRQ_MIPS_CPU
select SYS_HAS_CPU_MIPS32_R1
-   select MIPS_DMA_DEFAULT
select NO_EXCEPT_FILL
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -281,7 +276,6 @@ config BCM63XX
select SYNC_R4K
select DMA_NONCOHERENT
select IRQ_MIPS_CPU
-   select MIPS_DMA_DEFAULT
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_HAS_EARLY_PRINTK
@@ -304,7 +298,6 @@ config MIPS_COBALT
select I8259
select IRQ_MIPS_CPU
select IRQ_GT641XX
-   select MIPS_DMA_DEFAULT
select PCI_GT64XXX_PCI0
select PCI
select SYS_HAS_CPU_NEVADA
@@ -325,7 +318,6 @@ config MACH_DECSTATION
select CPU_R4000_WORKAROUNDS if 64BIT
select CPU_R4400_WORKAROUNDS if 64BIT
select DMA_NONCOHERENT
-   select MIPS_DMA_DEFAULT
select NO_IOPORT_MAP
select IRQ_MIPS_CPU
select SYS_HAS_CPU_R3000
@@ -385,7 +377,6 @@ config MACH_INGENIC
select SYS_SUPPORTS_ZBOOT_UART16550
select DMA_NONCOHERENT
select IRQ_MIPS_CPU
-   select MIPS_DMA_DEFAULT
select PINCTRL
select GPIOLIB
select COMMON_CLK
@@ -400,7 +391,6 @@ config LANTIQ
select IRQ_MIPS_CPU
select CEVT_R4K
select CSRC_R4K
-   select MIPS_DMA_DEFAULT
select SYS_HAS_CPU_MIPS32_R1
select SYS_HAS_CPU_MIPS32_R2
select SYS_SUPPORTS_BIG_ENDIAN
@@ -428,7 +418,6 @@ config LASAT
select SYS_HAS_EARLY_PRINTK
select HW_HAS_PCI
select IRQ_MIPS_CPU
-   select MIPS_DMA_DEFAULT
select PCI_GT64XXX_PCI0
select MIPS_NILE4
select R5000_CPU_SCACHE
@@ -474,7 +463,6 @@ config MACH_PISTACHIO
select LIBFDT
select MFD_SYSCON
select MIPS_CPU_SCACHE
-   select MIPS_DMA_DEFAULT
select MIPS_GIC
select PINCTRL
select REGULATOR
@@ -507,7 +495,6 @@ config MIPS_MALTA
select GENERIC_ISA_DMA
select HAVE_PCSPKR_PLATFORM
select IRQ_MIPS_CPU
-   select MIPS_DMA_DEFAULT
select MIPS_GIC
select HW_HAS_PCI
select I8253
@@ -602,7 +589,6 @@ config PMC_MSP
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_MIPS16
select IRQ_MIPS_CPU
-   select MIPS_DMA_DEFAULT
select SERIAL_8250
select SERIAL_8250_CONSOLE
select USB_EHCI_BIG_ENDIAN_MMIO
@@ -620,7 +606,6 @@ config RALINK
select BOOT_RAW
select DMA_NONCOHERENT
select IRQ_MIPS_CPU
-   select MIPS_DMA_DEFAULT
select USE_OF
select SYS_HAS_CPU_MIPS32_R1
select SYS_HAS_CPU_MIPS32_R2
@@ -647,7 +632,6 @@ config SGI_IP22
select I8259
select IP22_CPU_SCACHE
select IRQ_MIPS_CPU
-   select MIPS_DMA_DEFAULT
select GENERIC_ISA_DMA_SUPPORT_BROKEN
select SGI_HAS_I8042
select SGI_HAS_INDYDOG
@@ -708,7 +692,6 @@ config SGI_IP28

[PATCH 16/25] MIPS: move coherentio setup to setup.c

2018-05-25 Thread Christoph Hellwig
We want to be able to use it even when not building dma-default.c
in the near future.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/kernel/setup.c   | 24 
 arch/mips/mm/dma-default.c | 23 ---
 2 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 563188ac6fa2..8dc72797d5cb 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1055,3 +1056,26 @@ static int __init debugfs_mips(void)
 }
 arch_initcall(debugfs_mips);
 #endif
+
+#if defined(CONFIG_DMA_MAYBE_COHERENT) && !defined(CONFIG_DMA_PERDEV_COHERENT)
+/* User defined DMA coherency from command line. */
+enum coherent_io_user_state coherentio = IO_COHERENCE_DEFAULT;
+EXPORT_SYMBOL_GPL(coherentio);
+int hw_coherentio = 0; /* Actual hardware supported DMA coherency setting. */
+
+static int __init setcoherentio(char *str)
+{
+   coherentio = IO_COHERENCE_ENABLED;
+   pr_info("Hardware DMA cache coherency (command line)\n");
+   return 0;
+}
+early_param("coherentio", setcoherentio);
+
+static int __init setnocoherentio(char *str)
+{
+   coherentio = IO_COHERENCE_DISABLED;
+   pr_info("Software DMA cache coherency (command line)\n");
+   return 0;
+}
+early_param("nocoherentio", setnocoherentio);
+#endif
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 2db6c2a6f964..10b56e8a2076 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -24,29 +24,6 @@
 
 #include 
 
-#if defined(CONFIG_DMA_MAYBE_COHERENT) && !defined(CONFIG_DMA_PERDEV_COHERENT)
-/* User defined DMA coherency from command line. */
-enum coherent_io_user_state coherentio = IO_COHERENCE_DEFAULT;
-EXPORT_SYMBOL_GPL(coherentio);
-int hw_coherentio = 0; /* Actual hardware supported DMA coherency setting. */
-
-static int __init setcoherentio(char *str)
-{
-   coherentio = IO_COHERENCE_ENABLED;
-   pr_info("Hardware DMA cache coherency (command line)\n");
-   return 0;
-}
-early_param("coherentio", setcoherentio);
-
-static int __init setnocoherentio(char *str)
-{
-   coherentio = IO_COHERENCE_DISABLED;
-   pr_info("Software DMA cache coherency (command line)\n");
-   return 0;
-}
-early_param("nocoherentio", setnocoherentio);
-#endif
-
 static inline struct page *dma_addr_to_page(struct device *dev,
dma_addr_t dma_addr)
 {
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 15/25] MIPS: IP27: use dma_direct_ops

2018-05-25 Thread Christoph Hellwig
IP27 is coherent and has a reasonably direct mapping, just with a little
per-bus offset added into the dma address.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/Kconfig |  2 +-
 .../include/asm/mach-ip27/dma-coherence.h | 70 ---
 arch/mips/pci/pci-ip27.c  | 14 
 3 files changed, 15 insertions(+), 71 deletions(-)
 delete mode 100644 arch/mips/include/asm/mach-ip27/dma-coherence.h

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 173e5714151c..934696595ad6 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -677,11 +677,11 @@ config SGI_IP22
 
 config SGI_IP27
bool "SGI IP27 (Origin200/2000)"
+   select ARCH_HAS_PHYS_TO_DMA
select FW_ARC
select FW_ARC64
select BOOT_ELF64
select DEFAULT_SGI_PARTITION
-   select MIPS_DMA_DEFAULT
select SYS_HAS_EARLY_PRINTK
select HW_HAS_PCI
select NR_CPUS_DEFAULT_64
diff --git a/arch/mips/include/asm/mach-ip27/dma-coherence.h 
b/arch/mips/include/asm/mach-ip27/dma-coherence.h
deleted file mode 100644
index 04d862020ac9..
--- a/arch/mips/include/asm/mach-ip27/dma-coherence.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2006  Ralf Baechle 
- *
- */
-#ifndef __ASM_MACH_IP27_DMA_COHERENCE_H
-#define __ASM_MACH_IP27_DMA_COHERENCE_H
-
-#include 
-
-#define pdev_to_baddr(pdev, addr) \
-   (BRIDGE_CONTROLLER(pdev->bus)->baddr + (addr))
-#define dev_to_baddr(dev, addr) \
-   pdev_to_baddr(to_pci_dev(dev), (addr))
-
-struct device;
-
-static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
-   size_t size)
-{
-   dma_addr_t pa = dev_to_baddr(dev, virt_to_phys(addr));
-
-   return pa;
-}
-
-static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
-   struct page *page)
-{
-   dma_addr_t pa = dev_to_baddr(dev, page_to_phys(page));
-
-   return pa;
-}
-
-static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
-   dma_addr_t dma_addr)
-{
-   return dma_addr & ~(0xffUL << 56);
-}
-
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
-   size_t size, enum dma_data_direction direction)
-{
-}
-
-static inline int plat_dma_supported(struct device *dev, u64 mask)
-{
-   /*
-* we fall back to GFP_DMA when the mask isn't all 1s,
-* so we can't guarantee allocations that must be
-* within a tighter range than GFP_DMA..
-*/
-   if (mask < DMA_BIT_MASK(24))
-   return 0;
-
-   return 1;
-}
-
-static inline void plat_post_dma_flush(struct device *dev)
-{
-}
-
-static inline int plat_device_is_coherent(struct device *dev)
-{
-   return 1;   /* IP27 non-coherent mode is unsupported */
-}
-
-#endif /* __ASM_MACH_IP27_DMA_COHERENCE_H */
diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c
index 0f09eafa5e3a..65b48d41a229 100644
--- a/arch/mips/pci/pci-ip27.c
+++ b/arch/mips/pci/pci-ip27.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -182,6 +183,19 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
return 0;
 }
 
+dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+   struct pci_dev *pdev = to_pci_dev(dev);
+   struct bridge_controller *bc = BRIDGE_CONTROLLER(pdev->bus);
+
+   return bc->baddr + paddr;
+}
+
+phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
+{
+   return dma_addr & ~(0xffUL << 56);
+}
+
 /*
  * Device might live on a subordinate PCI bus. XXX Walk up the chain of buses
  * to find the slot number in sense of the bridge device register.
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 14/25] MIPS: use dma_direct_ops for coherent I/O

2018-05-25 Thread Christoph Hellwig
Switch the simple cache coherent architectures that don't require any
DMA address translation to dma_direct_ops.

We'll soon use at least parts of the direct DMA ops implementation for
all platforms, so select the symbol globally.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/Kconfig   | 15 +--
 arch/mips/include/asm/dma-mapping.h |  2 +-
 2 files changed, 2 insertions(+), 15 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 24cc20ea60b9..173e5714151c 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -16,6 +16,7 @@ config MIPS
select BUILDTIME_EXTABLE_SORT
select CLONE_BACKWARDS
select CPU_PM if CPU_IDLE
+   select DMA_DIRECT_OPS
select GENERIC_ATOMIC64 if !64BIT
select GENERIC_CLOCKEVENTS
select GENERIC_CMOS_UPDATE
@@ -563,7 +564,6 @@ config NEC_MARKEINS
bool "NEC EMMA2RH Mark-eins board"
select SOC_EMMA2RH
select HW_HAS_PCI
-   select MIPS_DMA_DEFAULT
help
  This enables support for the NEC Electronics Mark-eins boards.
 
@@ -577,14 +577,12 @@ config MACH_VR41XX
 
 config NXP_STB220
bool "NXP STB220 board"
-   select MIPS_DMA_DEFAULT
select SOC_PNX833X
help
 Support for NXP Semiconductors STB220 Development Board.
 
 config NXP_STB225
bool "NXP 225 board"
-   select MIPS_DMA_DEFAULT
select SOC_PNX833X
select SOC_PNX8335
help
@@ -762,7 +760,6 @@ config SGI_IP32
 config SIBYTE_CRHINE
bool "Sibyte BCM91120C-CRhine"
select BOOT_ELF32
-   select MIPS_DMA_DEFAULT
select SIBYTE_BCM1120
select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1
@@ -772,7 +769,6 @@ config SIBYTE_CRHINE
 config SIBYTE_CARMEL
bool "Sibyte BCM91120x-Carmel"
select BOOT_ELF32
-   select MIPS_DMA_DEFAULT
select SIBYTE_BCM1120
select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1
@@ -782,7 +778,6 @@ config SIBYTE_CARMEL
 config SIBYTE_CRHONE
bool "Sibyte BCM91125C-CRhone"
select BOOT_ELF32
-   select MIPS_DMA_DEFAULT
select SIBYTE_BCM1125
select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1
@@ -793,7 +788,6 @@ config SIBYTE_CRHONE
 config SIBYTE_RHONE
bool "Sibyte BCM91125E-Rhone"
select BOOT_ELF32
-   select MIPS_DMA_DEFAULT
select SIBYTE_BCM1125H
select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1
@@ -804,7 +798,6 @@ config SIBYTE_SWARM
bool "Sibyte BCM91250A-SWARM"
select BOOT_ELF32
select HAVE_PATA_PLATFORM
-   select MIPS_DMA_DEFAULT
select SIBYTE_SB1250
select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1
@@ -817,7 +810,6 @@ config SIBYTE_LITTLESUR
bool "Sibyte BCM91250C2-LittleSur"
select BOOT_ELF32
select HAVE_PATA_PLATFORM
-   select MIPS_DMA_DEFAULT
select SIBYTE_SB1250
select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1
@@ -828,7 +820,6 @@ config SIBYTE_LITTLESUR
 config SIBYTE_SENTOSA
bool "Sibyte BCM91250E-Sentosa"
select BOOT_ELF32
-   select MIPS_DMA_DEFAULT
select SIBYTE_SB1250
select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1
@@ -838,7 +829,6 @@ config SIBYTE_SENTOSA
 config SIBYTE_BIGSUR
bool "Sibyte BCM91480B-BigSur"
select BOOT_ELF32
-   select MIPS_DMA_DEFAULT
select NR_CPUS_DEFAULT_4
select SIBYTE_BCM1x80
select SWAP_IO_SPACE
@@ -959,7 +949,6 @@ config NLM_XLR_BOARD
select SYS_HAS_CPU_XLR
select SYS_SUPPORTS_SMP
select HW_HAS_PCI
-   select MIPS_DMA_DEFAULT
select SWAP_IO_SPACE
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
@@ -986,7 +975,6 @@ config NLM_XLP_BOARD
select SYS_HAS_CPU_XLP
select SYS_SUPPORTS_SMP
select HW_HAS_PCI
-   select MIPS_DMA_DEFAULT
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
select PHYS_ADDR_T_64BIT
@@ -1012,7 +1000,6 @@ config MIPS_PARAVIRT
bool "Para-Virtualized guest system"
select CEVT_R4K
select CSRC_R4K
-   select MIPS_DMA_DEFAULT
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
diff --git a/arch/mips/include/asm/dma-mapping.h 
b/arch/mips/include/asm/dma-mapping.h
index eaf3d9054104..7c0d4f0ccaa0 100644
--- a/arch/mips/include/asm/dma-mapping.h
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -20,7 +20,7 @@ static inline const struct dma_map_ops 
*get_arch_dma_ops(struct bus_type *bus)
 #elif defined(CONFIG_MIPS_DMA_DEFAULT)
return _default_dma_map_ops;
 #else
-   return NULL;
+   return _direct_ops;
 #endif
 }
 
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 13/25] MIPS: loongson: remove loongson-3 handling from dma-coherence.h

2018-05-25 Thread Christoph Hellwig
Loongson3 is dma coherent and uses swiotlb, so it will never used any
of these helpers.

Signed-off-by: Christoph Hellwig 
---
 .../include/asm/mach-loongson64/dma-coherence.h  | 16 +---
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/arch/mips/include/asm/mach-loongson64/dma-coherence.h 
b/arch/mips/include/asm/mach-loongson64/dma-coherence.h
index b8825a7d1279..651dd2eb3ee5 100644
--- a/arch/mips/include/asm/mach-loongson64/dma-coherence.h
+++ b/arch/mips/include/asm/mach-loongson64/dma-coherence.h
@@ -20,29 +20,19 @@ struct device;
 static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
  size_t size)
 {
-#ifdef CONFIG_CPU_LOONGSON3
-   return __phys_to_dma(dev, virt_to_phys(addr));
-#else
return virt_to_phys(addr) | 0x8000;
-#endif
 }
 
 static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
   struct page *page)
 {
-#ifdef CONFIG_CPU_LOONGSON3
-   return __phys_to_dma(dev, page_to_phys(page));
-#else
return page_to_phys(page) | 0x8000;
-#endif
 }
 
 static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
dma_addr_t dma_addr)
 {
-#if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT)
-   return __dma_to_phys(dev, dma_addr);
-#elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT)
+#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT)
return (dma_addr > 0x8fff) ? dma_addr : (dma_addr & 0x0fff);
 #else
return dma_addr & 0x7fff;
@@ -69,11 +59,7 @@ static inline int plat_dma_supported(struct device *dev, u64 
mask)
 
 static inline int plat_device_is_coherent(struct device *dev)
 {
-#ifdef CONFIG_DMA_NONCOHERENT
return 0;
-#else
-   return 1;
-#endif /* CONFIG_DMA_NONCOHERENT */
 }
 
 static inline void plat_post_dma_flush(struct device *dev)
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 12/25] MIPS: loongson: untangle dma implementations

2018-05-25 Thread Christoph Hellwig
Only loongson-3 is DMA coherent and uses swiotlb.  So move the dma
address translations stubs directly to the loongson-3 code, and remove
a few Kconfig indirections.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/Kconfig|  2 +-
 arch/mips/loongson64/Kconfig |  5 -
 arch/mips/loongson64/common/Makefile |  5 -
 arch/mips/loongson64/loongson-3/Makefile |  2 +-
 .../{common/dma-swiotlb.c => loongson-3/dma.c}   | 16 
 5 files changed, 6 insertions(+), 24 deletions(-)
 rename arch/mips/loongson64/{common/dma-swiotlb.c => loongson-3/dma.c} (68%)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 92cc7943d940..24cc20ea60b9 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -448,7 +448,6 @@ config MACH_LOONGSON32
 
 config MACH_LOONGSON64
bool "Loongson-2/3 family of machines"
-   select ARCH_HAS_PHYS_TO_DMA
select SYS_SUPPORTS_ZBOOT
help
  This enables the support of Loongson-2/3 family of machines.
@@ -1383,6 +1382,7 @@ choice
 config CPU_LOONGSON3
bool "Loongson 3 CPU"
depends on SYS_HAS_CPU_LOONGSON3
+   select ARCH_HAS_PHYS_TO_DMA
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_HUGEPAGES
diff --git a/arch/mips/loongson64/Kconfig b/arch/mips/loongson64/Kconfig
index dbd2a9f9f9a9..a785bf8da3f3 100644
--- a/arch/mips/loongson64/Kconfig
+++ b/arch/mips/loongson64/Kconfig
@@ -93,7 +93,6 @@ config LOONGSON_MACH3X
select LOONGSON_MC146818
select ZONE_DMA32
select LEFI_FIRMWARE_INTERFACE
-   select PHYS48_TO_HT40
help
Generic Loongson 3 family machines utilize the 3A/3B revision
of Loongson processor and RS780/SBX00 chipset.
@@ -132,10 +131,6 @@ config LOONGSON_UART_BASE
default y
depends on EARLY_PRINTK || SERIAL_8250
 
-config PHYS48_TO_HT40
-   bool
-   default y if CPU_LOONGSON3
-
 config LOONGSON_MC146818
bool
default n
diff --git a/arch/mips/loongson64/common/Makefile 
b/arch/mips/loongson64/common/Makefile
index 8235ac7eac95..684624f61f5a 100644
--- a/arch/mips/loongson64/common/Makefile
+++ b/arch/mips/loongson64/common/Makefile
@@ -25,8 +25,3 @@ obj-$(CONFIG_CS5536) += cs5536/
 #
 
 obj-$(CONFIG_SUSPEND) += pm.o
-
-#
-# Big Memory (SWIOTLB) Support
-#
-obj-$(CONFIG_SWIOTLB) += dma-swiotlb.o
diff --git a/arch/mips/loongson64/loongson-3/Makefile 
b/arch/mips/loongson64/loongson-3/Makefile
index 44bc1482158b..b5a0c2fa5446 100644
--- a/arch/mips/loongson64/loongson-3/Makefile
+++ b/arch/mips/loongson64/loongson-3/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for Loongson-3 family machines
 #
-obj-y  += irq.o cop2-ex.o platform.o acpi_init.o
+obj-y  += irq.o cop2-ex.o platform.o acpi_init.o dma.o
 
 obj-$(CONFIG_SMP)  += smp.o
 
diff --git a/arch/mips/loongson64/common/dma-swiotlb.c 
b/arch/mips/loongson64/loongson-3/dma.c
similarity index 68%
rename from arch/mips/loongson64/common/dma-swiotlb.c
rename to arch/mips/loongson64/loongson-3/dma.c
index a4f554bf1232..5e86635f71db 100644
--- a/arch/mips/loongson64/common/dma-swiotlb.c
+++ b/arch/mips/loongson64/loongson-3/dma.c
@@ -5,26 +5,18 @@
 
 dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
-   long nid;
-#ifdef CONFIG_PHYS48_TO_HT40
/* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from
 * Loongson-3's 48bit address space and embed it into 40bit */
-   nid = (paddr >> 44) & 0x3;
-   paddr = ((nid << 44) ^ paddr) | (nid << 37);
-#endif
-   return paddr;
+   long nid = (paddr >> 44) & 0x3;
+   return ((nid << 44) ^ paddr) | (nid << 37);
 }
 
 phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr)
 {
-   long nid;
-#ifdef CONFIG_PHYS48_TO_HT40
/* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from
 * Loongson-3's 48bit address space and embed it into 40bit */
-   nid = (daddr >> 37) & 0x3;
-   daddr = ((nid << 37) ^ daddr) | (nid << 44);
-#endif
-   return daddr;
+   long nid = (daddr >> 37) & 0x3;
+   return ((nid << 37) ^ daddr) | (nid << 44);
 }
 
 void __init plat_swiotlb_setup(void)
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 11/25] MIPS: Octeon: move swiotlb declarations out of dma-coherence.h

2018-05-25 Thread Christoph Hellwig
No need to pull them into a global header.

Signed-off-by: Christoph Hellwig 
---
 .../asm/mach-cavium-octeon/dma-coherence.h | 18 --
 arch/mips/include/asm/octeon/pci-octeon.h  |  3 +++
 arch/mips/pci/pci-octeon.c |  2 --
 arch/mips/pci/pcie-octeon.c|  2 --
 4 files changed, 3 insertions(+), 22 deletions(-)
 delete mode 100644 arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h

diff --git a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h 
b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
deleted file mode 100644
index 66eee98b8b8d..
--- a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2006  Ralf Baechle 
- */
-#ifndef __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H
-#define __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H
-
-#include 
-
-struct device;
-
-extern void octeon_pci_dma_init(void);
-extern char *octeon_swiotlb;
-
-#endif /* __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/octeon/pci-octeon.h 
b/arch/mips/include/asm/octeon/pci-octeon.h
index 1884609741a8..b12d9a3fbfb6 100644
--- a/arch/mips/include/asm/octeon/pci-octeon.h
+++ b/arch/mips/include/asm/octeon/pci-octeon.h
@@ -63,4 +63,7 @@ enum octeon_dma_bar_type {
  */
 extern enum octeon_dma_bar_type octeon_dma_bar_type;
 
+void octeon_pci_dma_init(void);
+extern char *octeon_swiotlb;
+
 #endif
diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c
index a20697df3539..5017d5843c5a 100644
--- a/arch/mips/pci/pci-octeon.c
+++ b/arch/mips/pci/pci-octeon.c
@@ -21,8 +21,6 @@
 #include 
 #include 
 
-#include 
-
 #define USE_OCTEON_INTERNAL_ARBITER
 
 /*
diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c
index 87ba86bd8696..9cc5905860ef 100644
--- a/arch/mips/pci/pcie-octeon.c
+++ b/arch/mips/pci/pcie-octeon.c
@@ -94,8 +94,6 @@ union cvmx_pcie_address {
 
 static int cvmx_pcie_rc_initialize(int pcie_port);
 
-#include 
-
 /**
  * Return the Core virtual base address for PCIe IO access. IOs are
  * read/written as an offset from this address.
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 10/25] MIPS: Octeon: remove mips dma-default stubs

2018-05-25 Thread Christoph Hellwig
Octeon doesn't use the dma-default code, and now doesn't built it either,
so these stubs can be removed.

Signed-off-by: Christoph Hellwig 
---
 .../asm/mach-cavium-octeon/dma-coherence.h| 48 ---
 1 file changed, 48 deletions(-)

diff --git a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h 
b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
index c0254c72d97b..66eee98b8b8d 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
@@ -4,11 +4,6 @@
  * for more details.
  *
  * Copyright (C) 2006  Ralf Baechle 
- *
- *
- * Similar to mach-generic/dma-coherence.h except
- * plat_device_is_coherent hard coded to return 1.
- *
  */
 #ifndef __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H
 #define __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H
@@ -18,49 +13,6 @@
 struct device;
 
 extern void octeon_pci_dma_init(void);
-
-static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
-   size_t size)
-{
-   BUG();
-   return 0;
-}
-
-static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
-   struct page *page)
-{
-   BUG();
-   return 0;
-}
-
-static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
-   dma_addr_t dma_addr)
-{
-   BUG();
-   return 0;
-}
-
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
-   size_t size, enum dma_data_direction direction)
-{
-   BUG();
-}
-
-static inline int plat_dma_supported(struct device *dev, u64 mask)
-{
-   BUG();
-   return 0;
-}
-
-static inline int plat_device_is_coherent(struct device *dev)
-{
-   return 1;
-}
-
-static inline void plat_post_dma_flush(struct device *dev)
-{
-}
-
 extern char *octeon_swiotlb;
 
 #endif /* __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H */
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 09/25] MIPS: make the default mips dma implementation optional

2018-05-25 Thread Christoph Hellwig
Octeon and loonson64 already don't use it at all, and we're going to
migrate more plaforms away from it.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/Kconfig   | 40 +
 arch/mips/include/asm/dma-mapping.h |  4 ++-
 arch/mips/jazz/Kconfig  |  3 +++
 arch/mips/loongson32/Kconfig|  2 ++
 arch/mips/loongson64/Kconfig|  2 ++
 arch/mips/mm/Makefile   |  3 ++-
 arch/mips/pic32/Kconfig |  1 +
 arch/mips/txx9/Kconfig  |  1 +
 arch/mips/vr41xx/Kconfig|  5 
 9 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 43bb037301f6..92cc7943d940 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -71,6 +71,9 @@ config MIPS
select SYSCTL_EXCEPTION_TRACE
select VIRT_TO_BUS
 
+config MIPS_DMA_DEFAULT
+   bool
+
 menu "Machine selection"
 
 choice
@@ -92,6 +95,7 @@ config MIPS_GENERIC
select IRQ_MIPS_CPU
select LIBFDT
select MIPS_CPU_SCACHE
+   select MIPS_DMA_DEFAULT
select MIPS_GIC
select MIPS_L1_CACHE_SHIFT_7
select NO_EXCEPT_FILL
@@ -135,6 +139,7 @@ config MIPS_ALCHEMY
select CEVT_R4K
select CSRC_R4K
select IRQ_MIPS_CPU
+   select MIPS_DMA_DEFAULT
select DMA_MAYBE_COHERENT   # Au1000,1500,1100 aren't, rest is
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_32BIT_KERNEL
@@ -150,6 +155,7 @@ config AR7
select CEVT_R4K
select CSRC_R4K
select IRQ_MIPS_CPU
+   select MIPS_DMA_DEFAULT
select NO_EXCEPT_FILL
select SWAP_IO_SPACE
select SYS_HAS_CPU_MIPS32_R1
@@ -172,6 +178,7 @@ config ATH25
select DMA_NONCOHERENT
select IRQ_MIPS_CPU
select IRQ_DOMAIN
+   select MIPS_DMA_DEFAULT
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_32BIT_KERNEL
@@ -191,6 +198,7 @@ config ATH79
select COMMON_CLK
select CLKDEV_LOOKUP
select IRQ_MIPS_CPU
+   select MIPS_DMA_DEFAULT
select MIPS_MACHINE
select SYS_HAS_CPU_MIPS32_R2
select SYS_HAS_EARLY_PRINTK
@@ -217,6 +225,7 @@ config BMIPS_GENERIC
select BCM7120_L2_IRQ
select BRCMSTB_L2_IRQ
select IRQ_MIPS_CPU
+   select MIPS_DMA_DEFAULT
select DMA_NONCOHERENT
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -247,6 +256,7 @@ config BCM47XX
select HW_HAS_PCI
select IRQ_MIPS_CPU
select SYS_HAS_CPU_MIPS32_R1
+   select MIPS_DMA_DEFAULT
select NO_EXCEPT_FILL
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -270,6 +280,7 @@ config BCM63XX
select SYNC_R4K
select DMA_NONCOHERENT
select IRQ_MIPS_CPU
+   select MIPS_DMA_DEFAULT
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_HAS_EARLY_PRINTK
@@ -292,6 +303,7 @@ config MIPS_COBALT
select I8259
select IRQ_MIPS_CPU
select IRQ_GT641XX
+   select MIPS_DMA_DEFAULT
select PCI_GT64XXX_PCI0
select PCI
select SYS_HAS_CPU_NEVADA
@@ -312,6 +324,7 @@ config MACH_DECSTATION
select CPU_R4000_WORKAROUNDS if 64BIT
select CPU_R4400_WORKAROUNDS if 64BIT
select DMA_NONCOHERENT
+   select MIPS_DMA_DEFAULT
select NO_IOPORT_MAP
select IRQ_MIPS_CPU
select SYS_HAS_CPU_R3000
@@ -371,6 +384,7 @@ config MACH_INGENIC
select SYS_SUPPORTS_ZBOOT_UART16550
select DMA_NONCOHERENT
select IRQ_MIPS_CPU
+   select MIPS_DMA_DEFAULT
select PINCTRL
select GPIOLIB
select COMMON_CLK
@@ -385,6 +399,7 @@ config LANTIQ
select IRQ_MIPS_CPU
select CEVT_R4K
select CSRC_R4K
+   select MIPS_DMA_DEFAULT
select SYS_HAS_CPU_MIPS32_R1
select SYS_HAS_CPU_MIPS32_R2
select SYS_SUPPORTS_BIG_ENDIAN
@@ -412,6 +427,7 @@ config LASAT
select SYS_HAS_EARLY_PRINTK
select HW_HAS_PCI
select IRQ_MIPS_CPU
+   select MIPS_DMA_DEFAULT
select PCI_GT64XXX_PCI0
select MIPS_NILE4
select R5000_CPU_SCACHE
@@ -458,6 +474,7 @@ config MACH_PISTACHIO
select LIBFDT
select MFD_SYSCON
select MIPS_CPU_SCACHE
+   select MIPS_DMA_DEFAULT
select MIPS_GIC
select PINCTRL
select REGULATOR
@@ -490,6 +507,7 @@ config MIPS_MALTA
select GENERIC_ISA_DMA
select HAVE_PCSPKR_PLATFORM
select IRQ_MIPS_CPU
+   select MIPS_DMA_DEFAULT
select MIPS_GIC
select HW_HAS_PCI
select I8253
@@ -546,6 +564,7 @@ config NEC_MARKEINS
bool "NEC EMMA2RH Mark-eins board"
select SOC_EMMA2RH
select HW_HAS_PCI
+   select MIPS_DMA_DEFAULT
help
  This enables 

[PATCH 08/25] MIPS: remove the mips_dma_map_ops indirection

2018-05-25 Thread Christoph Hellwig
And use mips_default_dma_map_ops directly.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/include/asm/dma-mapping.h | 4 ++--
 arch/mips/mm/dma-default.c  | 6 ++
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/mips/include/asm/dma-mapping.h 
b/arch/mips/include/asm/dma-mapping.h
index ebcce3e22297..f24b052ec740 100644
--- a/arch/mips/include/asm/dma-mapping.h
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -10,7 +10,7 @@
 #include 
 #endif
 
-extern const struct dma_map_ops *mips_dma_map_ops;
+extern const struct dma_map_ops mips_default_dma_map_ops;
 extern const struct dma_map_ops mips_swiotlb_ops;
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
@@ -18,7 +18,7 @@ static inline const struct dma_map_ops 
*get_arch_dma_ops(struct bus_type *bus)
 #ifdef CONFIG_SWIOTLB
return _swiotlb_ops;
 #else
-   return mips_dma_map_ops;
+   return _default_dma_map_ops;
 #endif
 }
 
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index f9fef0028ca2..2db6c2a6f964 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -384,7 +384,7 @@ static void mips_dma_cache_sync(struct device *dev, void 
*vaddr, size_t size,
__dma_sync_virtual(vaddr, size, direction);
 }
 
-static const struct dma_map_ops mips_default_dma_map_ops = {
+const struct dma_map_ops mips_default_dma_map_ops = {
.alloc = mips_dma_alloc_coherent,
.free = mips_dma_free_coherent,
.mmap = mips_dma_mmap,
@@ -399,6 +399,4 @@ static const struct dma_map_ops mips_default_dma_map_ops = {
.dma_supported = mips_dma_supported,
.cache_sync = mips_dma_cache_sync,
 };
-
-const struct dma_map_ops *mips_dma_map_ops = _default_dma_map_ops;
-EXPORT_SYMBOL(mips_dma_map_ops);
+EXPORT_SYMBOL(mips_default_dma_map_ops);
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 06/25] MIPS: loongson: remove loongson_dma_supported

2018-05-25 Thread Christoph Hellwig
swiotlb_dma_supported will always return true for the a mask
large enough to be covered by wired up physical address, so this
function is pointless.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/loongson64/common/dma-swiotlb.c | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/arch/mips/loongson64/common/dma-swiotlb.c 
b/arch/mips/loongson64/common/dma-swiotlb.c
index 6a739f8ae110..a5e50f2ec301 100644
--- a/arch/mips/loongson64/common/dma-swiotlb.c
+++ b/arch/mips/loongson64/common/dma-swiotlb.c
@@ -56,13 +56,6 @@ static void loongson_dma_sync_sg_for_device(struct device 
*dev,
mb();
 }
 
-static int loongson_dma_supported(struct device *dev, u64 mask)
-{
-   if (mask > DMA_BIT_MASK(loongson_sysconf.dma_mask_bits))
-   return 0;
-   return swiotlb_dma_supported(dev, mask);
-}
-
 dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
long nid;
@@ -99,7 +92,7 @@ static const struct dma_map_ops loongson_dma_map_ops = {
.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
.sync_sg_for_device = loongson_dma_sync_sg_for_device,
.mapping_error = swiotlb_dma_mapping_error,
-   .dma_supported = loongson_dma_supported,
+   .dma_supported = swiotlb_dma_supported,
 };
 
 void __init plat_swiotlb_setup(void)
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 07/25] MIPS: consolidate the swiotlb implementations

2018-05-25 Thread Christoph Hellwig
Octeon and Loongson share exactly the same code, move it into a common
implementation, and use that implementation directly from get_arch_dma_ops.

Also provide the expected dma-direct.h helpers directly instead of
delegating to platform dma-coherence.h headers.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/cavium-octeon/dma-octeon.c  | 61 
 arch/mips/include/asm/dma-direct.h| 17 -
 arch/mips/include/asm/dma-mapping.h   |  5 ++
 .../asm/mach-cavium-octeon/dma-coherence.h| 11 ---
 .../asm/mach-loongson64/dma-coherence.h   | 10 ---
 arch/mips/loongson64/common/dma-swiotlb.c | 71 +--
 arch/mips/mm/Makefile |  1 +
 arch/mips/mm/dma-swiotlb.c| 61 
 8 files changed, 84 insertions(+), 153 deletions(-)
 create mode 100644 arch/mips/mm/dma-swiotlb.c

diff --git a/arch/mips/cavium-octeon/dma-octeon.c 
b/arch/mips/cavium-octeon/dma-octeon.c
index 1e68636c9137..939620b90164 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -11,7 +11,6 @@
  * Copyright (C) 2010 Cavium Networks, Inc.
  */
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -159,49 +158,6 @@ void __init octeon_pci_dma_init(void)
 }
 #endif /* CONFIG_PCI */
 
-static dma_addr_t octeon_dma_map_page(struct device *dev, struct page *page,
-   unsigned long offset, size_t size, enum dma_data_direction direction,
-   unsigned long attrs)
-{
-   dma_addr_t daddr = swiotlb_map_page(dev, page, offset, size,
-   direction, attrs);
-   mb();
-
-   return daddr;
-}
-
-static int octeon_dma_map_sg(struct device *dev, struct scatterlist *sg,
-   int nents, enum dma_data_direction direction, unsigned long attrs)
-{
-   int r = swiotlb_map_sg_attrs(dev, sg, nents, direction, attrs);
-   mb();
-   return r;
-}
-
-static void octeon_dma_sync_single_for_device(struct device *dev,
-   dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
-{
-   swiotlb_sync_single_for_device(dev, dma_handle, size, direction);
-   mb();
-}
-
-static void octeon_dma_sync_sg_for_device(struct device *dev,
-   struct scatterlist *sg, int nelems, enum dma_data_direction direction)
-{
-   swiotlb_sync_sg_for_device(dev, sg, nelems, direction);
-   mb();
-}
-
-static void *octeon_dma_alloc_coherent(struct device *dev, size_t size,
-   dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
-{
-   void *ret = swiotlb_alloc(dev, size, dma_handle, gfp, attrs);
-
-   mb();
-
-   return ret;
-}
-
 dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
 #ifdef CONFIG_PCI
@@ -220,21 +176,6 @@ phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t 
daddr)
return daddr;
 }
 
-static const struct dma_map_ops octeon_swiotlb_ops = {
-   .alloc  = octeon_dma_alloc_coherent,
-   .free   = swiotlb_free,
-   .map_page   = octeon_dma_map_page,
-   .unmap_page = swiotlb_unmap_page,
-   .map_sg = octeon_dma_map_sg,
-   .unmap_sg   = swiotlb_unmap_sg_attrs,
-   .sync_single_for_cpu= swiotlb_sync_single_for_cpu,
-   .sync_single_for_device = octeon_dma_sync_single_for_device,
-   .sync_sg_for_cpu= swiotlb_sync_sg_for_cpu,
-   .sync_sg_for_device = octeon_dma_sync_sg_for_device,
-   .mapping_error  = swiotlb_dma_mapping_error,
-   .dma_supported  = swiotlb_dma_supported
-};
-
 char *octeon_swiotlb;
 
 void __init plat_swiotlb_setup(void)
@@ -297,6 +238,4 @@ void __init plat_swiotlb_setup(void)
 
if (swiotlb_init_with_tbl(octeon_swiotlb, swiotlb_nslabs, 1) == -ENOMEM)
panic("Cannot allocate SWIOTLB buffer");
-
-   mips_dma_map_ops = _swiotlb_ops;
 }
diff --git a/arch/mips/include/asm/dma-direct.h 
b/arch/mips/include/asm/dma-direct.h
index f32f15530aba..b5c240806e1b 100644
--- a/arch/mips/include/asm/dma-direct.h
+++ b/arch/mips/include/asm/dma-direct.h
@@ -1 +1,16 @@
-#include 
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _MIPS_DMA_DIRECT_H
+#define _MIPS_DMA_DIRECT_H 1
+
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t 
size)
+{
+   if (!dev->dma_mask)
+   return false;
+
+   return addr + size - 1 <= *dev->dma_mask;
+}
+
+dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr);
+phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr);
+
+#endif /* _MIPS_DMA_DIRECT_H */
diff --git a/arch/mips/include/asm/dma-mapping.h 
b/arch/mips/include/asm/dma-mapping.h
index 886e75a383f2..ebcce3e22297 100644
--- a/arch/mips/include/asm/dma-mapping.h
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -11,10 +11,15 @@
 #endif
 
 extern const struct dma_map_ops *mips_dma_map_ops;
+extern const struct dma_map_ops mips_swiotlb_ops;
 

[PATCH 05/25] MIPS: Octeon: refactor swiotlb code

2018-05-25 Thread Christoph Hellwig
Share a common set of swiotlb operations, and to instead branch out in
__phys_to_dma/__dma_to_phys for the PCI vs non-PCI case.  Also use const
structures for the PCI methods so that attackers can't use them as
exploit vectors.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/cavium-octeon/dma-octeon.c  | 169 --
 .../asm/mach-cavium-octeon/dma-coherence.h|   2 -
 arch/mips/pci/pci-octeon.c|   2 -
 3 files changed, 70 insertions(+), 103 deletions(-)

diff --git a/arch/mips/cavium-octeon/dma-octeon.c 
b/arch/mips/cavium-octeon/dma-octeon.c
index e5d00c79bd26..1e68636c9137 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -23,10 +23,16 @@
 #include 
 
 #ifdef CONFIG_PCI
+#include 
 #include 
 #include 
 #include 
 
+struct octeon_dma_map_ops {
+   dma_addr_t (*phys_to_dma)(struct device *dev, phys_addr_t paddr);
+   phys_addr_t (*dma_to_phys)(struct device *dev, dma_addr_t daddr);
+};
+
 static dma_addr_t octeon_hole_phys_to_dma(phys_addr_t paddr)
 {
if (paddr >= CVMX_PCIE_BAR1_PHYS_BASE && paddr < 
(CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_PHYS_SIZE))
@@ -43,6 +49,11 @@ static phys_addr_t octeon_hole_dma_to_phys(dma_addr_t daddr)
return daddr;
 }
 
+static const struct octeon_dma_map_ops octeon_gen2_ops = {
+   .phys_to_dma= octeon_hole_phys_to_dma,
+   .dma_to_phys= octeon_hole_dma_to_phys,
+};
+
 static dma_addr_t octeon_gen1_phys_to_dma(struct device *dev, phys_addr_t 
paddr)
 {
if (paddr >= 0x41000ull && paddr < 0x42000ull)
@@ -60,15 +71,10 @@ static phys_addr_t octeon_gen1_dma_to_phys(struct device 
*dev, dma_addr_t daddr)
return daddr;
 }
 
-static dma_addr_t octeon_gen2_phys_to_dma(struct device *dev, phys_addr_t 
paddr)
-{
-   return octeon_hole_phys_to_dma(paddr);
-}
-
-static phys_addr_t octeon_gen2_dma_to_phys(struct device *dev, dma_addr_t 
daddr)
-{
-   return octeon_hole_dma_to_phys(daddr);
-}
+static const struct octeon_dma_map_ops octeon_gen1_ops = {
+   .phys_to_dma= octeon_gen1_phys_to_dma,
+   .dma_to_phys= octeon_gen1_dma_to_phys,
+};
 
 static dma_addr_t octeon_big_phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
@@ -92,6 +98,11 @@ static phys_addr_t octeon_big_dma_to_phys(struct device 
*dev, dma_addr_t daddr)
return daddr;
 }
 
+static const struct octeon_dma_map_ops octeon_big_ops = {
+   .phys_to_dma= octeon_big_phys_to_dma,
+   .dma_to_phys= octeon_big_dma_to_phys,
+};
+
 static dma_addr_t octeon_small_phys_to_dma(struct device *dev,
   phys_addr_t paddr)
 {
@@ -120,6 +131,32 @@ static phys_addr_t octeon_small_dma_to_phys(struct device 
*dev,
return daddr;
 }
 
+static const struct octeon_dma_map_ops octeon_small_ops = {
+   .phys_to_dma= octeon_small_phys_to_dma,
+   .dma_to_phys= octeon_small_dma_to_phys,
+};
+
+static const struct octeon_dma_map_ops *octeon_pci_dma_ops;
+
+void __init octeon_pci_dma_init(void)
+{
+   switch (octeon_dma_bar_type) {
+   case OCTEON_DMA_BAR_TYPE_PCIE2:
+   octeon_pci_dma_ops = _gen2_ops;
+   break;
+   case OCTEON_DMA_BAR_TYPE_PCIE:
+   octeon_pci_dma_ops = _gen1_ops;
+   break;
+   case OCTEON_DMA_BAR_TYPE_BIG:
+   octeon_pci_dma_ops = _big_ops;
+   break;
+   case OCTEON_DMA_BAR_TYPE_SMALL:
+   octeon_pci_dma_ops = _small_ops;
+   break;
+   default:
+   BUG();
+   }
+}
 #endif /* CONFIG_PCI */
 
 static dma_addr_t octeon_dma_map_page(struct device *dev, struct page *page,
@@ -165,57 +202,37 @@ static void *octeon_dma_alloc_coherent(struct device 
*dev, size_t size,
return ret;
 }
 
-static dma_addr_t octeon_unity_phys_to_dma(struct device *dev, phys_addr_t 
paddr)
-{
-   return paddr;
-}
-
-static phys_addr_t octeon_unity_dma_to_phys(struct device *dev, dma_addr_t 
daddr)
-{
-   return daddr;
-}
-
-struct octeon_dma_map_ops {
-   const struct dma_map_ops dma_map_ops;
-   dma_addr_t (*phys_to_dma)(struct device *dev, phys_addr_t paddr);
-   phys_addr_t (*dma_to_phys)(struct device *dev, dma_addr_t daddr);
-};
-
 dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
-   struct octeon_dma_map_ops *ops = container_of(get_dma_ops(dev),
- struct octeon_dma_map_ops,
- dma_map_ops);
-
-   return ops->phys_to_dma(dev, paddr);
+#ifdef CONFIG_PCI
+   if (dev && dev_is_pci(dev))
+   return octeon_pci_dma_ops->phys_to_dma(dev, paddr);
+#endif
+   return paddr;
 }
 
 phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr)
 {
-   struct octeon_dma_map_ops *ops = container_of(get_dma_ops(dev),
- struct 

[PATCH 04/25] MIPS: Octeon: unexport __phys_to_dma and __dma_to_phys

2018-05-25 Thread Christoph Hellwig
These functions are just low-level helpers for the swiotlb and dma-direct
implementations, and should never be used by drivers.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/cavium-octeon/dma-octeon.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/mips/cavium-octeon/dma-octeon.c 
b/arch/mips/cavium-octeon/dma-octeon.c
index 7b335ab21697..e5d00c79bd26 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -13,7 +13,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -190,7 +189,6 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t 
paddr)
 
return ops->phys_to_dma(dev, paddr);
 }
-EXPORT_SYMBOL(__phys_to_dma);
 
 phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr)
 {
@@ -200,7 +198,6 @@ phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t 
daddr)
 
return ops->dma_to_phys(dev, daddr);
 }
-EXPORT_SYMBOL(__dma_to_phys);
 
 static struct octeon_dma_map_ops octeon_linear_dma_map_ops = {
.dma_map_ops = {
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 02/25] MIPS: simplify CONFIG_DMA_NONCOHERENT ifdefs

2018-05-25 Thread Christoph Hellwig
CONFIG_DMA_MAYBE_COHERENT already selects CONFIG_DMA_NONCOHERENT, so we
can remove the extra conditions.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/include/asm/io.h | 4 ++--
 arch/mips/mm/c-r4k.c   | 4 ++--
 arch/mips/mm/cache.c   | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index a7d0b836f2f7..6d6bdc6a48eb 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -588,7 +588,7 @@ static inline void memcpy_toio(volatile void __iomem *dst, 
const void *src, int
  *
  * This API used to be exported; it now is for arch code internal use only.
  */
-#if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT)
+#ifdef CONFIG_DMA_NONCOHERENT
 
 extern void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
 extern void (*_dma_cache_wback)(unsigned long start, unsigned long size);
@@ -607,7 +607,7 @@ extern void (*_dma_cache_inv)(unsigned long start, unsigned 
long size);
 #define dma_cache_inv(start,size)  \
do { (void) (start); (void) (size); } while (0)
 
-#endif /* CONFIG_DMA_NONCOHERENT || CONFIG_DMA_MAYBE_COHERENT */
+#endif /* CONFIG_DMA_NONCOHERENT */
 
 /*
  * Read a 32-bit register that requires a 64-bit read cycle on the bus.
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 6f534b209971..dcfff4f6cd88 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -830,7 +830,7 @@ static void r4k_flush_icache_user_range(unsigned long 
start, unsigned long end)
return __r4k_flush_icache_range(start, end, true);
 }
 
-#if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT)
+#ifdef CONFIG_DMA_NONCOHERENT
 
 static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
 {
@@ -901,7 +901,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned 
long size)
bc_inv(addr, size);
__sync();
 }
-#endif /* CONFIG_DMA_NONCOHERENT || CONFIG_DMA_MAYBE_COHERENT */
+#endif /* CONFIG_DMA_NONCOHERENT */
 
 struct flush_cache_sigtramp_args {
struct mm_struct *mm;
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 0d3c656feba0..70a523151ff3 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -56,7 +56,7 @@ EXPORT_SYMBOL_GPL(local_flush_data_cache_page);
 EXPORT_SYMBOL(flush_data_cache_page);
 EXPORT_SYMBOL(flush_icache_all);
 
-#if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT)
+#ifdef CONFIG_DMA_NONCOHERENT
 
 /* DMA cache operations. */
 void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
@@ -65,7 +65,7 @@ void (*_dma_cache_inv)(unsigned long start, unsigned long 
size);
 
 EXPORT_SYMBOL(_dma_cache_wback_inv);
 
-#endif /* CONFIG_DMA_NONCOHERENT || CONFIG_DMA_MAYBE_COHERENT */
+#endif /* CONFIG_DMA_NONCOHERENT */
 
 /*
  * We could optimize the case where the cache argument is not BCACHE but
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 03/25] MIPS: remove CONFIG_DMA_COHERENT

2018-05-25 Thread Christoph Hellwig
We can just check for !CONFIG_DMA_NONCOHERENT instead and simplify things
a lot.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/Kconfig| 16 
 arch/mips/include/asm/dma-coherence.h|  6 +++---
 arch/mips/include/asm/mach-generic/kmalloc.h |  3 +--
 arch/mips/mti-malta/malta-setup.c|  4 ++--
 arch/mips/sibyte/Kconfig |  1 -
 5 files changed, 6 insertions(+), 24 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 2dcdc13cd65d..43bb037301f6 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -660,7 +660,6 @@ config SGI_IP27
select FW_ARC64
select BOOT_ELF64
select DEFAULT_SGI_PARTITION
-   select DMA_COHERENT
select SYS_HAS_EARLY_PRINTK
select HW_HAS_PCI
select NR_CPUS_DEFAULT_64
@@ -737,7 +736,6 @@ config SGI_IP32
 config SIBYTE_CRHINE
bool "Sibyte BCM91120C-CRhine"
select BOOT_ELF32
-   select DMA_COHERENT
select SIBYTE_BCM1120
select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1
@@ -747,7 +745,6 @@ config SIBYTE_CRHINE
 config SIBYTE_CARMEL
bool "Sibyte BCM91120x-Carmel"
select BOOT_ELF32
-   select DMA_COHERENT
select SIBYTE_BCM1120
select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1
@@ -757,7 +754,6 @@ config SIBYTE_CARMEL
 config SIBYTE_CRHONE
bool "Sibyte BCM91125C-CRhone"
select BOOT_ELF32
-   select DMA_COHERENT
select SIBYTE_BCM1125
select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1
@@ -768,7 +764,6 @@ config SIBYTE_CRHONE
 config SIBYTE_RHONE
bool "Sibyte BCM91125E-Rhone"
select BOOT_ELF32
-   select DMA_COHERENT
select SIBYTE_BCM1125H
select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1
@@ -778,7 +773,6 @@ config SIBYTE_RHONE
 config SIBYTE_SWARM
bool "Sibyte BCM91250A-SWARM"
select BOOT_ELF32
-   select DMA_COHERENT
select HAVE_PATA_PLATFORM
select SIBYTE_SB1250
select SWAP_IO_SPACE
@@ -791,7 +785,6 @@ config SIBYTE_SWARM
 config SIBYTE_LITTLESUR
bool "Sibyte BCM91250C2-LittleSur"
select BOOT_ELF32
-   select DMA_COHERENT
select HAVE_PATA_PLATFORM
select SIBYTE_SB1250
select SWAP_IO_SPACE
@@ -803,7 +796,6 @@ config SIBYTE_LITTLESUR
 config SIBYTE_SENTOSA
bool "Sibyte BCM91250E-Sentosa"
select BOOT_ELF32
-   select DMA_COHERENT
select SIBYTE_SB1250
select SWAP_IO_SPACE
select SYS_HAS_CPU_SB1
@@ -813,7 +805,6 @@ config SIBYTE_SENTOSA
 config SIBYTE_BIGSUR
bool "Sibyte BCM91480B-BigSur"
select BOOT_ELF32
-   select DMA_COHERENT
select NR_CPUS_DEFAULT_4
select SIBYTE_BCM1x80
select SWAP_IO_SPACE
@@ -890,7 +881,6 @@ config CAVIUM_OCTEON_SOC
select CEVT_R4K
select ARCH_HAS_PHYS_TO_DMA
select PHYS_ADDR_T_64BIT
-   select DMA_COHERENT
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
select EDAC_SUPPORT
@@ -939,7 +929,6 @@ config NLM_XLR_BOARD
select PHYS_ADDR_T_64BIT
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_HIGHMEM
-   select DMA_COHERENT
select NR_CPUS_DEFAULT_32
select CEVT_R4K
select CSRC_R4K
@@ -967,7 +956,6 @@ config NLM_XLP_BOARD
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_HIGHMEM
-   select DMA_COHERENT
select NR_CPUS_DEFAULT_32
select CEVT_R4K
select CSRC_R4K
@@ -986,7 +974,6 @@ config MIPS_PARAVIRT
bool "Para-Virtualized guest system"
select CEVT_R4K
select CSRC_R4K
-   select DMA_COHERENT
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
@@ -1112,9 +1099,6 @@ config DMA_PERDEV_COHERENT
bool
select DMA_MAYBE_COHERENT
 
-config DMA_COHERENT
-   bool
-
 config DMA_NONCOHERENT
bool
select NEED_DMA_MAP_STATE
diff --git a/arch/mips/include/asm/dma-coherence.h 
b/arch/mips/include/asm/dma-coherence.h
index 72d0eab02afc..8eda48748ed5 100644
--- a/arch/mips/include/asm/dma-coherence.h
+++ b/arch/mips/include/asm/dma-coherence.h
@@ -21,10 +21,10 @@ enum coherent_io_user_state {
 extern enum coherent_io_user_state coherentio;
 extern int hw_coherentio;
 #else
-#ifdef CONFIG_DMA_COHERENT
-#define coherentio IO_COHERENCE_ENABLED
-#else
+#ifdef CONFIG_DMA_NONCOHERENT
 #define coherentio IO_COHERENCE_DISABLED
+#else
+#define coherentio IO_COHERENCE_ENABLED
 #endif
 #define hw_coherentio  0
 #endif /* CONFIG_DMA_MAYBE_COHERENT */
diff --git a/arch/mips/include/asm/mach-generic/kmalloc.h 
b/arch/mips/include/asm/mach-generic/kmalloc.h
index 74207c7bd00d..649a98338886 100644
--- a/arch/mips/include/asm/mach-generic/kmalloc.h
+++ 

[PATCH 01/25] MIPS: remove a dead ifdef from mach-ath25/dma-coherence.h

2018-05-25 Thread Christoph Hellwig
ath25 is alwas non-coherent, so keeping these ifdefs doesn't make any sense.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/include/asm/mach-ath25/dma-coherence.h | 5 -
 1 file changed, 5 deletions(-)

diff --git a/arch/mips/include/asm/mach-ath25/dma-coherence.h 
b/arch/mips/include/asm/mach-ath25/dma-coherence.h
index d5defdde32db..124755d4f079 100644
--- a/arch/mips/include/asm/mach-ath25/dma-coherence.h
+++ b/arch/mips/include/asm/mach-ath25/dma-coherence.h
@@ -61,12 +61,7 @@ static inline int plat_dma_supported(struct device *dev, u64 
mask)
 
 static inline int plat_device_is_coherent(struct device *dev)
 {
-#ifdef CONFIG_DMA_COHERENT
-   return 1;
-#endif
-#ifdef CONFIG_DMA_NONCOHERENT
return 0;
-#endif
 }
 
 static inline void plat_post_dma_flush(struct device *dev)
-- 
2.17.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[RFC] switch mips to use the generic dma map ops

2018-05-25 Thread Christoph Hellwig
Hi all,

this huge series does a deep cleaning of the mips dma mapping code and
moves most architectures over to use the generic dma_direct_ops or
dma_noncoherent_ops.  The Jazz architectures grows a new dma_map_ops
tailered to its bare bones iommu implementation, and the swiotlb code
use by Loongson-3 and Octeon is merged into a single implementation,
pending further unification with the generic swiotlb_ops in another
step.

Note that all this has been compile tested only, and I've probably
missed even that for some platforms..

A git tree is available here:

git://git.infradead.org/users/hch/misc.git mips-direct-ops

Gitweb:


http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/mips-direct-ops
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


RE: [PATCH v6 0/7] vfio/type1: Add support for valid iova list management

2018-05-25 Thread Shameerali Kolothum Thodi
Hi Alex,

> -Original Message-
> From: Alex Williamson [mailto:alex.william...@redhat.com]
> Sent: Thursday, May 24, 2018 7:21 PM
> To: Shameerali Kolothum Thodi 
> Cc: eric.au...@redhat.com; pmo...@linux.vnet.ibm.com;
> k...@vger.kernel.org; linux-ker...@vger.kernel.org; iommu@lists.linux-
> foundation.org; Linuxarm ; John Garry
> ; xuwei (O) ; Joerg Roedel
> 
> Subject: Re: [PATCH v6 0/7] vfio/type1: Add support for valid iova list
> management
> 
> [Cc +Joerg: AMD-Vi observation towards the end]
> 
> On Wed, 18 Apr 2018 12:40:38 +0100
> Shameer Kolothum  wrote:
> 
> > This series introduces an iova list associated with a vfio
> > iommu. The list is kept updated taking care of iommu apertures,
> > and reserved regions. Also this series adds checks for any conflict
> > with existing dma mappings whenever a new device group is attached to
> > the domain.
> >
> > User-space can retrieve valid iova ranges using VFIO_IOMMU_GET_INFO
> > ioctl capability chains. Any dma map request outside the valid iova
> > range will be rejected.
> 
> Hi Shameer,
> 
> I ran into two minor issues in testing this series, both related to
> mdev usage of type1.  First, in patch 5/7 when we try to validate a dma
> map request:

I must admit I haven't looked into the mdev use case at all and my impression
was that it will be same as others. Thanks for doing these tests.

> > +static bool vfio_iommu_iova_dma_valid(struct vfio_iommu *iommu,
> > +   dma_addr_t start, dma_addr_t end)
> > +{
> > +   struct list_head *iova = >iova_list;
> > +   struct vfio_iova *node;
> > +
> > +   list_for_each_entry(node, iova, list) {
> > +   if ((start >= node->start) && (end <= node->end))
> > +   return true;
> > +   }
> > +
> > +   return false;
> > +}
> 
> A container with only an mdev device will have an empty list because it
> has not backing iommu to set ranges or reserved regions, so any dma map
> will fail.  I think this is resolved as follows:
> 
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -1100,7 +1100,7 @@ static bool vfio_iommu_iova_dma_valid(struct
> vfio_iommu *iommu,
> return true;
> }
> 
> -   return false;
> +   return list_empty(>iova_list);
>  }

Ok.

> ie. return false only if there was anything to test against.
> 
> The second issue is similar, patch 6/7 adds to VFIO_IOMMU_GET_INFO:
> 
> + ret = vfio_iommu_iova_build_caps(iommu, );
> + if (ret)
> + return ret;
> 
> And build_caps has:
> 
> + list_for_each_entry(iova, >iova_list, list)
> + iovas++;
> +
> + if (!iovas) {
> + ret = -EINVAL;
> 
> Therefore if the iova list is empty, as for mdevs, the use can no
> longer even call VFIO_IOMMU_GET_INFO on the container, which is a
> regression.  Again, I think the fix is simple:
> 
> @@ -2090,7 +2090,7 @@ static int vfio_iommu_iova_build_caps(struct
> vfio_iommu *iommu,
> iovas++;
> 
> if (!iovas) {
> -   ret = -EINVAL;
> +   ret = 0;
> goto out_unlock;
> }
> 
> ie. build_caps needs to handle lack of an iova_list as a non-error.

Ok.

> Also, I wrote a small unit test to validate the iova list for my
> systems[1].  With the above changes, my Intel test system gives expected
> results:
> 
> # ./vfio-type1-iova-list /sys/bus/mdev/devices/c08db5ed-05d3-4b39-b150-
> 438a18bc698f /sys/bus/pci/devices/:00:1b.0
>  Adding device: c08db5ed-05d3-4b39-b150-438a18bc698f 
> Initial info struct size: 0x18
> No caps
>  Adding device: :00:1b.0 
> Initial info struct size: 0x18
> Requested info struct size: 0x48
> New info struct size: 0x48
> argsz: 0x48, flags: 0x3, cap_offset: 0x18
>   00: 4800  0300  00f0   
>   10: 1800    0100 0100  
>   20: 0200       
>   30:  dffe    f0fe  
>   40:    ff01
> [cap id: 1, version: 1, next: 0x0]
> Found type1 iova range version: 1
>   00:  - fedf
>   01: fef0 - 01ff
> 
> Adding an mdev device to the container results in no iova list, adding
> the physical device updates to the expected set with the MSI range
> excluded.
> 
> I was a little surprised by an AMD system:
> 
> # ./vfio-type1-iova-list /sys/bus/pci/devices/:01:00.0
>  Adding device: :01:00.0 
> Initial info struct size: 0x18
> Requested info struct size: 0x58
> New info struct size: 0x58
> argsz: 0x58, flags: 0x3, cap_offset: 0x18
>   00: 5800  0300  00f0  7fff 
>   10: 1800    0100 0100  
>   20: 0300       
>   30:  

Re: [PATCH] swiotlb: Fix inversed DMA_ATTR_NO_WARN test

2018-05-25 Thread Michel Dänzer
On 2018-05-25 10:41 AM, Christoph Hellwig wrote:
> On Tue, May 22, 2018 at 03:13:58PM +0200, Christian König wrote:
>> Am 02.05.2018 um 18:59 schrieb Michel Dänzer:
>>> On 2018-05-02 06:21 PM, Christoph Hellwig wrote:
 On Wed, May 02, 2018 at 04:31:09PM +0200, Michel Dänzer wrote:
>> No.  __GFP_NOWARN (and gfp_t flags in general) are the wrong interface
>> for dma allocations and just cause problems.  I actually plan to
>> get rid of the gfp_t argument in dma_alloc_attrs sooner, and only
>> allow either GFP_KERNEL or GFP_DMA passed in dma_alloc_coherent.
> How about GFP_TRANSHUGE_LIGHT? TTM uses that to opportunistically
> allocate huge pages (GFP_TRANSHUGE can result in unacceptably long
> delays with memory pressure).
 Well, that is exactly what I don't want drivers to do - same for
 __GFP_COMP in some drm code.  This very much assumes the page allocator
 is used to back dma allocations, which very often it actually isn't, and
 any use of magic gfp flags creates a tight coupling of consumers with a
 specific implementation.

 In general I can't think of a good reason not to actually use
 GFP_TRANSHUGE_LIGHT by default in the dma allocator unless
 DMA_ATTR_ALLOC_SINGLE_PAGES is set.  Can you prepare a patch for that?
>>> I'm afraid I'll have to leave that to somebody else.
>>
>> Coming back to this topic once more, sorry for the delay but busy as usual 
>> :)
>>
>> What exactly do you mean with "dma allocator" here? The TTM allocator using 
>> the dma_alloc_coherent calls? Or the swiotlb implementation of the calls?
> 
> dma allocatr in this case: backends for dma_alloc_coherent/
> dma_alloc_attrs.  Most importantly dma_direct_alloc.
> 
> But while we're at it I can't actually see any GFP_TRANSHUGE_LIGHT
> usage in TTM, just plain old GFP_TRANSHUGE.

See
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=da291320baec914f0bb4e65a9dccb86bd6c728f2
.


-- 
Earthling Michel Dänzer   |   http://www.amd.com
Libre software enthusiast | Mesa and X developer
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: [PATCH v2 03/40] iommu/sva: Manage process address spaces

2018-05-25 Thread Jonathan Cameron
+CC Kenneth Lee

On Fri, 25 May 2018 09:33:11 +0300
Ilias Apalodimas  wrote:

> On Thu, May 24, 2018 at 04:04:39PM +0100, Jean-Philippe Brucker wrote:
> > On 24/05/18 12:50, Ilias Apalodimas wrote:  
> > >> Interesting, I hadn't thought about this use-case before. At first I
> > >> thought you were talking about mdev devices assigned to VMs, but I think
> > >> you're referring to mdevs assigned to userspace drivers instead? Out of
> > >> curiosity, is it only theoretical or does someone actually need this?  
> > > 
> > > There has been some non upstreamed efforts to have mdev and produce 
> > > userspace
> > > drivers. Huawei is using it on what they call "wrapdrive" for crypto 
> > > devices and
> > > we did a proof of concept for ethernet interfaces. At the time we choose 
> > > not to
> > > involve the IOMMU for the reason you mentioned, but having it there would 
> > > be
> > > good.  
> > 
> > I'm guessing there were good reasons to do it that way but I wonder, is
> > it not simpler to just have the kernel driver create a /dev/foo, with a
> > standard ioctl/mmap/poll interface? Here VFIO adds a layer of
> > indirection, and since the mediating driver has to implement these
> > operations already, what is gained?  
> The best reason i can come up with is "common code". You already have one API
> doing that for you so we replicate it in a /dev file?
> The mdev approach still needs extentions to support what we tried to do (i.e
> mdev bus might need yo have access on iommu_ops), but as far as i undestand 
> it's
> a possible case.
> > 
> > Thanks,
> > Jean  


___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] swiotlb: Fix inversed DMA_ATTR_NO_WARN test

2018-05-25 Thread Christoph Hellwig
On Tue, May 22, 2018 at 03:13:58PM +0200, Christian König wrote:
> Am 02.05.2018 um 18:59 schrieb Michel Dänzer:
>> On 2018-05-02 06:21 PM, Christoph Hellwig wrote:
>>> On Wed, May 02, 2018 at 04:31:09PM +0200, Michel Dänzer wrote:
> No.  __GFP_NOWARN (and gfp_t flags in general) are the wrong interface
> for dma allocations and just cause problems.  I actually plan to
> get rid of the gfp_t argument in dma_alloc_attrs sooner, and only
> allow either GFP_KERNEL or GFP_DMA passed in dma_alloc_coherent.
 How about GFP_TRANSHUGE_LIGHT? TTM uses that to opportunistically
 allocate huge pages (GFP_TRANSHUGE can result in unacceptably long
 delays with memory pressure).
>>> Well, that is exactly what I don't want drivers to do - same for
>>> __GFP_COMP in some drm code.  This very much assumes the page allocator
>>> is used to back dma allocations, which very often it actually isn't, and
>>> any use of magic gfp flags creates a tight coupling of consumers with a
>>> specific implementation.
>>>
>>> In general I can't think of a good reason not to actually use
>>> GFP_TRANSHUGE_LIGHT by default in the dma allocator unless
>>> DMA_ATTR_ALLOC_SINGLE_PAGES is set.  Can you prepare a patch for that?
>> I'm afraid I'll have to leave that to somebody else.
>
> Coming back to this topic once more, sorry for the delay but busy as usual 
> :)
>
> What exactly do you mean with "dma allocator" here? The TTM allocator using 
> the dma_alloc_coherent calls? Or the swiotlb implementation of the calls?

dma allocatr in this case: backends for dma_alloc_coherent/
dma_alloc_attrs.  Most importantly dma_direct_alloc.

But while we're at it I can't actually see any GFP_TRANSHUGE_LIGHT
usage in TTM, just plain old GFP_TRANSHUGE.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 03/40] iommu/sva: Manage process address spaces

2018-05-25 Thread Ilias Apalodimas
On Thu, May 24, 2018 at 04:04:39PM +0100, Jean-Philippe Brucker wrote:
> On 24/05/18 12:50, Ilias Apalodimas wrote:
> >> Interesting, I hadn't thought about this use-case before. At first I
> >> thought you were talking about mdev devices assigned to VMs, but I think
> >> you're referring to mdevs assigned to userspace drivers instead? Out of
> >> curiosity, is it only theoretical or does someone actually need this?
> > 
> > There has been some non upstreamed efforts to have mdev and produce 
> > userspace
> > drivers. Huawei is using it on what they call "wrapdrive" for crypto 
> > devices and
> > we did a proof of concept for ethernet interfaces. At the time we choose 
> > not to
> > involve the IOMMU for the reason you mentioned, but having it there would be
> > good.
> 
> I'm guessing there were good reasons to do it that way but I wonder, is
> it not simpler to just have the kernel driver create a /dev/foo, with a
> standard ioctl/mmap/poll interface? Here VFIO adds a layer of
> indirection, and since the mediating driver has to implement these
> operations already, what is gained?
The best reason i can come up with is "common code". You already have one API
doing that for you so we replicate it in a /dev file?
The mdev approach still needs extentions to support what we tried to do (i.e
mdev bus might need yo have access on iommu_ops), but as far as i undestand it's
a possible case.
> 
> Thanks,
> Jean
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu