Re: [PATCH v5 01/23] iommu: introduce bind_pasid_table API function

2018-08-27 Thread Jacob Pan
On Fri, 24 Aug 2018 17:00:51 +0200
Auger Eric  wrote:

> Hi Jacob,
> 
> On 05/11/2018 10:53 PM, Jacob Pan wrote:
> > Virtual IOMMU was proposed to support Shared Virtual Memory (SVM)
> > use in the guest:
> > https://lists.gnu.org/archive/html/qemu-devel/2016-11/msg05311.html
> > 
> > As part of the proposed architecture, when an SVM capable PCI
> > device is assigned to a guest, nested mode is turned on. Guest owns
> > the first level page tables (request with PASID) which performs
> > GVA->GPA translation. Second level page tables are owned by the
> > host for GPA->HPA translation for both request with and without
> > PASID.
> > 
> > A new IOMMU driver interface is therefore needed to perform tasks as
> > follows:
> > * Enable nested translation and appropriate translation type
> > * Assign guest PASID table pointer (in GPA) and size to host IOMMU
> > 
> > This patch introduces new API functions to perform bind/unbind
> > guest PASID tables. Based on common data, model specific IOMMU
> > drivers can be extended to perform the specific steps for binding
> > pasid table of assigned devices.
> > 
> > Signed-off-by: Jean-Philippe Brucker 
> > Signed-off-by: Liu, Yi L 
> > Signed-off-by: Ashok Raj 
> > Signed-off-by: Jacob Pan 
> > ---
> >  drivers/iommu/iommu.c  | 19 +++
> >  include/linux/iommu.h  | 24 
> >  include/uapi/linux/iommu.h | 33 +
> >  3 files changed, 76 insertions(+)
> >  create mode 100644 include/uapi/linux/iommu.h
> > 
> > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > index d2aa2320..3a69620 100644
> > --- a/drivers/iommu/iommu.c
> > +++ b/drivers/iommu/iommu.c
> > @@ -1325,6 +1325,25 @@ int iommu_attach_device(struct iommu_domain
> > *domain, struct device *dev) }
> >  EXPORT_SYMBOL_GPL(iommu_attach_device);
> >  
> > +int iommu_bind_pasid_table(struct iommu_domain *domain, struct
> > device *dev,
> > +   struct pasid_table_config *pasidt_binfo)  
> As Jean-Philippe, I must confessed i am very confused by having both
> the iommu_domain and dev passed as argument.
> 
> I know this was discussed when the RFC was submitted and maybe I
> missed the main justification behind that choice. I understand that
> at the HW level we want to change the context entry or ARM CD in my
> case for a specific device. But on other hand, at the logical level,
> I understand the iommu_domain is representing a set of translation
> config & page tables shared by all the devices within the domain
> (hope this is fundamentally correct ?!). So to me we can't change the
> device translation setup without changing the whole iommu_device setup
> otherwise this would mean this device has a translation configuration
> that is not consistent anymore with the other devices in the same
> domain. Is that correct? So can't we only keep the iommu_domain arg?
> 
I agree with you on your understanding of HW and logical level. I think
there is a new twist to the definition of domain introduced by having
PASID and vSVA. Up until now, domain only means 2nd level mapping. In
that sense, bind guest PASID table does not alter domain. For VT-d 2.5
spec. implementation of the bind_pasid_table(), we needed some per
device data, also flags such as indication for IO page fault handling.

Anyway, for the new VT-d 3.0 spec. we no longer need this API. In
stead, I will introduce bind_guest_pasid() API, where per device PASID
table is allocated by the host.

> > +{
> > +   if (unlikely(!domain->ops->bind_pasid_table))
> > +   return -ENODEV;
> > +
> > +   return domain->ops->bind_pasid_table(domain, dev,
> > pasidt_binfo); +}
> > +EXPORT_SYMBOL_GPL(iommu_bind_pasid_table);
> > +
> > +void iommu_unbind_pasid_table(struct iommu_domain *domain, struct
> > device *dev) +{
> > +   if (unlikely(!domain->ops->unbind_pasid_table))
> > +   return;
> > +
> > +   domain->ops->unbind_pasid_table(domain, dev);
> > +}
> > +EXPORT_SYMBOL_GPL(iommu_unbind_pasid_table);
> > +
> >  static void __iommu_detach_device(struct iommu_domain *domain,
> >   struct device *dev)
> >  {
> > diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> > index 19938ee..5199ca4 100644
> > --- a/include/linux/iommu.h
> > +++ b/include/linux/iommu.h
> > @@ -25,6 +25,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  
> >  #define IOMMU_READ (1 << 0)
> >  #define IOMMU_WRITE(1 << 1)
> > @@ -187,6 +188,8 @@ struct iommu_resv_region {
> >   * @domain_get_windows: Return the number of windows for a domain
> >   * @of_xlate: add OF master IDs to iommu grouping
> >   * @pgsize_bitmap: bitmap of all possible supported page sizes
> > + * @bind_pasid_table: bind pasid table pointer for guest SVM
> > + * @unbind_pasid_table: unbind pasid table pointer and restore
> > defaults */
> >  struct iommu_ops {
> > bool (*capable)(enum iommu_cap);
> > @@ -233,8 +236,14 @@ struct iommu_ops {
> > u32 

Re: new SBus related DMA warnings in 4.18+git

2018-08-27 Thread David Miller
From: Sam Ravnborg 
Date: Mon, 27 Aug 2018 21:15:18 +0200

> Why not fix the drivers rather than papering over the fact
> that they are missing the DMA mask?
> 
> We are in the lucky situation the Meelis can test any patches.

SBUS drivers never set the mask because they never needed to and could
use the default, since SBUS IOMMUs were quite universal in nature.

I think it's more error prone to add the mask setting to every single
SBUS driver than to just have the core setup the default properly.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: new SBus related DMA warnings in 4.18+git

2018-08-27 Thread Sam Ravnborg
Hi Christoph.

On Mon, Aug 27, 2018 at 05:47:16PM +0200, Christoph Hellwig wrote:
> On Sun, Aug 26, 2018 at 10:48:44AM +0300, Meelis Roos wrote:
> > Tried yesterdays git 4.18.0-12789-gaa5b105 on a Sun Ultra 1 with SBus 
> > and several SBus connected devicess give DMA mapping related warnings:
> 
> This should have been around since the warning was added.
> 
> The patch below should fix it:
> 
> ---
> >From 6294e0e330851ee06e66ab85b348f1d92d375d7a Mon Sep 17 00:00:00 2001
> From: Christoph Hellwig 
> Date: Mon, 27 Aug 2018 17:23:24 +0200
> Subject: driver core: initialize a default DMA mask for platform device
> 
> We still treat devices without a DMA mask as defaulting to 32-bits for
> both mask, but a few releases ago we've started warning about such
> cases, as they require special cases to work around this sloppyness.
> Add a dma_mask field to struct platform_object so that we can initialize
> the dma_mask pointer in struct device and initialize both masks to
> 32-bits by default.  Architectures can still override this in
> arch_setup_pdev_archdata if needed.
> 
> Note that the code looks a little odd with the various conditionals
> because we have to support platform_device structures that are
> statically allocated.
I know the patch did not work out as intended - saw another thread.
But this looks like the patch just paper over the fact that
the drivers are missing to set the DMA mask.

Why not fix the drivers rather than papering over the fact
that they are missing the DMA mask?

We are in the lucky situation the Meelis can test any patches.

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


Re: new SBus related DMA warnings in 4.18+git

2018-08-27 Thread Meelis Roos
> On Sun, Aug 26, 2018 at 10:48:44AM +0300, Meelis Roos wrote:
> > Tried yesterdays git 4.18.0-12789-gaa5b105 on a Sun Ultra 1 with SBus 
> > and several SBus connected devicess give DMA mapping related warnings:
> 
> This should have been around since the warning was added.
> 
> The patch below should fix it:
> 
> ---
> >From 6294e0e330851ee06e66ab85b348f1d92d375d7a Mon Sep 17 00:00:00 2001
> From: Christoph Hellwig 
> Date: Mon, 27 Aug 2018 17:23:24 +0200
> Subject: driver core: initialize a default DMA mask for platform device

No, it does not fix it. Dmesg from another SBus machine that conmpiled 
it faster (Sun Ultra 2):

[0.000112] PROMLIB: Sun IEEE Boot Prom 'OBP 3.25.0 1999/12/03 11:35'
[0.000131] PROMLIB: Root node compatible: 
[0.000250] Linux version 4.18.0-12952-g2923b27-dirty (mroos@u2) (gcc 
version 4.9.3 (Debian 4.9.3-2)) #239 SMP Mon Aug 27 21:42:14 EEST 2018
[0.000448] debug: ignoring loglevel setting.
[0.329860] bootconsole [earlyprom0] enabled
[0.380881] ARCH: SUN4U
[0.410167] Ethernet address: 08:00:20:89:2a:a0
[0.464243] MM: PAGE_OFFSET is 0xf800 (max_phys_bits == 40)
[0.543372] MM: VMALLOC [0x0001 --> 0x0600]
[0.618366] MM: VMEMMAP [0x0600 --> 0x0c00]
[0.697932] Kernel: Using 2 locked TLB entries for main kernel image.
[0.774140] Remapping the kernel... 
[0.807146] done.
[1.154827] OF stdout device is: /sbus@1f,0/zs@f,110:a
[1.219566] PROM: Built device tree with 63364 bytes of memory.
[1.290510] Top of RAM: 0x6ff2c000, Total RAM: 0x37f1a000
[1.354970] Memory hole size: 896MB
[1.406349] Allocated 16384 bytes for kernel page tables.
[1.470133] Zone ranges:
[1.500269]   Normal   [mem 0x-0x6ff2bfff]
[1.574219] Movable zone start for each node
[1.625258] Early memory node ranges
[1.667967]   node   0: [mem 0x-0x0fff]
[1.742961]   node   0: [mem 0x2000-0x27ff]
[1.817956]   node   0: [mem 0x4000-0x4fff]
[1.892948]   node   0: [mem 0x6000-0x6fefdfff]
[1.967942]   node   0: [mem 0x6ff0-0x6ff05fff]
[2.042936]   node   0: [mem 0x6ff16000-0x6ff2bfff]
[2.118044] Initmem setup node 0 [mem 0x-0x6ff2bfff]
[2.202302] On node 0 totalpages: 114573
[2.249169]   Normal zone: 896 pages used for memmap
[2.308537]   Normal zone: 0 pages reserved
[2.358535]   Normal zone: 114573 pages, LIFO batch:31
[2.495241] Booting Linux...
[2.528734] CPU CAPS: [flush,stbar,swap,muldiv,v9,mul32,div32,v8plus]
[2.605799] CPU CAPS: [vis]
[2.668258] percpu: Embedded 10 pages/cpu @(ptrval) s44928 r8192 
d28800 u2097152
[2.766410] pcpu-alloc: s44928 r8192 d28800 u2097152 alloc=1*4194304
[2.841510] pcpu-alloc: [0] 0 1 
[2.885668] Built 1 zonelists, mobility grouping on.  Total pages: 113677
[2.965990] Kernel command line: root=/dev/sda2 ro ignore_loglevel
[3.046466] Dentry cache hash table entries: 131072 (order: 7, 1048576 bytes)
[3.134227] Inode-cache hash table entries: 65536 (order: 6, 524288 bytes)
[3.215649] Sorting __ex_table...
[3.310465] Memory: 892040K/916584K available (4329K kernel code, 255K 
rwdata, 816K rodata, 232K init, 268K bss, 24544K reserved, 0K cma-reserved)
[3.467295] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
[3.545872] rcu: Hierarchical RCU implementation.
[3.601352] NR_IRQS: 2048, nr_irqs: 2048, preallocated irqs: 1
[3.671504] clocksource: tick: mask: 0x max_cycles: 
0x44439c2a93, max_idle_ns: 440795210626 ns
[3.790815] clocksource: mult[360e5ba] shift[24]
[3.846017] clockevent: mult[4bc5ed4a] shift[32]
[3.901587] Console: colour dummy device 80x25
[3.954414] console [tty0] enabled
[3.994980] bootconsole [earlyprom0] disabled
[4.197213] Calibrating delay using timer specific routine.. 593.26 BogoMIPS 
(lpj=2966300)
[4.197267] pid_max: default: 32768 minimum: 301
[4.197757] Mount-cache hash table entries: 2048 (order: 1, 16384 bytes)
[4.197861] Mountpoint-cache hash table entries: 2048 (order: 1, 16384 bytes)
[4.201878] rcu: Hierarchical SRCU implementation.
[4.203657] smp: Bringing up secondary CPUs ...
[4.237851] CPU 1: synchronized TICK with master CPU (last diff -17 cycles, 
maxerr 539 cycles)
[4.238252] smp: Brought up 1 node, 2 CPUs
[4.239996] devtmpfs: initialized
[4.245228] random: get_random_u32 called from 
bucket_table_alloc.isra.18+0x7c/0x1c0 with crng_init=0
[4.245850] clocksource: jiffies: mask: 0x max_cycles: 0x, 
max_idle_ns: 1911260446275 ns
[4.245913] futex hash table entries: 512 (order: 2, 32768 bytes)
[4.247101] NET: Registered protocol family 16
[4.261051] SYSIO: UPA portID , at 01fe
[

Re: swiotlb cleanup (resend)

2018-08-27 Thread Konrad Rzeszutek Wilk
On Mon, Aug 27, 2018 at 08:33:08PM +0200, Christoph Hellwig wrote:
> On Mon, Aug 27, 2018 at 02:13:11PM -0400, Konrad Rzeszutek Wilk wrote:
> > On Wed, Jul 25, 2018 at 01:37:56PM +0200, Christoph Hellwig wrote:
> > > Hi Konrad,
> > > 
> > > below are a few swiotlb patches.  Mostly just cleanups, but the removal
> > > of the panic option is an actual change in (rarely used) functionality.
> > > 
> > > I'd be happy to pick them up through the dma-mapping tree if you are
> > > fine with that.
> > 
> > Hey,
> > 
> > I put them in my 'devel/for-linus-4.19' as I would like to make
> > sure that they work just fine with Xen-SWIOTLB and some baremetal
> > machines.
> 
> I actually have a new version of these combined with merging
> arm64 support into the main swiotlb ops.  Please hold off a bit for
> now.


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


Re: swiotlb cleanup (resend)

2018-08-27 Thread Christoph Hellwig
On Mon, Aug 27, 2018 at 02:13:11PM -0400, Konrad Rzeszutek Wilk wrote:
> On Wed, Jul 25, 2018 at 01:37:56PM +0200, Christoph Hellwig wrote:
> > Hi Konrad,
> > 
> > below are a few swiotlb patches.  Mostly just cleanups, but the removal
> > of the panic option is an actual change in (rarely used) functionality.
> > 
> > I'd be happy to pick them up through the dma-mapping tree if you are
> > fine with that.
> 
> Hey,
> 
> I put them in my 'devel/for-linus-4.19' as I would like to make
> sure that they work just fine with Xen-SWIOTLB and some baremetal
> machines.

I actually have a new version of these combined with merging
arm64 support into the main swiotlb ops.  Please hold off a bit for
now.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [RFC PATCH 11/11] powerpc/svm: Increase SWIOTLB buffer size

2018-08-27 Thread Konrad Rzeszutek Wilk
On Fri, Aug 24, 2018 at 01:25:35PM -0300, Thiago Jung Bauermann wrote:
> From: Anshuman Khandual 
> 
> SWIOTLB buffer default size (64MB) is not enough for large sequential write
> operations which eventually leads to kernel crash like here.
> 
> virtio-pci :00:05.0: swiotlb buffer is full (sz: 327680 bytes)
> virtio-pci :00:05.0: DMA: Out of SW-IOMMU space for 327680 bytes
> Kernel panic - not syncing: DMA: Random memory could be DMA read
> CPU: 12 PID: 3985 Comm: mkfs.ext4 Not tainted 4.18.0-rc4+ #285
> Call Trace:
> [c007d2a27020] [c0cfdffc] dump_stack+0xb0/0xf4 (unreliable)
> [c007d2a27060] [c0112a98] panic+0x140/0x328
> [c007d2a270f0] [c01b4f88] swiotlb_full+0x108/0x130
> [c007d2a27180] [c01b5f6c] swiotlb_map_page+0x25c/0x2c0
> [c007d2a271e0] [c07bfaf8] vring_map_one_sg.isra.0+0x58/0x70
> [c007d2a27200] [c07c08dc] virtqueue_add_sgs+0x1bc/0x690
> [c007d2a272f0] [d42a1280] virtio_queue_rq+0x358/0x4a0 [virtio_blk]
> [c007d2a273d0] [c06b5d68] blk_mq_dispatch_rq_list+0x1f8/0x6d0
> ..
> 
> Increase the SWIOTLB size to 1GB on Ultravisor based secure guests.

Gosh, that is huge.

What about making the SWIOTLB be more dynamic? That is expand it's size
dynamically if it can?

> 
> Signed-off-by: Anshuman Khandual 
> Signed-off-by: Thiago Jung Bauermann 
> ---
>  arch/powerpc/Kconfig | 5 +
>  kernel/dma/swiotlb.c | 5 +
>  2 files changed, 10 insertions(+)
> 
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 1466d1234723..fee7194ce9e4 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -457,6 +457,11 @@ config PPC_SVM
>  
>If unsure, say "N".
>  
> +config SWIOTLB_DEFAULT_SIZE
> +   int "Size of Software I/O TLB buffer (in MiB)"
> +   default "1024"
> +   depends on PPC_SVM
> +
>  config PPC_TRANSACTIONAL_MEM
> bool "Transactional Memory support for POWERPC"
> depends on PPC_BOOK3S_64
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index 04b68d9dffac..32dc67422d8a 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -146,8 +146,13 @@ void swiotlb_set_max_segment(unsigned int val)
>   max_segment = rounddown(val, PAGE_SIZE);
>  }
>  
> +#ifdef CONFIG_SWIOTLB_DEFAULT_SIZE
> +#define IO_TLB_DEFAULT_SIZE ((unsigned long) CONFIG_SWIOTLB_DEFAULT_SIZE << 
> 20)
> +#else
>  /* default to 64MB */
>  #define IO_TLB_DEFAULT_SIZE (64UL<<20)
> +#endif
> +
>  unsigned long swiotlb_size_or_default(void)
>  {
>   unsigned long size;
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: swiotlb cleanup (resend)

2018-08-27 Thread Konrad Rzeszutek Wilk
On Wed, Jul 25, 2018 at 01:37:56PM +0200, Christoph Hellwig wrote:
> Hi Konrad,
> 
> below are a few swiotlb patches.  Mostly just cleanups, but the removal
> of the panic option is an actual change in (rarely used) functionality.
> 
> I'd be happy to pick them up through the dma-mapping tree if you are
> fine with that.

Hey,

I put them in my 'devel/for-linus-4.19' as I would like to make
sure that they work just fine with Xen-SWIOTLB and some baremetal
machines.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 05/20] swiotlb: allow the architecture to provide a get_required_mask hook

2018-08-27 Thread Konrad Rzeszutek Wilk
On Mon, Jul 30, 2018 at 06:38:09PM +0200, Christoph Hellwig wrote:
> For now this allows consolidating the powerpc code.  In the long run
> we should grow a generic implementation of dma_get_required_mask that
> returns the dma mask required to avoid bounce buffering.
> 
> Signed-off-by: Christoph Hellwig 
Reviewed-by: Konrad Rzeszutek Wilk 

Thank you!
> ---
>  kernel/dma/swiotlb.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index 904541055792..1bb420244753 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -1084,5 +1084,9 @@ const struct dma_map_ops swiotlb_dma_ops = {
>   .map_page   = swiotlb_map_page,
>   .unmap_page = swiotlb_unmap_page,
>   .dma_supported  = dma_direct_supported,
> +#ifdef swiotlb_get_required_mask
> + .get_required_mask  = swiotlb_get_required_mask,
> +#endif
> +
>  };
>  EXPORT_SYMBOL(swiotlb_dma_ops);
> -- 
> 2.18.0
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: new SBus related DMA warnings in 4.18+git

2018-08-27 Thread Christoph Hellwig
On Sun, Aug 26, 2018 at 10:48:44AM +0300, Meelis Roos wrote:
> Tried yesterdays git 4.18.0-12789-gaa5b105 on a Sun Ultra 1 with SBus 
> and several SBus connected devicess give DMA mapping related warnings:

This should have been around since the warning was added.

The patch below should fix it:

---
>From 6294e0e330851ee06e66ab85b348f1d92d375d7a Mon Sep 17 00:00:00 2001
From: Christoph Hellwig 
Date: Mon, 27 Aug 2018 17:23:24 +0200
Subject: driver core: initialize a default DMA mask for platform device

We still treat devices without a DMA mask as defaulting to 32-bits for
both mask, but a few releases ago we've started warning about such
cases, as they require special cases to work around this sloppyness.
Add a dma_mask field to struct platform_object so that we can initialize
the dma_mask pointer in struct device and initialize both masks to
32-bits by default.  Architectures can still override this in
arch_setup_pdev_archdata if needed.

Note that the code looks a little odd with the various conditionals
because we have to support platform_device structures that are
statically allocated.

Signed-off-by: Christoph Hellwig 
---
 drivers/base/platform.c | 15 +--
 include/linux/platform_device.h |  1 +
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index dff82a3c2caa..baf4b06cf2d9 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -225,6 +225,17 @@ struct platform_object {
char name[];
 };
 
+static void setup_pdev_archdata(struct platform_device *pdev)
+{
+   if (!pdev->dev.coherent_dma_mask)
+   pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+   if (!pdev->dma_mask)
+   pdev->dma_mask = DMA_BIT_MASK(32);
+   if (!pdev->dev.dma_mask)
+   pdev->dev.dma_mask = >dma_mask;
+   arch_setup_pdev_archdata(pdev);
+};
+
 /**
  * platform_device_put - destroy a platform device
  * @pdev: platform device to free
@@ -271,7 +282,7 @@ struct platform_device *platform_device_alloc(const char 
*name, int id)
pa->pdev.id = id;
device_initialize(>pdev.dev);
pa->pdev.dev.release = platform_device_release;
-   arch_setup_pdev_archdata(>pdev);
+   setup_pdev_archdata(>pdev);
}
 
return pa ? >pdev : NULL;
@@ -472,7 +483,7 @@ EXPORT_SYMBOL_GPL(platform_device_del);
 int platform_device_register(struct platform_device *pdev)
 {
device_initialize(>dev);
-   arch_setup_pdev_archdata(pdev);
+   setup_pdev_archdata(pdev);
return platform_device_add(pdev);
 }
 EXPORT_SYMBOL_GPL(platform_device_register);
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 1a9f38f27f65..d84ec1de6022 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -25,6 +25,7 @@ struct platform_device {
int id;
boolid_auto;
struct device   dev;
+   dma_addr_t  dma_mask;
u32 num_resources;
struct resource *resource;
 
-- 
2.18.0

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


[PATCH 5/5] dma-mapping: support non-coherent devices in dma_common_get_sgtable

2018-08-27 Thread Christoph Hellwig
We can use the arch_dma_coherent_to_pfn hook to provide a ->get_sgtable
implementation.  Note that this isn't an endorsement of this interface
(which is a horrible bad idea), but it is required to move arm64 over
to the generic code without a loss of functionality.

Signed-off-by: Christoph Hellwig 
---
 drivers/xen/swiotlb-xen.c   |  2 +-
 include/linux/dma-mapping.h |  7 ---
 kernel/dma/mapping.c| 23 ---
 3 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 470757ea..28819a0e61d0 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -689,7 +689,7 @@ xen_swiotlb_get_sgtable(struct device *dev, struct sg_table 
*sgt,
   handle, size, attrs);
}
 #endif
-   return dma_common_get_sgtable(dev, sgt, cpu_addr, handle, size);
+   return dma_common_get_sgtable(dev, sgt, cpu_addr, handle, size, attrs);
 }
 
 static int xen_swiotlb_mapping_error(struct device *dev, dma_addr_t dma_addr)
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index ea39eafec873..5da76b8860f5 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -483,8 +483,8 @@ dma_mmap_attrs(struct device *dev, struct vm_area_struct 
*vma, void *cpu_addr,
 #define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0)
 
 int
-dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
-  void *cpu_addr, dma_addr_t dma_addr, size_t size);
+dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, void 
*cpu_addr,
+   dma_addr_t dma_addr, size_t size, unsigned long attrs);
 
 static inline int
 dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
@@ -496,7 +496,8 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table 
*sgt, void *cpu_addr,
if (ops->get_sgtable)
return ops->get_sgtable(dev, sgt, cpu_addr, dma_addr, size,
attrs);
-   return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size);
+   return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size,
+   attrs);
 }
 
 #define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0)
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index 9550c08ddab1..213322077374 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -202,17 +202,26 @@ EXPORT_SYMBOL(dmam_release_declared_memory);
  * Create scatter-list for the already allocated DMA buffer.
  */
 int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
-void *cpu_addr, dma_addr_t handle, size_t size)
+void *cpu_addr, dma_addr_t dma_addr, size_t size,
+unsigned long attrs)
 {
-   struct page *page = virt_to_page(cpu_addr);
+   struct page *page;
int ret;
 
-   ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
-   if (unlikely(ret))
-   return ret;
+   if (!dev_is_dma_coherent(dev)) {
+   if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN))
+   return -ENXIO;
 
-   sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0);
-   return 0;
+   page = pfn_to_page(arch_dma_coherent_to_pfn(dev, cpu_addr,
+   dma_addr));
+   } else {
+   page = virt_to_page(cpu_addr);
+   }
+
+   ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
+   if (!ret)
+   sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0);
+   return ret;
 }
 EXPORT_SYMBOL(dma_common_get_sgtable);
 
-- 
2.18.0

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


[PATCH 4/5] dma-mapping: consolidate the dma mmap implementations

2018-08-27 Thread Christoph Hellwig
The only functional differences (modulo a few missing fixes in the arch
code) is that architectures without coherent caches need a hook to
convert a virtual or dma address into a pfn, given that we don't have
the kernel linear mapping available for the otherwise easy virt_to_page
call.  As a side effect we can support mmap of the per-device coherent
area even on architectures not providing the callback, and we make
previous dangerous default methods dma_common_mmap actually save for
non-coherent architectures by rejecting it without the right helper.

In addition to that we need a hook so that some architectures can
override the protection bits when mmaping a dma coherent allocations.

Signed-off-by: Christoph Hellwig 
---
 arch/arc/Kconfig  |  2 +-
 arch/arc/mm/dma.c | 25 +++--
 arch/arm/mm/dma-mapping-nommu.c   |  2 +-
 arch/microblaze/Kconfig   |  2 +-
 arch/microblaze/include/asm/pgtable.h |  2 --
 arch/microblaze/kernel/dma.c  | 22 --
 arch/microblaze/mm/consistent.c   |  3 ++-
 arch/mips/Kconfig |  3 ++-
 arch/mips/jazz/jazzdma.c  |  1 -
 arch/mips/mm/dma-noncoherent.c| 32 ---
 drivers/xen/swiotlb-xen.c |  2 +-
 include/linux/dma-mapping.h   |  5 +++--
 include/linux/dma-noncoherent.h   | 10 +++--
 kernel/dma/Kconfig| 10 +
 kernel/dma/direct.c   | 11 -
 kernel/dma/mapping.c  | 32 ++-
 16 files changed, 58 insertions(+), 106 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 5f684324bff8..4d01b3a707a9 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -9,6 +9,7 @@
 config ARC
def_bool y
select ARC_TIMERS
+   select ARCH_HAS_DMA_COHERENT_TO_PFN
select ARCH_HAS_SYNC_DMA_FOR_CPU
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_HAS_SG_CHAIN
@@ -17,7 +18,6 @@ config ARC
select CLONE_BACKWARDS
select COMMON_CLK
select DMA_DIRECT_OPS
-   select DMA_NONCOHERENT_MMAP
select GENERIC_ATOMIC64 if !ISA_ARCV2 || !(ARC_HAS_LL64 && ARC_HAS_LLSC)
select GENERIC_CLOCKEVENTS
select GENERIC_FIND_FIRST_BIT
diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index ec47e6079f5d..374da476ae3b 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -104,29 +104,10 @@ void arch_dma_free(struct device *dev, size_t size, void 
*vaddr,
__free_pages(page, get_order(size));
 }
 
-int arch_dma_mmap(struct device *dev, struct vm_area_struct *vma,
-   void *cpu_addr, dma_addr_t dma_addr, size_t size,
-   unsigned long attrs)
+long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
+   dma_addr_t dma_addr)
 {
-   unsigned long user_count = vma_pages(vma);
-   unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
-   unsigned long pfn = __phys_to_pfn(dma_addr);
-   unsigned long off = vma->vm_pgoff;
-   int ret = -ENXIO;
-
-   vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
-   if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, ))
-   return ret;
-
-   if (off < count && user_count <= (count - off)) {
-   ret = remap_pfn_range(vma, vma->vm_start,
- pfn + off,
- user_count << PAGE_SHIFT,
- vma->vm_page_prot);
-   }
-
-   return ret;
+   return __phys_to_pfn(dma_addr);
 }
 
 /*
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
index a858562dc8e2..7cdfb8fde767 100644
--- a/arch/arm/mm/dma-mapping-nommu.c
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -91,7 +91,7 @@ static int arm_nommu_dma_mmap(struct device *dev, struct 
vm_area_struct *vma,
if (dma_mmap_from_global_coherent(vma, cpu_addr, size, ))
return ret;
 
-   return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
+   return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
 }
 
 
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 0f48ab6a8070..164a4857737a 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -1,6 +1,7 @@
 config MICROBLAZE
def_bool y
select ARCH_NO_SWAP
+   select ARCH_HAS_DMA_COHERENT_TO_PFN if MMU
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_SYNC_DMA_FOR_CPU
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
@@ -12,7 +13,6 @@ config MICROBLAZE
select CLONE_BACKWARDS3
select COMMON_CLK
select DMA_DIRECT_OPS
-   select DMA_NONCOHERENT_MMAP
select GENERIC_ATOMIC64
select GENERIC_CLOCKEVENTS
select GENERIC_CPU_DEVICES
diff --git a/arch/microblaze/include/asm/pgtable.h 
b/arch/microblaze/include/asm/pgtable.h
index 7b650ab14fa0..f64ebb9c9a41 

[PATCH 2/5] dma-mapping: move the dma_coherent flag to struct device

2018-08-27 Thread Christoph Hellwig
Various architectures support both coherent and non-coherent dma on
a per-device basis.  Move the dma_noncoherent flag from mips the
mips archdata field to struct device proper to prepare the
infrastructure for reuse on other architectures.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/Kconfig |  1 +
 arch/mips/include/asm/Kbuild  |  1 +
 arch/mips/include/asm/device.h| 19 
 arch/mips/include/asm/dma-coherence.h |  6 +
 arch/mips/include/asm/dma-mapping.h   |  2 +-
 arch/mips/mm/dma-noncoherent.c| 32 +--
 include/linux/device.h|  7 ++
 include/linux/dma-noncoherent.h   | 18 +++
 kernel/dma/Kconfig|  3 +++
 9 files changed, 43 insertions(+), 46 deletions(-)
 delete mode 100644 arch/mips/include/asm/device.h

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 0b25180028b8..54c52bd0d9d3 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1106,6 +1106,7 @@ config ARCH_SUPPORTS_UPROBES
bool
 
 config DMA_MAYBE_COHERENT
+   select ARCH_HAS_DMA_COHERENCE_H
select DMA_NONCOHERENT
bool
 
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild
index 58351e48421e..9a81e72119da 100644
--- a/arch/mips/include/asm/Kbuild
+++ b/arch/mips/include/asm/Kbuild
@@ -1,6 +1,7 @@
 # MIPS headers
 generic-(CONFIG_GENERIC_CSUM) += checksum.h
 generic-y += current.h
+generic-y += device.h
 generic-y += dma-contiguous.h
 generic-y += emergency-restart.h
 generic-y += export.h
diff --git a/arch/mips/include/asm/device.h b/arch/mips/include/asm/device.h
deleted file mode 100644
index 6aa796f1081a..
--- a/arch/mips/include/asm/device.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Arch specific extensions to struct device
- *
- * This file is released under the GPLv2
- */
-#ifndef _ASM_MIPS_DEVICE_H
-#define _ASM_MIPS_DEVICE_H
-
-struct dev_archdata {
-#ifdef CONFIG_DMA_PERDEV_COHERENT
-   /* Non-zero if DMA is coherent with CPU caches */
-   bool dma_coherent;
-#endif
-};
-
-struct pdev_archdata {
-};
-
-#endif /* _ASM_MIPS_DEVICE_H*/
diff --git a/arch/mips/include/asm/dma-coherence.h 
b/arch/mips/include/asm/dma-coherence.h
index 8eda48748ed5..876ba0d14cde 100644
--- a/arch/mips/include/asm/dma-coherence.h
+++ b/arch/mips/include/asm/dma-coherence.h
@@ -20,6 +20,12 @@ enum coherent_io_user_state {
 #elif defined(CONFIG_DMA_MAYBE_COHERENT)
 extern enum coherent_io_user_state coherentio;
 extern int hw_coherentio;
+
+static inline int dev_is_dma_coherent(struct device *dev)
+{
+   return coherentio == IO_COHERENCE_ENABLED ||
+   (coherentio == IO_COHERENCE_DEFAULT && hw_coherentio);
+}
 #else
 #ifdef CONFIG_DMA_NONCOHERENT
 #define coherentio IO_COHERENCE_DISABLED
diff --git a/arch/mips/include/asm/dma-mapping.h 
b/arch/mips/include/asm/dma-mapping.h
index e81c4e97ff1a..40d825c779de 100644
--- a/arch/mips/include/asm/dma-mapping.h
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -25,7 +25,7 @@ static inline void arch_setup_dma_ops(struct device *dev, u64 
dma_base,
  bool coherent)
 {
 #ifdef CONFIG_DMA_PERDEV_COHERENT
-   dev->archdata.dma_coherent = coherent;
+   dev->dma_coherent = coherent;
 #endif
 }
 
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index 2aca1236af36..d408ac51f56c 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -14,26 +14,6 @@
 #include 
 #include 
 
-#ifdef CONFIG_DMA_PERDEV_COHERENT
-static inline int dev_is_coherent(struct device *dev)
-{
-   return dev->archdata.dma_coherent;
-}
-#else
-static inline int dev_is_coherent(struct device *dev)
-{
-   switch (coherentio) {
-   default:
-   case IO_COHERENCE_DEFAULT:
-   return hw_coherentio;
-   case IO_COHERENCE_ENABLED:
-   return 1;
-   case IO_COHERENCE_DISABLED:
-   return 0;
-   }
-}
-#endif /* CONFIG_DMA_PERDEV_COHERENT */
-
 /*
  * The affected CPUs below in 'cpu_needs_post_dma_flush()' can speculatively
  * fill random cachelines with stale data at any time, requiring an extra
@@ -49,7 +29,7 @@ static inline int dev_is_coherent(struct device *dev)
  */
 static inline bool cpu_needs_post_dma_flush(struct device *dev)
 {
-   if (dev_is_coherent(dev))
+   if (dev_is_dma_coherent(dev))
return false;
 
switch (boot_cpu_type()) {
@@ -76,7 +56,7 @@ void *arch_dma_alloc(struct device *dev, size_t size,
if (!ret)
return NULL;
 
-   if (!dev_is_coherent(dev) && !(attrs & DMA_ATTR_NON_CONSISTENT)) {
+   if (!dev_is_dma_coherent(dev) && !(attrs & DMA_ATTR_NON_CONSISTENT)) {
dma_cache_wback_inv((unsigned long) ret, size);
ret = (void *)UNCAC_ADDR(ret);
}
@@ -87,7 +67,7 @@ void *arch_dma_alloc(struct device *dev, size_t size,
 void arch_dma_free(struct device *dev, 

[PATCH 1/5] MIPS: don't select DMA_MAYBE_COHERENT from DMA_PERDEV_COHERENT

2018-08-27 Thread Christoph Hellwig
While both option select a form of conditional dma coherence they don't
actually share any code in the implementation, so untangle them.

Signed-off-by: Christoph Hellwig 
---
 arch/mips/Kconfig|  2 +-
 arch/mips/kernel/setup.c |  2 +-
 arch/mips/mm/c-r4k.c | 17 -
 3 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 35511999156a..0b25180028b8 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -,7 +,7 @@ config DMA_MAYBE_COHERENT
 
 config DMA_PERDEV_COHERENT
bool
-   select DMA_MAYBE_COHERENT
+   select DMA_NONCOHERENT
 
 config DMA_NONCOHERENT
bool
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index c71d1eb7da59..6d840a44fa36 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -1067,7 +1067,7 @@ static int __init debugfs_mips(void)
 arch_initcall(debugfs_mips);
 #endif
 
-#if defined(CONFIG_DMA_MAYBE_COHERENT) && !defined(CONFIG_DMA_PERDEV_COHERENT)
+#ifdef CONFIG_DMA_MAYBE_COHERENT
 /* User defined DMA coherency from command line. */
 enum coherent_io_user_state coherentio = IO_COHERENCE_DEFAULT;
 EXPORT_SYMBOL_GPL(coherentio);
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index a9ef057c79fe..05bd77727fb9 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -1955,22 +1955,21 @@ void r4k_cache_init(void)
__flush_icache_user_range   = r4k_flush_icache_user_range;
__local_flush_icache_user_range = local_r4k_flush_icache_user_range;
 
-#if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT)
-# if defined(CONFIG_DMA_PERDEV_COHERENT)
-   if (0) {
-# else
-   if ((coherentio == IO_COHERENCE_ENABLED) ||
-   ((coherentio == IO_COHERENCE_DEFAULT) && hw_coherentio)) {
-# endif
+#ifdef CONFIG_DMA_NONCOHERENT
+#ifdef CONFIG_DMA_MAYBE_COHERENT
+   if (coherentio == IO_COHERENCE_ENABLED ||
+   (coherentio == IO_COHERENCE_DEFAULT && hw_coherentio)) {
_dma_cache_wback_inv= (void *)cache_noop;
_dma_cache_wback= (void *)cache_noop;
_dma_cache_inv  = (void *)cache_noop;
-   } else {
+   } else
+#endif /* CONFIG_DMA_MAYBE_COHERENT */
+   {
_dma_cache_wback_inv= r4k_dma_cache_wback_inv;
_dma_cache_wback= r4k_dma_cache_wback_inv;
_dma_cache_inv  = r4k_dma_cache_inv;
}
-#endif
+#endif /* CONFIG_DMA_NONCOHERENT */
 
build_clear_page();
build_copy_page();
-- 
2.18.0

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


[no subject]

2018-08-27 Thread Christoph Hellwig
Subject: [RFC] merge dma_direct_ops and dma_noncoherent_ops

While most architectures are either always or never dma coherent for a
given build, the arm, arm64, mips and soon arc architectures can have
different dma coherent settings on a per-device basis.  Additionally
some mips builds can decide at boot time if dma is coherent or not.

I've started to look into handling noncoherent dma in swiotlb, and
moving the dma-iommu ops into common code [1], and for that we need a
generic way to check if a given device is coherent or not.  Moving
this flag into struct device also simplifies the conditionally coherent
architecture implementations.

These patches are also available in a git tree given that they have
a few previous posted dependencies:

git://git.infradead.org/users/hch/misc.git dma-direct-noncoherent-merge

Gitweb:


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


Re: [PATCH v1] iommu/ipmmu-vmsa: Don't register as BUS IOMMU if machine doesn't have IPMMU-VMSA

2018-08-27 Thread Geert Uytterhoeven
Hi Laurent,

On Fri, Jul 27, 2018 at 11:09 AM Laurent Pinchart
 wrote:
> (CC'ing Geert and Magnus)
>
> Thank you for the patch.
>
> On Friday, 27 July 2018 00:19:16 EEST Dmitry Osipenko wrote:
> > This fixes kernel crashing on NVIDIA Tegra if kernel is compiled in
> > a multiplatform configuration and IPMMU-VMSA driver is enabled.
> >
> > Cc:  # v3.20+
> > Signed-off-by: Dmitry Osipenko 
> > ---
> >  drivers/iommu/ipmmu-vmsa.c | 7 +++
> >  1 file changed, 7 insertions(+)
> >
> > diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> > index 9e8495762bc8..78c50db9cd71 100644
> > --- a/drivers/iommu/ipmmu-vmsa.c
> > +++ b/drivers/iommu/ipmmu-vmsa.c
> > @@ -1109,12 +1109,19 @@ static struct platform_driver ipmmu_driver = {
> >
> >  static int __init ipmmu_init(void)
> >  {
> > + struct device_node *np;
> >   static bool setup_done;
> >   int ret;
> >
> >   if (setup_done)
> >   return 0;
> >
> > + np = of_find_matching_node(NULL, ipmmu_of_ids);
> > + if (!np)
> > + return 0;
> > +
> > + of_node_put(np);
> > +
>
> While functionally correct, this will add some unnecessary overhead when
> iommu_init() is called from IOMMU_OF_DECLARE(). I'm OK with this fix as a
> temporary measure to solve your problem, but we need to address the underlying
> issue properly.
>
> Geert, Magnus, the ipmmu-vmsa driver is a bit of a mess. We should brush it up
> and start using IOMMU_OF_DECLARE() on all platforms (and eventually get rid of
> bus_set_iommu() completely...). Do you have plans to address this ? If not,
> could you please add it to your to-do list ?

On the contrary: IOMMU_OF_DECLARE() has been removed.

>
> >   ret = platform_driver_register(_driver);
> >   if (ret < 0)
> >   return ret;

Gr{oetje,eeting}s,

Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 1/2] iommu/ipmmu-vmsa: Hook up R8A774A1 DT maching code

2018-08-27 Thread Simon Horman
On Thu, Aug 23, 2018 at 04:33:04PM +0100, Fabrizio Castro wrote:
> Add support for RZ/G2M (R8A774A1) SoC IPMMUs.
> 
> Signed-off-by: Fabrizio Castro 
> Reviewed-by: Biju Das 
> ---
> v1-v2:
> * taken out IOMMU_OF_DECLARE

Reviewed-by: Simon Horman 

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


Re: [PATCH v2 3/3] dts: arm64/sdm845: Add node for qcom,smmu-v2

2018-08-27 Thread Vivek Gautam



On 8/27/2018 2:26 PM, Vivek Gautam wrote:

Hi Rob, Robin,


On 8/15/2018 4:27 AM, Rob Herring wrote:

On Wed, Aug 15, 2018 at 01:09:43AM +0530, Vivek Gautam wrote:

Adding Jordan here.

On Tue, Aug 14, 2018 at 4:19 PM, Robin Murphy  
wrote:

Hi Vivek,

On 14/08/18 11:27, Vivek Gautam wrote:

Add device node for qcom,smmu-v2 available on sdm845.
This smmu is available only to GPU device.

Signed-off-by: Vivek Gautam 
---
   arch/arm64/boot/dts/qcom/sdm845.dtsi | 23 +++
   1 file changed, 23 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 1c2be2082f33..bd1ec5fa5146 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -6,6 +6,7 @@
    */
 #include 
+#include 
   #include 
   #include 
   #include 
@@ -989,6 +990,28 @@
 cell-index = <0>;
 };
   + gpu_smmu: iommu@504 {
+   compatible = "qcom,sdm845-smmu-v2",
"qcom,smmu-v2";


Which of "sdm845" or "msm8996"[1] is the actual SoC name here?

Well, the bindings use the SoC prefix with smmu-v2, so it should be
sdm845 for this SoC. This is same as I posted in my v1 of the series 
[2].

Using 8996 based string in sdm845 makes things look awful.

You need to list valid values of '' in the binding. Otherwise we
get this confusion.


Sorry for delayed response, I was away on vacation.
I will list down the valid values for '' as suggested, and respin 
this series, and

smmu bindings patch that comes as part of the runtime pm series [3].

[3] https://lore.kernel.org/patchwork/patch/968017/



I have updated the binding doc with valid values for '' string [4].
Kindly review this based on [4].

[4] https://lore.kernel.org/patchwork/patch/977888/

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

Re: [PATCH] iommu/rockchip: Free irqs in shutdown handler

2018-08-27 Thread Enric Balletbo Serra
Heiko,

Thanks for the patch
Missatge de Heiko Stuebner  del dia dl., 27 d’ag.
2018 a les 12:57:
>
> In the iommu's shutdown handler we disable runtime-pm which could
> result in the irq-handler running unclocked and since commit
> 3fc7c5c0cff3 ("iommu/rockchip: Handle errors returned from PM framework")
> we warn about that fact.
>
> This can cause warnings on shutdown on some Rockchip machines, so
> free the irqs in the shutdown handler before we disable runtime-pm.
>
> Reported-by: Enric Balletbo i Serra 
> Fixes: 3fc7c5c0cff3 ("iommu/rockchip: Handle errors returned from PM 
> framework")
> Signed-off-by: Heiko Stuebner 
> ---
>  drivers/iommu/rockchip-iommu.c | 6 ++
>  1 file changed, 6 insertions(+)
>
> diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
> index 258115b10fa9..ad3e2b97469e 100644
> --- a/drivers/iommu/rockchip-iommu.c
> +++ b/drivers/iommu/rockchip-iommu.c
> @@ -1241,6 +1241,12 @@ static int rk_iommu_probe(struct platform_device *pdev)
>
>  static void rk_iommu_shutdown(struct platform_device *pdev)
>  {
> +   struct rk_iommu *iommu = platform_get_drvdata(pdev);
> +   int i = 0, irq;
> +
> +   while ((irq = platform_get_irq(pdev, i++)) != -ENXIO)
> +   devm_free_irq(iommu->dev, irq, iommu);
> +
> pm_runtime_force_suspend(>dev);
>  }
>
> --
> 2.17.0
>

After this patch the WARNING is gone on my Samsung Chromebook Plus.

Tested-by: Enric Balletbo i Serra 

>
> ___
> Linux-rockchip mailing list
> linux-rockc...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

[Patch v15 5/5] iommu/arm-smmu: Add support for qcom,smmu-v2 variant

2018-08-27 Thread Vivek Gautam
qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
clock and power requirements.
On msm8996, multiple cores, viz. mdss, video, etc. use this
smmu. On sdm845, this smmu is used with gpu.
Add bindings for the same.

Signed-off-by: Vivek Gautam 
Reviewed-by: Rob Herring 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---

Changes since v14:
 - Moved out dt-bindings change to separate patch.

 drivers/iommu/arm-smmu.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index b5e7f72d418c..c0177ea32678 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -119,6 +119,7 @@ enum arm_smmu_implementation {
GENERIC_SMMU,
ARM_MMU500,
CAVIUM_SMMUV2,
+   QCOM_SMMUV2,
 };
 
 struct arm_smmu_s2cr {
@@ -1970,6 +1971,17 @@ ARM_SMMU_MATCH_DATA(arm_mmu401, ARM_SMMU_V1_64K, 
GENERIC_SMMU);
 ARM_SMMU_MATCH_DATA(arm_mmu500, ARM_SMMU_V2, ARM_MMU500);
 ARM_SMMU_MATCH_DATA(cavium_smmuv2, ARM_SMMU_V2, CAVIUM_SMMUV2);
 
+static const char * const qcom_smmuv2_clks[] = {
+   "bus", "iface",
+};
+
+static const struct arm_smmu_match_data qcom_smmuv2 = {
+   .version = ARM_SMMU_V2,
+   .model = QCOM_SMMUV2,
+   .clks = qcom_smmuv2_clks,
+   .num_clks = ARRAY_SIZE(qcom_smmuv2_clks),
+};
+
 static const struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,smmu-v1", .data = _generic_v1 },
{ .compatible = "arm,smmu-v2", .data = _generic_v2 },
@@ -1977,6 +1989,7 @@ static const struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,mmu-401", .data = _mmu401 },
{ .compatible = "arm,mmu-500", .data = _mmu500 },
{ .compatible = "cavium,smmu-v2", .data = _smmuv2 },
+   { .compatible = "qcom,smmu-v2", .data = _smmuv2 },
{ },
 };
 MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[Patch v15 4/5] dt-bindings: arm-smmu: Add bindings for qcom,smmu-v2

2018-08-27 Thread Vivek Gautam
Add bindings doc for Qcom's smmu-v2 implementation.

Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---

Changes since v14:
 - This is a new patch added in v15 after noticing the new
   checkpatch warning for separate dt-bindings doc.
 - This patch also addresses comments given by Rob and Robin to add
   a list of valid values of '' in "qcom,-smmu-v2"
   compatible string.

 .../devicetree/bindings/iommu/arm,smmu.txt | 47 ++
 1 file changed, 47 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 8a6ffce12af5..52198a539606 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -17,10 +17,24 @@ conditions.
 "arm,mmu-401"
 "arm,mmu-500"
 "cavium,smmu-v2"
+"qcom,-smmu-v2", "qcom,smmu-v2"
 
   depending on the particular implementation and/or the
   version of the architecture implemented.
 
+  A number of Qcom SoCs use qcom,smmu-v2 version of the IP.
+  "qcom,-smmu-v2" represents a soc specific compatible
+  string that should be present along with the "qcom,smmu-v2"
+  to facilitate SoC specific clocks/power connections and to
+  address specific bug fixes.
+  '' string in "qcom,-smmu-v2" should be one of the
+  following:
+  msm8996 - for msm8996 Qcom SoC.
+  sdm845 - for sdm845 Qcom Soc.
+
+  An example string would be -
+  "qcom,msm8996-smmu-v2", "qcom,smmu-v2".
+
 - reg   : Base address and size of the SMMU.
 
 - #global-interrupts : The number of global interrupts exposed by the
@@ -71,6 +85,22 @@ conditions.
   or using stream matching with #iommu-cells = <2>, and
   may be ignored if present in such cases.
 
+- clock-names:List of the names of clocks input to the device. The
+  required list depends on particular implementation and
+  is as follows:
+  - for "qcom,smmu-v2":
+- "bus": clock required for downstream bus access and
+ for the smmu ptw,
+- "iface": clock required to access smmu's registers
+   through the TCU's programming interface.
+  - unspecified for other implementations.
+
+- clocks: Specifiers for all clocks listed in the clock-names property,
+  as per generic clock bindings.
+
+- power-domains:  Specifiers for power domains required to be powered on for
+  the SMMU to operate, as per generic power domain bindings.
+
 ** Deprecated properties:
 
 - mmu-masters (deprecated in favour of the generic "iommus" binding) :
@@ -137,3 +167,20 @@ conditions.
 iommu-map = <0  0 0x400>;
 ...
 };
+
+   /* Qcom's arm,smmu-v2 implementation */
+   smmu4: iommu {
+   compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
+   reg = <0xd0 0x1>;
+
+   #global-interrupts = <1>;
+   interrupts = ,
+,
+;
+   #iommu-cells = <1>;
+   power-domains = < MDSS_GDSC>;
+
+   clocks = < SMMU_MDP_AXI_CLK>,
+< SMMU_MDP_AHB_CLK>;
+   clock-names = "bus", "iface";
+   };
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[Patch v15 2/5] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-08-27 Thread Vivek Gautam
From: Sricharan R 

The smmu device probe/remove and add/remove master device callbacks
gets called when the smmu is not linked to its master, that is without
the context of the master device. So calling runtime apis in those places
separately.

Signed-off-by: Sricharan R 
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---

Changes since v14:
 - none.

 drivers/iommu/arm-smmu.c | 101 +++
 1 file changed, 93 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index a81224bc6637..23b4a60149b6 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -268,6 +268,20 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
{ 0, NULL},
 };
 
+static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   return pm_runtime_get_sync(smmu->dev);
+
+   return 0;
+}
+
+static inline void arm_smmu_rpm_put(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   pm_runtime_put(smmu->dev);
+}
+
 static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
 {
return container_of(dom, struct arm_smmu_domain, domain);
@@ -913,11 +927,15 @@ static void arm_smmu_destroy_domain_context(struct 
iommu_domain *domain)
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct arm_smmu_device *smmu = smmu_domain->smmu;
struct arm_smmu_cfg *cfg = _domain->cfg;
-   int irq;
+   int ret, irq;
 
if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY)
return;
 
+   ret = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return;
+
/*
 * Disable the context bank and free the page tables before freeing
 * it.
@@ -932,6 +950,8 @@ static void arm_smmu_destroy_domain_context(struct 
iommu_domain *domain)
 
free_io_pgtable_ops(smmu_domain->pgtbl_ops);
__arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
+
+   arm_smmu_rpm_put(smmu);
 }
 
 static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
@@ -1213,10 +1233,15 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
return -ENODEV;
 
smmu = fwspec_smmu(fwspec);
+
+   ret = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return ret;
+
/* Ensure that the domain is finalised */
ret = arm_smmu_init_domain_context(domain, smmu);
if (ret < 0)
-   return ret;
+   goto rpm_put;
 
/*
 * Sanity check the domain. We don't support domains across
@@ -1226,33 +1251,50 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
dev_err(dev,
"cannot attach to SMMU %s whilst already attached to 
domain on SMMU %s\n",
dev_name(smmu_domain->smmu->dev), dev_name(smmu->dev));
-   return -EINVAL;
+   ret = -EINVAL;
+   goto rpm_put;
}
 
/* Looks ok, so add the device to the domain */
-   return arm_smmu_domain_add_master(smmu_domain, fwspec);
+   ret = arm_smmu_domain_add_master(smmu_domain, fwspec);
+
+rpm_put:
+   arm_smmu_rpm_put(smmu);
+   return ret;
 }
 
 static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t size, int prot)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   int ret;
 
if (!ops)
return -ENODEV;
 
-   return ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
 size_t size)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   size_t ret;
 
if (!ops)
return 0;
 
-   return ops->unmap(ops, iova, size);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->unmap(ops, iova, size);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static void arm_smmu_iotlb_sync(struct iommu_domain *domain)
@@ -1407,7 +1449,13 @@ static int arm_smmu_add_device(struct device *dev)
while (i--)
cfg->smendx[i] = INVALID_SMENDX;
 
+   ret = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   goto out_cfg_free;
+
ret = arm_smmu_master_alloc_smes(dev);
+   arm_smmu_rpm_put(smmu);
+
if (ret)
goto out_cfg_free;
 
@@ -1427,7 +1475,7 @@ static void 

[Patch v15 3/5] iommu/arm-smmu: Add the device_link between masters and smmu

2018-08-27 Thread Vivek Gautam
From: Sricharan R 

Finally add the device link between the master device and
smmu, so that the smmu gets runtime enabled/disabled only when the
master needs it. This is done from add_device callback which gets
called once when the master is added to the smmu.

Signed-off-by: Sricharan R 
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---

Changes since v14:
 - none.

 drivers/iommu/arm-smmu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 23b4a60149b6..b5e7f72d418c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1461,6 +1461,9 @@ static int arm_smmu_add_device(struct device *dev)
 
iommu_device_link(>iommu, dev);
 
+   device_link_add(dev, smmu->dev,
+   DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER);
+
return 0;
 
 out_cfg_free:
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[Patch v15 1/5] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-08-27 Thread Vivek Gautam
From: Sricharan R 

The smmu needs to be functional only when the respective
master's using it are active. The device_link feature
helps to track such functional dependencies, so that the
iommu gets powered when the master device enables itself
using pm_runtime. So by adapting the smmu driver for
runtime pm, above said dependency can be addressed.

This patch adds the pm runtime/sleep callbacks to the
driver and also the functions to parse the smmu clocks
from DT and enable them in resume/suspend.

Also, while we enable the runtime pm add a pm sleep suspend
callback that pushes devices to low power state by turning
the clocks off in a system sleep.
Also add corresponding clock enable path in resume callback.

Signed-off-by: Sricharan R 
Signed-off-by: Archit Taneja 
[vivek: rework for clock and pm ops]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---

Changes since v14:
 - none.

 drivers/iommu/arm-smmu.c | 77 ++--
 1 file changed, 74 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index fd1b80ef9490..a81224bc6637 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -48,6 +48,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -205,6 +206,8 @@ struct arm_smmu_device {
u32 num_global_irqs;
u32 num_context_irqs;
unsigned int*irqs;
+   struct clk_bulk_data*clks;
+   int num_clks;
 
u32 cavium_id_base; /* Specific to Cavium */
 
@@ -1896,10 +1899,12 @@ static int arm_smmu_device_cfg_probe(struct 
arm_smmu_device *smmu)
 struct arm_smmu_match_data {
enum arm_smmu_arch_version version;
enum arm_smmu_implementation model;
+   const char * const *clks;
+   int num_clks;
 };
 
 #define ARM_SMMU_MATCH_DATA(name, ver, imp)\
-static struct arm_smmu_match_data name = { .version = ver, .model = imp }
+static const struct arm_smmu_match_data name = { .version = ver, .model = imp }
 
 ARM_SMMU_MATCH_DATA(smmu_generic_v1, ARM_SMMU_V1, GENERIC_SMMU);
 ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU);
@@ -1918,6 +1923,23 @@ static const struct of_device_id arm_smmu_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
 
+static void arm_smmu_fill_clk_data(struct arm_smmu_device *smmu,
+  const char * const *clks)
+{
+   int i;
+
+   if (smmu->num_clks < 1)
+   return;
+
+   smmu->clks = devm_kcalloc(smmu->dev, smmu->num_clks,
+ sizeof(*smmu->clks), GFP_KERNEL);
+   if (!smmu->clks)
+   return;
+
+   for (i = 0; i < smmu->num_clks; i++)
+   smmu->clks[i].id = clks[i];
+}
+
 #ifdef CONFIG_ACPI
 static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)
 {
@@ -2000,6 +2022,9 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev,
data = of_device_get_match_data(dev);
smmu->version = data->version;
smmu->model = data->model;
+   smmu->num_clks = data->num_clks;
+
+   arm_smmu_fill_clk_data(smmu, data->clks);
 
parse_driver_options(smmu);
 
@@ -2098,6 +2123,14 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
smmu->irqs[i] = irq;
}
 
+   err = devm_clk_bulk_get(smmu->dev, smmu->num_clks, smmu->clks);
+   if (err)
+   return err;
+
+   err = clk_bulk_prepare(smmu->num_clks, smmu->clks);
+   if (err)
+   return err;
+
err = arm_smmu_device_cfg_probe(smmu);
if (err)
return err;
@@ -2184,6 +2217,9 @@ static int arm_smmu_device_remove(struct platform_device 
*pdev)
 
/* Turn the thing off */
writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
+
+   clk_bulk_unprepare(smmu->num_clks, smmu->clks);
+
return 0;
 }
 
@@ -2192,15 +2228,50 @@ static void arm_smmu_device_shutdown(struct 
platform_device *pdev)
arm_smmu_device_remove(pdev);
 }
 
-static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
+static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
 {
struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+   int ret;
+
+   ret = clk_bulk_enable(smmu->num_clks, smmu->clks);
+   if (ret)
+   return ret;
 
arm_smmu_device_reset(smmu);
+
return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume);
+static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
+{
+   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+   clk_bulk_disable(smmu->num_clks, smmu->clks);
+
+   return 0;
+}
+
+static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
+{
+   if 

[Patch v15 0/5] iommu/arm-smmu: Add runtime pm/sleep support

2018-08-27 Thread Vivek Gautam
This series provides the support for turning on the arm-smmu's
clocks/power domains using runtime pm. This is done using
device links between smmu and client devices. The device link
framework keeps the two devices in correct order for power-cycling
across runtime PM or across system-wide PM.

With addition of a new device link flag DL_FLAG_AUTOREMOVE_SUPPLIER [8],
the device links created between arm-smmu and its clients will be
automatically purged when arm-smmu driver unbinds from its device.

As not all implementations support clock/power gating, we are checking
for a valid 'smmu->dev's pm_domain' to conditionally enable the runtime
power management for such smmu implementations that can support it.
Otherwise, the clocks are turned to be always on in .probe until .remove.
With conditional runtime pm now, we avoid touching dev->power.lock
in fastpaths for smmu implementations that don't need to do anything
useful with pm_runtime.
This lets us to use the much-argued pm_runtime_get_sync/put_sync()
calls in map/unmap callbacks so that the clients do not have to
worry about handling any of the arm-smmu's power.

This series also adds support for Qcom's arm-smmu-v2 variant that
has different clocks and power requirements.

Previous version of this patch series is @ [2].

Build tested the series based on 4.19-rc1.

[v15]
   * Added a list of valid values of '' in "qcom,-smmu-v2"
 compatible string as pointed out by Robin, and Rob in the thread [9]:
   * Added Srini's Tested-by.
   * Separated out the dt-bindings change from driver change into a new
 patch as suggested by new checkpatch warning.

 Rob, I took the liberty of removing your Reviewed-by (for your
 comment on '') for the new dt-bindings patch 4/5.
 Please feel free to review it again. Thanks!

[v14]
   * Moved arm_smmu_device_reset() from arm_smmu_pm_resume() to
 arm_smmu_runtime_resume() so that the pm_resume callback calls
 only runtime_resume to resume the device.
 This should take care of restoring the state of smmu in systems
 in which smmu lose register state on power-domain collapse.

[v13]
   Addressing Rafael's comments:
   * Added .suspend pm callback to disable the clocks in system wide suspend.
   * Added corresponding clock enable in .resume pm callback.
   * Explicitly enabling/disabling the clocks now when runtime PM is disabled.
   * device_link_add() doesn't depend on pm_runtime_enabled() as we can
 use device links across system suspend/resume too.

   Addressing Robin's comments:
   * Making device_link_add failures as non-fatal.

   * Removed IOMMU_OF_DECLARE() declaration as we don't need this after Rob's
 patch that removed all of these declarations.

[v12]
   * Use new device link's flag introduced in [8] -
 DL_FLAG_AUTOREMOVE_SUPPLIER. With this devices links are automatically
 purged when arm-smmu driver unbinds.
   * Using pm_runtime_force_suspend() instead of pm_runtime_disable() to
 avoid following warning from arm_smmu_device_remove()

 [295711.537507] [ cut here ]
 [295711.544226] Unpreparing enabled smmu_mdp_ahb_clk
 [295711.549099] WARNING: CPU: 0 PID: 1 at ../drivers/clk/clk.c:697
 clk_core_unprepare+0xd8/0xe0
 ...
 [295711.674073] Call trace:
 [295711.679454]  clk_core_unprepare+0xd8/0xe0
 [295711.682059]  clk_unprepare+0x28/0x40
 [295711.685964]  clk_bulk_unprepare+0x28/0x40
 [295711.689701]  arm_smmu_device_remove+0x88/0xd8
 [295711.693692]  arm_smmu_device_shutdown+0xc/0x18
 [295711.698120]  platform_drv_shutdown+0x20/0x30

[v11]
   * Some more cleanups for device link. We don't need an explicit
 delete for device link from the driver, but just set the flag
 DL_FLAG_AUTOREMOVE.
 device_link_add() API description says -
 "If the DL_FLAG_AUTOREMOVE is set, the link will be removed
 automatically when the consumer device driver unbinds."
   * Addressed the comments for 'smmu' in arm_smmu_map/unmap().
   * Dropped the patch [7] that introduced device_link_del_dev() API. 

[v10]
   * Introduce device_link_del_dev() API to delete the link between
 given consumer and supplier devices. The users of device link
 do not need to store link pointer to delete the link later.
 They can straightaway use this API by passing consumer and
 supplier devices.
   * Made corresponding changes to arm-smmu driver patch handling the
 device links.
   * Dropped the patch [6] that was adding device_link_find() API to
 device core layer. device_link_del_dev() serves the purpose to
 directly delete the link between two given devices.

[v9]
   * Removed 'rpm_supported' flag, instead checking on pm_domain
 to enable runtime pm.
   * Creating device link only when the runtime pm is enabled, as we
 don't need a device link besides managing the power dependency
 between supplier and consumer devices.
   * Introducing a patch to add 

[PATCH] iommu/rockchip: Free irqs in shutdown handler

2018-08-27 Thread Heiko Stuebner
In the iommu's shutdown handler we disable runtime-pm which could
result in the irq-handler running unclocked and since commit
3fc7c5c0cff3 ("iommu/rockchip: Handle errors returned from PM framework")
we warn about that fact.

This can cause warnings on shutdown on some Rockchip machines, so
free the irqs in the shutdown handler before we disable runtime-pm.

Reported-by: Enric Balletbo i Serra 
Fixes: 3fc7c5c0cff3 ("iommu/rockchip: Handle errors returned from PM framework")
Signed-off-by: Heiko Stuebner 
---
 drivers/iommu/rockchip-iommu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 258115b10fa9..ad3e2b97469e 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1241,6 +1241,12 @@ static int rk_iommu_probe(struct platform_device *pdev)
 
 static void rk_iommu_shutdown(struct platform_device *pdev)
 {
+   struct rk_iommu *iommu = platform_get_drvdata(pdev);
+   int i = 0, irq;
+
+   while ((irq = platform_get_irq(pdev, i++)) != -ENXIO)
+   devm_free_irq(iommu->dev, irq, iommu);
+
pm_runtime_force_suspend(>dev);
 }
 
-- 
2.17.0

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


Re: [PATCH 16/20] powerpc/dma: use dma_direct_{alloc,free}

2018-08-27 Thread Scott Wood
On Thu, 2018-08-09 at 10:52 +1000, Benjamin Herrenschmidt wrote:
> On Mon, 2018-07-30 at 18:38 +0200, Christoph Hellwig wrote:
> > These do the same functionality as the existing helpers, but do it
> > simpler, and also allow the (optional) use of CMA.
> > 
> > Note that the swiotlb code now calls into the dma_direct code directly,
> > given that it doesn't work with noncoherent caches at all, and isn't
> > called
> > when we have an iommu either, so the iommu special case in
> > dma_nommu_alloc_coherent isn't required for swiotlb.
> 
> I am not convinced that this will produce the same results due to
> the way the zone picking works.
> 
> As for the interaction with swiotlb, we'll need the FSL guys to have
> a look. Scott, do you remember what this is about ?

dma_direct_alloc() has similar (though not identical[1]) zone picking, so I
think it will work.  Needs testing though, and I no longer have a book3e
machine with a PCIe card in it.

The odd thing about this platform (fsl book3e) is the 31-bit[2] limitation on
PCI.  We currently use ZONE_DMA32 for this, rather than ZONE_DMA, at Ben's
request[3].  dma_direct_alloc() regards ZONE_DMA32 as being fixed at 32-bits,
but it doesn't really matter as long as limit_zone_pfn() still works, and the
allocation is made below 2 GiB.  If we were to switch to ZONE_DMA, and have
both 31-bit and 32-bit zones, then dma_direct_alloc() would have a problem
knowing when to use the 31-bit zone since it's based on a non-power-of-2 limit
that isn't reflected in the dma mask.

-Scott

[1] The logic in dma_direct_alloc() seems wrong -- the zone should need to fit
in the mask, not the other way around.  If ARCH_ZONE_DMA_BITS is 24, then
0x007f should be a failure rather than GFP_DMA, 0x7fff should be
GFP_DMA rather than GFP_DMA32, and 0x3 should be GFP_DMA32 rather than
an unrestricted allocation (in each case assuming that the end of RAM is
beyond the mask).

[2] The actual limit is closer to 4 GiB, but not quite due to special windows.
 swiotlb still uses the real limit when deciding whether to bounce, so the dma
mask is still 32 bits.

[3] https://lists.ozlabs.org/pipermail/linuxppc-dev/2012-July/099593.html

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


Re: [PATCH v2 3/3] dts: arm64/sdm845: Add node for qcom,smmu-v2

2018-08-27 Thread Vivek Gautam

Hi Rob, Robin,


On 8/15/2018 4:27 AM, Rob Herring wrote:

On Wed, Aug 15, 2018 at 01:09:43AM +0530, Vivek Gautam wrote:

Adding Jordan here.

On Tue, Aug 14, 2018 at 4:19 PM, Robin Murphy  wrote:

Hi Vivek,

On 14/08/18 11:27, Vivek Gautam wrote:

Add device node for qcom,smmu-v2 available on sdm845.
This smmu is available only to GPU device.

Signed-off-by: Vivek Gautam 
---
   arch/arm64/boot/dts/qcom/sdm845.dtsi | 23 +++
   1 file changed, 23 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 1c2be2082f33..bd1ec5fa5146 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -6,6 +6,7 @@
*/
 #include 
+#include 
   #include 
   #include 
   #include 
@@ -989,6 +990,28 @@
 cell-index = <0>;
 };
   + gpu_smmu: iommu@504 {
+   compatible = "qcom,sdm845-smmu-v2",
"qcom,smmu-v2";


Which of "sdm845" or "msm8996"[1] is the actual SoC name here?

Well, the bindings use the SoC prefix with smmu-v2, so it should be
sdm845 for this SoC. This is same as I posted in my v1 of the series [2].
Using 8996 based string in sdm845 makes things look awful.

You need to list valid values of '' in the binding. Otherwise we
get this confusion.


Sorry for delayed response, I was away on vacation.
I will list down the valid values for '' as suggested, and respin 
this series, and

smmu bindings patch that comes as part of the runtime pm series [1].

[1] https://lore.kernel.org/patchwork/patch/968017/

Best regards
Vivek



Rob


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


[PATCH 4/4] dma-mapping: clear dev->dma_ops in arch_teardown_dma_ops

2018-08-27 Thread Christoph Hellwig
There is no reason to leave the per-device dma_ops around when
deconfiguring a device, so move this code from arm64 into the
common code.

Signed-off-by: Christoph Hellwig 
---
 arch/arm64/include/asm/dma-mapping.h | 5 -
 arch/arm64/mm/dma-mapping.c  | 5 -
 include/linux/dma-mapping.h  | 5 -
 3 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/include/asm/dma-mapping.h 
b/arch/arm64/include/asm/dma-mapping.h
index b7847eb8a7bb..0a2d13332545 100644
--- a/arch/arm64/include/asm/dma-mapping.h
+++ b/arch/arm64/include/asm/dma-mapping.h
@@ -39,11 +39,6 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, 
u64 size,
const struct iommu_ops *iommu, bool coherent);
 #define arch_setup_dma_ops arch_setup_dma_ops
 
-#ifdef CONFIG_IOMMU_DMA
-void arch_teardown_dma_ops(struct device *dev);
-#define arch_teardown_dma_ops  arch_teardown_dma_ops
-#endif
-
 /* do not use this function in a driver */
 static inline bool is_device_dma_coherent(struct device *dev)
 {
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 072c51fb07d7..cdcb73db9ea2 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -862,11 +862,6 @@ static void __iommu_setup_dma_ops(struct device *dev, u64 
dma_base, u64 size,
 dev_name(dev));
 }
 
-void arch_teardown_dma_ops(struct device *dev)
-{
-   dev->dma_ops = NULL;
-}
-
 #else
 
 static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 1423b69f3cc9..eafd6f318e78 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -664,7 +664,10 @@ static inline void arch_setup_dma_ops(struct device *dev, 
u64 dma_base,
 #endif
 
 #ifndef arch_teardown_dma_ops
-static inline void arch_teardown_dma_ops(struct device *dev) { }
+static inline void arch_teardown_dma_ops(struct device *dev)
+{
+   dev->dma_ops = NULL;
+}
 #endif
 
 static inline unsigned int dma_get_max_seg_size(struct device *dev)
-- 
2.18.0

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


[PATCH 2/4] dma-mapping: remove dma_configure

2018-08-27 Thread Christoph Hellwig
There is no good reason for this indirection given that the method
always exists.

Signed-off-by: Christoph Hellwig 
---
 drivers/base/dd.c   |  8 +---
 include/linux/dma-mapping.h |  6 --
 kernel/dma/mapping.c| 10 --
 3 files changed, 5 insertions(+), 19 deletions(-)

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index edfc9f0b1180..65128cf8427c 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -480,9 +480,11 @@ static int really_probe(struct device *dev, struct 
device_driver *drv)
if (ret)
goto pinctrl_bind_failed;
 
-   ret = dma_configure(dev);
-   if (ret)
-   goto dma_failed;
+   if (dev->bus->dma_configure) {
+   ret = dev->bus->dma_configure(dev);
+   if (ret)
+   goto dma_failed;
+   }
 
if (driver_sysfs_add(dev)) {
printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 1db6a6b46d0d..1c6c7c09bcf2 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -754,14 +754,8 @@ dma_mark_declared_memory_occupied(struct device *dev,
 #endif /* CONFIG_HAVE_GENERIC_DMA_COHERENT */
 
 #ifdef CONFIG_HAS_DMA
-int dma_configure(struct device *dev);
 void dma_deconfigure(struct device *dev);
 #else
-static inline int dma_configure(struct device *dev)
-{
-   return 0;
-}
-
 static inline void dma_deconfigure(struct device *dev) {}
 #endif
 
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index d2a92ddaac4d..25607ceb4a50 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -328,16 +328,6 @@ void dma_common_free_remap(void *cpu_addr, size_t size, 
unsigned long vm_flags)
 }
 #endif
 
-/*
- * enables DMA API use for a device
- */
-int dma_configure(struct device *dev)
-{
-   if (dev->bus->dma_configure)
-   return dev->bus->dma_configure(dev);
-   return 0;
-}
-
 void dma_deconfigure(struct device *dev)
 {
of_dma_deconfigure(dev);
-- 
2.18.0

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


[PATCH 3/4] dma-mapping: remove dma_deconfigure

2018-08-27 Thread Christoph Hellwig
This goes through a lot of hooks just to call arch_teardown_dma_ops.
Replace it with a direct call instead.

Signed-off-by: Christoph Hellwig 
---
 drivers/acpi/arm64/iort.c   |  2 +-
 drivers/acpi/scan.c | 10 --
 drivers/base/dd.c   |  4 ++--
 drivers/of/device.c | 12 
 include/acpi/acpi_bus.h |  1 -
 include/linux/acpi.h|  2 --
 include/linux/dma-mapping.h |  6 --
 include/linux/of_device.h   |  3 ---
 kernel/dma/mapping.c|  6 --
 9 files changed, 3 insertions(+), 43 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 08f26db2da7e..2a361e22d38d 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1428,7 +1428,7 @@ static int __init iort_add_platform_device(struct 
acpi_iort_node *node,
return 0;
 
 dma_deconfigure:
-   acpi_dma_deconfigure(>dev);
+   arch_teardown_dma_ops(>dev);
 dev_put:
platform_device_put(pdev);
 
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e1b6231cfa1c..56676a56b3e3 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1469,16 +1469,6 @@ int acpi_dma_configure(struct device *dev, enum 
dev_dma_attr attr)
 }
 EXPORT_SYMBOL_GPL(acpi_dma_configure);
 
-/**
- * acpi_dma_deconfigure - Tear-down DMA configuration for the device.
- * @dev: The pointer to the device
- */
-void acpi_dma_deconfigure(struct device *dev)
-{
-   arch_teardown_dma_ops(dev);
-}
-EXPORT_SYMBOL_GPL(acpi_dma_deconfigure);
-
 static void acpi_init_coherency(struct acpi_device *adev)
 {
unsigned long long cca = 0;
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 65128cf8427c..169412ee4ae8 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -539,7 +539,7 @@ static int really_probe(struct device *dev, struct 
device_driver *drv)
goto done;
 
 probe_failed:
-   dma_deconfigure(dev);
+   arch_teardown_dma_ops(dev);
 dma_failed:
if (dev->bus)
blocking_notifier_call_chain(>bus->p->bus_notifier,
@@ -968,7 +968,7 @@ static void __device_release_driver(struct device *dev, 
struct device *parent)
drv->remove(dev);
 
device_links_driver_cleanup(dev);
-   dma_deconfigure(dev);
+   arch_teardown_dma_ops(dev);
 
devres_release_all(dev);
dev->driver = NULL;
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 5957cd4fa262..c7fa5a9697c9 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -170,18 +170,6 @@ int of_dma_configure(struct device *dev, struct 
device_node *np, bool force_dma)
 }
 EXPORT_SYMBOL_GPL(of_dma_configure);
 
-/**
- * of_dma_deconfigure - Clean up DMA configuration
- * @dev:   Device for which to clean up DMA configuration
- *
- * Clean up all configuration performed by of_dma_configure_ops() and free all
- * resources that have been allocated.
- */
-void of_dma_deconfigure(struct device *dev)
-{
-   arch_teardown_dma_ops(dev);
-}
-
 int of_device_register(struct platform_device *pdev)
 {
device_initialize(>dev);
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index ba4dd54f2c82..53600f527a70 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -595,7 +595,6 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device 
*adev);
 int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset,
   u64 *size);
 int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
-void acpi_dma_deconfigure(struct device *dev);
 
 struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
   u64 address, bool check_children);
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index de8d3d3fa651..af4628979d13 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -831,8 +831,6 @@ static inline int acpi_dma_configure(struct device *dev,
return 0;
 }
 
-static inline void acpi_dma_deconfigure(struct device *dev) { }
-
 #define ACPI_PTR(_ptr) (NULL)
 
 static inline void acpi_device_set_enumerated(struct acpi_device *adev)
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 1c6c7c09bcf2..1423b69f3cc9 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -753,12 +753,6 @@ dma_mark_declared_memory_occupied(struct device *dev,
 }
 #endif /* CONFIG_HAVE_GENERIC_DMA_COHERENT */
 
-#ifdef CONFIG_HAS_DMA
-void dma_deconfigure(struct device *dev);
-#else
-static inline void dma_deconfigure(struct device *dev) {}
-#endif
-
 /*
  * Managed DMA API
  */
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index 165fd302b442..8d31e39dd564 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -58,7 +58,6 @@ static inline struct device_node *of_cpu_device_node_get(int 
cpu)
 int of_dma_configure(struct device *dev,
 struct device_node *np,
 

[PATCH 1/4] arm-nommu: don't define arch_teardown_dma_ops

2018-08-27 Thread Christoph Hellwig
We can just use the default implementation.

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

diff --git a/arch/arm/include/asm/dma-mapping.h 
b/arch/arm/include/asm/dma-mapping.h
index 8436f6ade57d..965b7c846ecb 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -100,8 +100,10 @@ static inline unsigned long dma_max_pfn(struct device *dev)
 extern void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
   const struct iommu_ops *iommu, bool coherent);
 
+#ifdef CONFIG_MMU
 #define arch_teardown_dma_ops arch_teardown_dma_ops
 extern void arch_teardown_dma_ops(struct device *dev);
+#endif
 
 /* do not use this function in a driver */
 static inline bool is_device_dma_coherent(struct device *dev)
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
index f448a0663b10..aa7aba302e76 100644
--- a/arch/arm/mm/dma-mapping-nommu.c
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -237,7 +237,3 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, 
u64 size,
 
set_dma_ops(dev, dma_ops);
 }
-
-void arch_teardown_dma_ops(struct device *dev)
-{
-}
-- 
2.18.0

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


cleanup ->dma_configure calling conventions

2018-08-27 Thread Christoph Hellwig
Hi all,

this series cleans up a bit how we call ->dma_configure and how
we clean up after tearing down a device that the method did set
up.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/3] hexagon: remove the sync_single_for_cpu DMA operation

2018-08-27 Thread Christoph Hellwig
Given that it didn't make 4.19-rc1, I'll pull this into the dma-mapping
tree first thing for 4.20 as I have some other changes that will go on
top of it.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v5 3/5] iommu/io-pgtable-arm: add support for non-strict mode

2018-08-27 Thread Leizhen (ThunderTown)



On 2018/8/23 1:52, Robin Murphy wrote:
> On 15/08/18 02:28, Zhen Lei wrote:
>> To support the non-strict mode, now we only tlbi and sync for the strict
>> mode. But for the non-leaf case, always follow strict mode.
>>
>> Signed-off-by: Zhen Lei 
>> ---
>>   drivers/iommu/io-pgtable-arm.c | 20 ++--
>>   drivers/iommu/io-pgtable.h |  3 +++
>>   2 files changed, 17 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
>> index 010a254..20d3e98 100644
>> --- a/drivers/iommu/io-pgtable-arm.c
>> +++ b/drivers/iommu/io-pgtable-arm.c
>> @@ -538,6 +538,7 @@ static size_t arm_lpae_split_blk_unmap(struct 
>> arm_lpae_io_pgtable *data,
>>   phys_addr_t blk_paddr;
>>   size_t tablesz = ARM_LPAE_GRANULE(data);
>>   size_t split_sz = ARM_LPAE_BLOCK_SIZE(lvl, data);
>> +size_t unmapped = size;
>>   int i, unmap_idx = -1;
>>
>>   if (WARN_ON(lvl == ARM_LPAE_MAX_LEVELS))
>> @@ -575,11 +576,16 @@ static size_t arm_lpae_split_blk_unmap(struct 
>> arm_lpae_io_pgtable *data,
>>   tablep = iopte_deref(pte, data);
>>   }
>>
>> -if (unmap_idx < 0)
> 
> [ side note: the more I see this test the more it looks slightly wrong, but 
> that's a separate issue. I'll have to sit down and really remember what's 
> going on here... ]
> 
>> -return __arm_lpae_unmap(data, iova, size, lvl, tablep);
>> +if (unmap_idx < 0) {
>> +unmapped = __arm_lpae_unmap(data, iova, size, lvl, tablep);
>> +if (!(data->iop.cfg.quirks & IO_PGTABLE_QUIRK_NON_STRICT))
>> +return unmapped;
>> +}
> 
> I don't quite get this change - we should only be recursing back into 
> __arm_lpae_unmap() here if nothing's actually been unmapped at this point - 
> the block entry is simply replaced by a full next-level table and we're going 
> to come back and split another block at that next level, or we raced against 
> someone else splitting the same block and that's their table instead. Since 
> that's reverting back to a "regular" unmap, I don't see where the need to 
> introduce an additional flush to that path comes from (relative to the 
> existing behaviour, at least).

The old block mapping maybe cached in TLBs, it should be invalidated completely 
before the new next-level mapping to be used. Just ensure that.

In fact, I think the code of arm_lpae_split_blk_unmap may has some mistakes. 
For example:
if (size == split_sz)
unmap_idx = ARM_LPAE_LVL_IDX(iova, lvl, data);

It means that "the size" can only be the block/page size of the next-level. 
Suppose current level is 2M block, but we may unmap 12K, and
the above "if" will limit us only be able to unmap 4K.

Furthermore, the situation "if (unmap_idx < 0)" should not appear.

Maybe my analysis is wrong, I will try to test it.


> 
>>   io_pgtable_tlb_add_flush(>iop, iova, size, size, true);
> 
> This is the flush which corresponds to whatever page split_blk_unmap() 
> actually unmapped itself (and also covers any recursively-split 
> intermediate-level entries)...
> 
>> -return size;
>> +io_pgtable_tlb_sync(>iop);
> 
> ...which does want this sync, but only technically for non-strict mode, since 
> it's otherwise covered by the sync in iommu_unmap().

Because split_blk_unmap() is rarely to be called, it has little impact on the 
overall performance,
so I ommitted the if statement of non-strict, I will add it back.

> 
> I'm not *against* tightening up the TLB maintenance here in general, but if 
> so that should be a separately-reasoned patch, not snuck in with other 
> changes.

OK

> 
> Robin.
> 
>> +
>> +return unmapped;
>>   }
>>
>>   static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
>> @@ -609,7 +615,7 @@ static size_t __arm_lpae_unmap(struct 
>> arm_lpae_io_pgtable *data,
>>   io_pgtable_tlb_sync(iop);
>>   ptep = iopte_deref(pte, data);
>>   __arm_lpae_free_pgtable(data, lvl + 1, ptep);
>> -} else {
>> +} else if (!(iop->cfg.quirks & IO_PGTABLE_QUIRK_NON_STRICT)) {
>>   io_pgtable_tlb_add_flush(iop, iova, size, size, true);
>>   }
>>
>> @@ -771,7 +777,8 @@ static void arm_lpae_restrict_pgsizes(struct 
>> io_pgtable_cfg *cfg)
>>   u64 reg;
>>   struct arm_lpae_io_pgtable *data;
>>
>> -if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS | IO_PGTABLE_QUIRK_NO_DMA))
>> +if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS | IO_PGTABLE_QUIRK_NO_DMA |
>> +IO_PGTABLE_QUIRK_NON_STRICT))
>>   return NULL;
>>
>>   data = arm_lpae_alloc_pgtable(cfg);
>> @@ -863,7 +870,8 @@ static void arm_lpae_restrict_pgsizes(struct 
>> io_pgtable_cfg *cfg)
>>   struct arm_lpae_io_pgtable *data;
>>
>>   /* The NS quirk doesn't apply at stage 2 */
>> -if (cfg->quirks & ~IO_PGTABLE_QUIRK_NO_DMA)
>> +if (cfg->quirks & ~(IO_PGTABLE_QUIRK_NO_DMA |
>> +IO_PGTABLE_QUIRK_NON_STRICT))
>>   return NULL;
>>

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

2018-08-27 Thread Xu Zaibo

Hi Jean,

On 2018/5/12 3:06, Jean-Philippe Brucker wrote:

diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 1aa7b82e8169..dc07752c8fe8 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -665,6 +665,82 @@ struct vfio_iommu_type1_dma_unmap {
  #define VFIO_IOMMU_ENABLE _IO(VFIO_TYPE, VFIO_BASE + 15)
  #define VFIO_IOMMU_DISABLE_IO(VFIO_TYPE, VFIO_BASE + 16)
  
+/*

+ * VFIO_IOMMU_BIND_PROCESS
+ *
+ * Allocate a PASID for a process address space, and use it to attach this
+ * process to all devices in the container. Devices can then tag their DMA
+ * traffic with the returned @pasid to perform transactions on the associated
+ * virtual address space. Mapping and unmapping buffers is performed by 
standard
+ * functions such as mmap and malloc.
+ *
+ * If flag is VFIO_IOMMU_BIND_PID, @pid contains the pid of a foreign process 
to
+ * bind. Otherwise the current task is bound. Given that the caller owns the
+ * device, setting this flag grants the caller read and write permissions on 
the
+ * entire address space of foreign process described by @pid. Therefore,
+ * permission to perform the bind operation on a foreign process is governed by
+ * the ptrace access mode PTRACE_MODE_ATTACH_REALCREDS check. See man ptrace(2)
+ * for more information.
+ *
+ * On success, VFIO writes a Process Address Space ID (PASID) into @pasid. This
+ * ID is unique to a process and can be used on all devices in the container.
+ *
+ * On fork, the child inherits the device fd and can use the bonds setup by its
+ * parent. Consequently, the child has R/W access on the address spaces bound 
by
+ * its parent. After an execv, the device fd is closed and the child doesn't
+ * have access to the address space anymore.
+ *
+ * To remove a bond between process and container, VFIO_IOMMU_UNBIND ioctl is
+ * issued with the same parameters. If a pid was specified in VFIO_IOMMU_BIND,
+ * it should also be present for VFIO_IOMMU_UNBIND. Otherwise unbind the 
current
+ * task from the container.
+ */
+struct vfio_iommu_type1_bind_process {
+   __u32   flags;
+#define VFIO_IOMMU_BIND_PID(1 << 0)
+   __u32   pasid;
As I am doing some works on the SVA patch set. I just consider why the 
user space need this pasid.
Maybe, is it much more reasonable to set the pasid into all devices 
under the vfio container by
a call back function from 'vfio_devices'  while 
'VFIO_IOMMU_BIND_PROCESS' CMD is executed
in kernel land? I am not sure because there exists no suitable call back 
in 'vfio_device' at present.


Thanks,
Zaibo

+   __s32   pid;
+};
+
+/*
+ * Only mode supported at the moment is VFIO_IOMMU_BIND_PROCESS, which takes
+ * vfio_iommu_type1_bind_process in data.
+ */
+struct vfio_iommu_type1_bind {
+   __u32   argsz;
+   __u32   flags;
+#define VFIO_IOMMU_BIND_PROCESS(1 << 0)
+   __u8data[];
+};
+
+/*
+ * VFIO_IOMMU_BIND - _IOWR(VFIO_TYPE, VFIO_BASE + 22, struct vfio_iommu_bind)
+ *
+ * Manage address spaces of devices in this container. Initially a TYPE1
+ * container can only have one address space, managed with
+ * VFIO_IOMMU_MAP/UNMAP_DMA.
+ *
+ * An IOMMU of type VFIO_TYPE1_NESTING_IOMMU can be managed by both MAP/UNMAP
+ * and BIND ioctls at the same time. MAP/UNMAP acts on the stage-2 (host) page
+ * tables, and BIND manages the stage-1 (guest) page tables. Other types of
+ * IOMMU may allow MAP/UNMAP and BIND to coexist, where MAP/UNMAP controls
+ * non-PASID traffic and BIND controls PASID traffic. But this depends on the
+ * underlying IOMMU architecture and isn't guaranteed.
+ *
+ * Availability of this feature depends on the device, its bus, the underlying
+ * IOMMU and the CPU architecture.
+ *
+ * returns: 0 on success, -errno on failure.
+ */
+#define VFIO_IOMMU_BIND_IO(VFIO_TYPE, VFIO_BASE + 22)
+
+/*
+ * VFIO_IOMMU_UNBIND - _IOWR(VFIO_TYPE, VFIO_BASE + 23, struct vfio_iommu_bind)
+ *
+ * Undo what was done by the corresponding VFIO_IOMMU_BIND ioctl.
+ */
+#define VFIO_IOMMU_UNBIND  _IO(VFIO_TYPE, VFIO_BASE + 23)
+
  /*  Additional API for SPAPR TCE (Server POWERPC) IOMMU  */
  
  /*



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


Re: [PATCH] Changing the AMD IOMMU API path to work in an atomic context which is necessary for any custom drivers using the IOMMU API while holding a spinlock.

2018-08-27 Thread Christoph Hellwig
On Fri, Aug 24, 2018 at 11:55:53PM +0100, Tom Murphy wrote:
> We were going to do this by using the iommu-dma api and replacing all the
> existing calls to the DMA api functions in the amd driver with their
> iommu-dma equivalent like in this driver:
> https://elixir.bootlin.com/linux/latest/source/arch/arm64/mm/dma-mapping.c#L810

FYI, I have a a wip branch to move the arm64 wrappers for both
swiotlb and dma-iommu here:

http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/dma-maybe-coherent

Maybe you could try to base on top of that.

> To do this we need the map/unmap callbacks to be spinlock-safe.

You probably want to send the patch together with the one(s) making use
of it.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v5 5/5] iommu/arm-smmu-v3: add bootup option "iommu.non_strict"

2018-08-27 Thread Leizhen (ThunderTown)



On 2018/8/23 1:02, Robin Murphy wrote:
> On 15/08/18 02:28, Zhen Lei wrote:
>> Add a bootup option to make the system manager can choose which mode to
>> be used. The default mode is strict.
>>
>> Signed-off-by: Zhen Lei 
>> ---
>>   Documentation/admin-guide/kernel-parameters.txt | 13 +
>>   drivers/iommu/arm-smmu-v3.c | 22 +-
>>   2 files changed, 34 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/admin-guide/kernel-parameters.txt 
>> b/Documentation/admin-guide/kernel-parameters.txt
>> index 5cde1ff..cb9d043e 100644
>> --- a/Documentation/admin-guide/kernel-parameters.txt
>> +++ b/Documentation/admin-guide/kernel-parameters.txt
>> @@ -1720,6 +1720,19 @@
>>   nobypass[PPC/POWERNV]
>>   Disable IOMMU bypass, using IOMMU for PCI devices.
>>
>> +iommu.non_strict=[ARM64]
>> +Format: { "0" | "1" }
>> +0 - strict mode, default.
>> +Release IOVAs after the related TLBs are invalid
>> +completely.
>> +1 - non-strict mode.
>> +Put off TLBs invalidation and release memory first.
>> +It's good for scatter-gather performance but lacks
>> +full isolation, an untrusted device can access the
>> +reused memory because the TLBs may still valid.
>> +Please takefull consideration before choosing this
>> +mode. Note that, VFIO will always use strict mode.
>> +
>>   iommu.passthrough=
>>   [ARM64] Configure DMA to bypass the IOMMU by default.
>>   Format: { "0" | "1" }
>> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
>> index 61eb7ec..0eda90e 100644
>> --- a/drivers/iommu/arm-smmu-v3.c
>> +++ b/drivers/iommu/arm-smmu-v3.c
>> @@ -631,6 +631,26 @@ struct arm_smmu_option_prop {
>>   { 0, NULL},
>>   };
>>
>> +static bool smmu_non_strict __read_mostly;
>> +
>> +static int __init arm_smmu_setup(char *str)
>> +{
>> +int ret;
>> +
>> +ret = kstrtobool(str, _non_strict);
>> +if (ret)
>> +return ret;
>> +
>> +if (smmu_non_strict) {
>> +pr_warn("WARNING: iommu non-strict mode is chosen.\n"
>> +"It's good for scatter-gather performance but lacks full 
>> isolation\n");
>> +add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
>> +}
>> +
>> +return 0;
>> +}
>> +early_param("iommu.non_strict", arm_smmu_setup);
> 
> As I said on v3, the option should be parsed by iommu-dma, since that's where 
> it takes effect, and I'm sure SMMUv2 users will be interested in trying it 
> out too.

OK, I am so sorry that I have not understood your opinion correctly.

> 
> In other words, if iommu_dma_init_domain() does something like:
> 
> if (iommu_dma_non_strict && domain->ops->flush_iotlb_all) {
> domain->non_strict = true;
> cookie->domain = domain;
> init_iova_flush_queue(...);
> }
> 
>> +
>>   static inline void __iomem *arm_smmu_page1_fixup(unsigned long offset,
>>struct arm_smmu_device *smmu)
>>   {
>> @@ -1622,7 +1642,7 @@ static int arm_smmu_domain_finalise(struct 
>> iommu_domain *domain)
>>   if (smmu->features & ARM_SMMU_FEAT_COHERENCY)
>>   pgtbl_cfg.quirks = IO_PGTABLE_QUIRK_NO_DMA;
>>
>> -if (domain->type == IOMMU_DOMAIN_DMA) {
>> +if ((domain->type == IOMMU_DOMAIN_DMA) && smmu_non_strict) {
>>   domain->non_strict = true;
>>   pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
>>   }
> 
> ...then all the driver should need to do is:
> 
> if (domain->non_strict)
> pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
> 
> 
> Now, that would make it possible to request non-strict mode even with drivers 
> which *don't* understand it, but I think that's not actually harmful, just 
> means that some TLBIs will still get issued synchronously and the flush queue 
> might not do much. If you wanted to avoid even that, you could replace 
> domain->non_strict with an iommu_domain_set_attr() call, so iommu_dma could 
> tell up-front whether the driver understands non-strict mode and it's worth 
> setting the queue up or not.

OK, I will think seriously about it, thanks. I've been busy these days, I will 
reply to you as soon as possible.

> 
> Robin.
> 
> .
> 

-- 
Thanks!
BestRegards

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


Re: [PATCH] Changing the AMD IOMMU API path to work in an atomic context which is necessary for any custom drivers using the IOMMU API while holding a spinlock.

2018-08-27 Thread Christoph Hellwig
On Fri, Aug 24, 2018 at 04:24:49PM +0100, Robin Murphy wrote:
> Although IIRC the AMD driver is in fact the only one whose map/unmap
> callbacks aren't already spinlock-safe (or at least it was last time I was
> looking). Stuff like iommu-dma is already relying on this in order to
> implement streaming DMA API calls (which may be in atomic context) on top of
> the corresponding IOMMU API operations.

True.  That should be mentioned in the spinlock, though - and once
it is done the calling conventions should be documented.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v9 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-08-27 Thread Geert Uytterhoeven
Hi Gary,

On Tue, Jun 12, 2018 at 11:42 PM Gary R Hook  wrote:
> Implement a skeleton framework for debugfs support in the AMD
> IOMMU.  Add an AMD-specific Kconfig boolean that depends upon
> general enablement of DebugFS in the IOMMU.
>
> Signed-off-by: Gary R Hook 

This is now commit 7d0f5fd3e4d68742 ("iommu/amd: Add basic debugfs
infrastructure for AMD IOMMU").

> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -146,6 +146,18 @@ config AMD_IOMMU_V2
>   hardware. Select this option if you want to use devices that support
>   the PCI PRI and PASID interface.
>
> +config AMD_IOMMU_DEBUGFS
> +   bool "Enable AMD IOMMU internals in DebugFS"
> +   depends on AMD_IOMMU && IOMMU_DEBUGFS
> +   ---help---
> + !!!WARNING!!!  !!!WARNING!!!  !!!WARNING!!!  !!!WARNING!!!
> +
> + DO NOT ENABLE THIS OPTION UNLESS YOU REALLY, -REALLY- KNOW WHAT YOU 
> ARE DOING!!!
> + Exposes AMD IOMMU device internals in DebugFS.
> +
> + This option is -NOT- intended for production environments, and 
> should
> + not generally be enabled.

If it is that bad, shouldn't this option be protected by some Kconfig
trickery to avoid it being enabled in allmodconfig/allyesconfig builds?

I forgot the way to do that, so some CCs added.

Gr{oetje,eeting}s,

Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu