Re: [PATCH 1/2] dt-bindings: iommu: renesas, ipmmu-vmsa: add r8a779f0 support

2022-01-27 Thread Laurent Pinchart
Hi Geert,

On Thu, Jan 27, 2022 at 12:05:31PM +0100, Geert Uytterhoeven wrote:
> On Tue, Jan 25, 2022 at 6:33 PM Yoshihiro Shimoda wrote:
> > Document the compatible values for the IPMMU-VMSA blocks in
> > the Renesas R-Car S4-8 (R8A779F0) SoC and R-Car Gen4.
> >
> > Signed-off-by: Yoshihiro Shimoda 
> 
> Thanks for your patch!
> 
> > --- a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.yaml
> > +++ b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.yaml
> > @@ -44,6 +44,10 @@ properties:
> >- renesas,ipmmu-r8a77990 # R-Car E3
> >- renesas,ipmmu-r8a77995 # R-Car D3
> >- renesas,ipmmu-r8a779a0 # R-Car V3U
> > +  - items:
> > +  - enum:
> > +  - renesas,ipmmu-r8a779f0 # R-Car S4-8
> > +  - const: renesas,rcar-gen4-ipmmu-vmsa  # R-Car Gen4
> 
> I'm wondering if we need the family-specific fallback.
> For R-Car Gen3, we don't have it, and match on (all) the SoC-specific
> compatible values instead.
> Do you remember why we decided to do it that way?

I'm afraid I don't. You know my usual opinion of SoC-specific compatible
strings :-)

> At least R-Car V3M/V3H/D3 have slight differences in the register bits,
> but I don't think that was the reason.

-- 
Regards,

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


Re: [PATCH] dt-bindings: More dropping redundant minItems/maxItems

2021-07-14 Thread Laurent Pinchart
Hi Rob,

Thank you for the patch.

On Tue, Jul 13, 2021 at 01:34:53PM -0600, Rob Herring wrote:
> Another round of removing redundant minItems/maxItems from new schema in
> the recent merge window.
> 
> If a property has an 'items' list, then a 'minItems' or 'maxItems' with the
> same size as the list is redundant and can be dropped. Note that is DT
> schema specific behavior and not standard json-schema behavior. The tooling
> will fixup the final schema adding any unspecified minItems/maxItems.
> 
> This condition is partially checked with the meta-schema already, but
> only if both 'minItems' and 'maxItems' are equal to the 'items' length.
> An improved meta-schema is pending.
> 
> Cc: Stephen Boyd 
> Cc: Joerg Roedel 
> Cc: Will Deacon 
> Cc: Krzysztof Kozlowski 
> Cc: Miquel Raynal 
> Cc: Richard Weinberger 
> Cc: Vignesh Raghavendra 
> Cc: Alessandro Zummo 
> Cc: Alexandre Belloni 
> Cc: Greg Kroah-Hartman 
> Cc: Sureshkumar Relli 
> Cc: Brian Norris 
> Cc: Kamal Dasu 
> Cc: Linus Walleij 
> Cc: Sebastian Siewior 
> Cc: Laurent Pinchart 
> Cc: linux-...@vger.kernel.org
> Cc: iommu@lists.linux-foundation.org
> Cc: linux-...@lists.infradead.org
> Cc: linux-...@vger.kernel.org
> Cc: linux-...@vger.kernel.org
> Signed-off-by: Rob Herring 

Reviewed-by: Laurent Pinchart 

> ---
>  .../devicetree/bindings/clock/brcm,iproc-clocks.yaml  | 1 -
>  .../devicetree/bindings/iommu/rockchip,iommu.yaml | 2 --
>  .../bindings/memory-controllers/arm,pl353-smc.yaml| 1 -
>  Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml  | 8 
>  .../devicetree/bindings/rtc/faraday,ftrtc010.yaml | 1 -
>  Documentation/devicetree/bindings/usb/nxp,isp1760.yaml| 2 --
>  6 files changed, 15 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.yaml 
> b/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.yaml
> index 8dc7b404ee12..1174c9aa9934 100644
> --- a/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.yaml
> +++ b/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.yaml
> @@ -50,7 +50,6 @@ properties:
>  
>reg:
>  minItems: 1
> -maxItems: 3
>  items:
>- description: base register
>- description: power register
> diff --git a/Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml 
> b/Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml
> index d2e28a9e3545..ba9124f721f1 100644
> --- a/Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml
> +++ b/Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml
> @@ -28,14 +28,12 @@ properties:
>- description: configuration registers for MMU instance 0
>- description: configuration registers for MMU instance 1
>  minItems: 1
> -maxItems: 2
>  
>interrupts:
>  items:
>- description: interruption for MMU instance 0
>- description: interruption for MMU instance 1
>  minItems: 1
> -maxItems: 2
>  
>clocks:
>  items:
> diff --git 
> a/Documentation/devicetree/bindings/memory-controllers/arm,pl353-smc.yaml 
> b/Documentation/devicetree/bindings/memory-controllers/arm,pl353-smc.yaml
> index 7a63c85ef8c5..01c9acf9275d 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/arm,pl353-smc.yaml
> +++ b/Documentation/devicetree/bindings/memory-controllers/arm,pl353-smc.yaml
> @@ -57,7 +57,6 @@ properties:
>  
>ranges:
>  minItems: 1
> -maxItems: 3
>  description: |
>Memory bus areas for interacting with the devices. Reflects
>the memory layout with four integer values following:
> diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml 
> b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> index e5f1a2a5..dd5a64969e37 100644
> --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> @@ -84,7 +84,6 @@ properties:
>  
>interrupts:
>  minItems: 1
> -maxItems: 3
>  items:
>- description: NAND CTLRDY interrupt
>- description: FLASH_DMA_DONE if flash DMA is available
> @@ -92,7 +91,6 @@ properties:
>  
>interrupt-names:
>  minItems: 1
> -maxItems: 3
>  items:
>- const: nand_ctlrdy
>- const: flash_dma_done
> @@ -148,8 +146,6 @@ allOf:
>  then:
>properties:
>  reg-names:
> -  minItems: 2
> -  maxItems: 2
>items:
>  - const: nand
>  - const: nand-int-base
> @@ -161,8 +157,6 @@ allOf:
>  then:
>properties:
>  reg-names:
> - 

Re: [PATCH v3 6/6] media: uvcvideo: Use dma_alloc_noncontiguous API

2021-03-12 Thread Laurent Pinchart
Hi Ricardo,

Thank you for the patch.

On Fri, Mar 12, 2021 at 11:25:39PM +0100, Ricardo Ribalda wrote:
> On architectures where there is no coherent caching such as ARM use the
> dma_alloc_noncontiguous API and handle manually the cache flushing using
> dma_sync_sgtable().

Maybe updating this based on the comment I've just sent in the v2 thread
?

> With this patch on the affected architectures we can measure up to 20x
> performance improvement in uvc_video_copy_data_work().
> 
> Eg: aarch64 with an external usb camera
> 
> NON_CONTIGUOUS
> frames:  999
> packets: 999
> empty:   0 (0 %)
> errors:  0
> invalid: 0
> pts: 0 early, 0 initial, 999 ok
> scr: 0 count ok, 0 diff ok
> sof: 2048 <= sof <= 0, freq 0.000 kHz
> bytes 67034480 : duration 33303
> FPS: 29.99
> URB: 523446/4993 uS/qty: 104.836 avg 132.532 std 13.230 min 831.094 max (uS)
> header: 76564/4993 uS/qty: 15.334 avg 15.229 std 3.438 min 186.875 max (uS)
> latency: 468945/4992 uS/qty: 93.939 avg 132.577 std 9.531 min 824.010 max (uS)
> decode: 54161/4993 uS/qty: 10.847 avg 6.313 std 1.614 min 111.458 max (uS)
> raw decode speed: 9.931 Gbits/s
> raw URB handling speed: 1.025 Gbits/s
> throughput: 16.102 Mbits/s
> URB decode CPU usage 0.162600 %
> 
> COHERENT
> frames:  999
> packets: 999
> empty:   0 (0 %)
> errors:  0
> invalid: 0
> pts: 0 early, 0 initial, 999 ok
> scr: 0 count ok, 0 diff ok
> sof: 2048 <= sof <= 0, freq 0.000 kHz
> bytes 54683536 : duration 33302
> FPS: 29.99
> URB: 1478135/4000 uS/qty: 369.533 avg 390.357 std 22.968 min 3337.865 max (uS)
> header: 79761/4000 uS/qty: 19.940 avg 18.495 std 1.875 min 336.719 max (uS)
> latency: 281077/4000 uS/qty: 70.269 avg 83.102 std 5.104 min 735.000 max (uS)
> decode: 1197057/4000 uS/qty: 299.264 avg 318.080 std 1.615 min 2806.667 max 
> (uS)
> raw decode speed: 365.470 Mbits/s
> raw URB handling speed: 295.986 Mbits/s
> throughput: 13.136 Mbits/s
> URB decode CPU usage 3.594500 %
> 
> In non-affected architectures we see no significant impact.
> 
> Eg: x86 with an external usb camera
> 
> NON_CONTIGUOUS
> frames:  999
> packets: 999
> empty:   0 (0 %)
> errors:  0
> invalid: 0
> pts: 0 early, 0 initial, 999 ok
> scr: 0 count ok, 0 diff ok
> sof: 2048 <= sof <= 0, freq 0.000 kHz
> bytes 70179056 : duration 33301
> FPS: 29.99
> URB: 288901/4897 uS/qty: 58.995 avg 26.022 std 4.319 min 253.853 max (uS)
> header: 54792/4897 uS/qty: 11.189 avg 6.218 std 0.620 min 61.750 max (uS)
> latency: 236602/4897 uS/qty: 48.315 avg 24.244 std 1.764 min 240.924 max (uS)
> decode: 52298/4897 uS/qty: 10.679 avg 8.299 std 1.638 min 108.861 max (uS)
> raw decode speed: 10.796 Gbits/s
> raw URB handling speed: 1.949 Gbits/s
> throughput: 16.859 Mbits/s
> URB decode CPU usage 0.157000 %
> 
> COHERENT
> frames:  999
> packets: 999
> empty:   0 (0 %)
> errors:  0
> invalid: 0
> pts: 0 early, 0 initial, 999 ok
> scr: 0 count ok, 0 diff ok
> sof: 2048 <= sof <= 0, freq 0.000 kHz
> bytes 71818320 : duration 33301
> FPS: 29.99
> URB: 321021/5000 uS/qty: 64.204 avg 23.001 std 10.430 min 268.837 max (uS)
> header: 54308/5000 uS/qty: 10.861 avg 5.104 std 0.778 min 54.736 max (uS)
> latency: 268799/5000 uS/qty: 53.759 avg 21.827 std 6.095 min 255.153 max (uS)
> decode: 5/5000 uS/qty: 10.444 avg 7.137 std 1.874 min 71.103 max (uS)
> raw decode speed: 11.048 Gbits/s
> raw URB handling speed: 1.789 Gbits/s
> throughput: 17.253 Mbits/s
> URB decode CPU usage 0.156800 %
> 
> Signed-off-by: Ricardo Ribalda 
> Reviewed-by: Laurent Pinchart 
> Reviewed-by: Tomasz Figa 
> Signed-off-by: Christoph Hellwig 
> ---
> 
> Changelog from v2 (Thanks Laurent!):
> 
> - Replace uvc_urb_dma_sync with uvc_submit_urb
> - Add x86 stats in commit message
> 
>  drivers/media/usb/uvc/uvc_video.c | 92 ++-
>  drivers/media/usb/uvc/uvcvideo.h  |  5 +-
>  2 files changed, 71 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_video.c 
> b/drivers/media/usb/uvc/uvc_video.c
> index f2f565281e63..37ee39412b83 100644
> --- a/drivers/media/usb/uvc/uvc_video.c
> +++ b/drivers/media/usb/uvc/uvc_video.c
> @@ -6,11 +6,14 @@
>   *  Laurent Pinchart (laurent.pinch...@ideasonboard.com)
>   */
>  
> +#include 
> +#include 
>  #include 
>  #include 
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -1096,6 +1099,28 @@ static int uvc_video_decode_start(struct uvc_streaming 
> *stream,
>   return data[0];
>  }
>  
> +static inline enum dma_data_direction stream_dir(struct uvc_streaming 
> *stream)

I hadn't noticed this before, but 

Re: [PATCH v2 6/6] media: uvcvideo: Use dma_alloc_noncontiguous API

2021-03-12 Thread Laurent Pinchart
Hi Ricardo,

On Fri, Mar 12, 2021 at 11:15:46PM +0100, Ricardo Ribalda Delgado wrote:
> On Fri, Mar 12, 2021 at 10:19 PM Laurent Pinchart wrote:
> > On Fri, Mar 12, 2021 at 01:57:09PM +0100, Ricardo Ribalda wrote:
> > > On architectures where there is no coherent caching such as ARM use the
> > > dma_alloc_noncontiguous API and handle manually the cache flushing using
> > > dma_sync_sgtable().
> >
> > You're actually switching to dma_alloc_noncontiguous() unconditionally,
> > not only on those architectures :-) Do I assume correctly that
> > dma_alloc_noncontiguous() will do the right thing on x86 too ?
> 
> Yes dma_alloc_noncontiguous does all the magic. It falls back to
> alloc_dma_pages. Christoph has done a great job.

It's a really nice work yes.

Maybe the commit message could be reworded accordingly then, to
explain that we switch to dma_alloc_noncontiguous() unconditionally as
it handles the differences behind the scenes ?

> I tried it in my notebook and although the images are nothing but
> pretty it is not the APIs fault. It is because the barbers are closed
> due to the pandemic ;).

:-)

> > > With this patch on the affected architectures we can measure up to 20x
> > > performance improvement in uvc_video_copy_data_work().
> >
> > Have you measured performances on x86 to ensure there's no regression ?
> 
> Yes in the early stages. I am adding the latest x86 measurements in
> the commit message in v3 to make it more clear.
> 
> > > Eg: aarch64 with an external usb camera
> > >
> > > NON_CONTIGUOUS
> > > frames:  999
> > > packets: 999
> > > empty:   0 (0 %)
> > > errors:  0
> > > invalid: 0
> > > pts: 0 early, 0 initial, 999 ok
> > > scr: 0 count ok, 0 diff ok
> > > sof: 2048 <= sof <= 0, freq 0.000 kHz
> > > bytes 67034480 : duration 33303
> > > FPS: 29.99
> > > URB: 523446/4993 uS/qty: 104.836 avg 132.532 std 13.230 min 831.094 max 
> > > (uS)
> > > header: 76564/4993 uS/qty: 15.334 avg 15.229 std 3.438 min 186.875 max 
> > > (uS)
> > > latency: 468945/4992 uS/qty: 93.939 avg 132.577 std 9.531 min 824.010 max 
> > > (uS)
> > > decode: 54161/4993 uS/qty: 10.847 avg 6.313 std 1.614 min 111.458 max (uS)
> > > raw decode speed: 9.931 Gbits/s
> > > raw URB handling speed: 1.025 Gbits/s
> > > throughput: 16.102 Mbits/s
> > > URB decode CPU usage 0.162600 %
> > >
> > > COHERENT
> > > frames:  999
> > > packets: 999
> > > empty:   0 (0 %)
> > > errors:  0
> > > invalid: 0
> > > pts: 0 early, 0 initial, 999 ok
> > > scr: 0 count ok, 0 diff ok
> > > sof: 2048 <= sof <= 0, freq 0.000 kHz
> > > bytes 54683536 : duration 33302
> > > FPS: 29.99
> > > URB: 1478135/4000 uS/qty: 369.533 avg 390.357 std 22.968 min 3337.865 max 
> > > (uS)
> > > header: 79761/4000 uS/qty: 19.940 avg 18.495 std 1.875 min 336.719 max 
> > > (uS)
> > > latency: 281077/4000 uS/qty: 70.269 avg 83.102 std 5.104 min 735.000 max 
> > > (uS)
> > > decode: 1197057/4000 uS/qty: 299.264 avg 318.080 std 1.615 min 2806.667 
> > > max (uS)
> > > raw decode speed: 365.470 Mbits/s
> > > raw URB handling speed: 295.986 Mbits/s
> > > throughput: 13.136 Mbits/s
> > > URB decode CPU usage 3.594500 %
> > >
> > > Signed-off-by: Ricardo Ribalda 
> > > Reviewed-by: Tomasz Figa 
> > > Signed-off-by: Christoph Hellwig 
> > > ---
> > >
> > > Changelog from v2: (Thanks Laurent)
> > >
> > > - Fix typos
> > > - Use the right dma direction if not capturing
> > > - Clear sgt during free
> > >
> > >  drivers/media/usb/uvc/uvc_video.c | 92 +++
> > >  drivers/media/usb/uvc/uvcvideo.h  |  5 +-
> > >  2 files changed, 74 insertions(+), 23 deletions(-)
> > >
> > > diff --git a/drivers/media/usb/uvc/uvc_video.c 
> > > b/drivers/media/usb/uvc/uvc_video.c
> > > index f2f565281e63..8e60f81e2257 100644
> > > --- a/drivers/media/usb/uvc/uvc_video.c
> > > +++ b/drivers/media/usb/uvc/uvc_video.c
> > > @@ -6,11 +6,14 @@
> > >   *  Laurent Pinchart (laurent.pinch...@ideasonboard.com)
> > >   */
> > >
> > > +#include 
> > > +#include 
> > >  #include 
> > >  #include 
> > >  #include 
> > >  #include 
> > >  #include 
> > > +#include 
> > >  #include 
> > >  #inclu

Re: [PATCH v2 6/6] media: uvcvideo: Use dma_alloc_noncontiguous API

2021-03-12 Thread Laurent Pinchart
Hi Ricardo,

Thank you for the patch.

On Fri, Mar 12, 2021 at 01:57:09PM +0100, Ricardo Ribalda wrote:
> On architectures where there is no coherent caching such as ARM use the
> dma_alloc_noncontiguous API and handle manually the cache flushing using
> dma_sync_sgtable().

You're actually switching to dma_alloc_noncontiguous() unconditionally,
not only on those architectures :-) Do I assume correctly that
dma_alloc_noncontiguous() will do the right thing on x86 too ?

> With this patch on the affected architectures we can measure up to 20x
> performance improvement in uvc_video_copy_data_work().

Have you measured performances on x86 to ensure there's no regression ?

> Eg: aarch64 with an external usb camera
> 
> NON_CONTIGUOUS
> frames:  999
> packets: 999
> empty:   0 (0 %)
> errors:  0
> invalid: 0
> pts: 0 early, 0 initial, 999 ok
> scr: 0 count ok, 0 diff ok
> sof: 2048 <= sof <= 0, freq 0.000 kHz
> bytes 67034480 : duration 33303
> FPS: 29.99
> URB: 523446/4993 uS/qty: 104.836 avg 132.532 std 13.230 min 831.094 max (uS)
> header: 76564/4993 uS/qty: 15.334 avg 15.229 std 3.438 min 186.875 max (uS)
> latency: 468945/4992 uS/qty: 93.939 avg 132.577 std 9.531 min 824.010 max (uS)
> decode: 54161/4993 uS/qty: 10.847 avg 6.313 std 1.614 min 111.458 max (uS)
> raw decode speed: 9.931 Gbits/s
> raw URB handling speed: 1.025 Gbits/s
> throughput: 16.102 Mbits/s
> URB decode CPU usage 0.162600 %
> 
> COHERENT
> frames:  999
> packets: 999
> empty:   0 (0 %)
> errors:  0
> invalid: 0
> pts: 0 early, 0 initial, 999 ok
> scr: 0 count ok, 0 diff ok
> sof: 2048 <= sof <= 0, freq 0.000 kHz
> bytes 54683536 : duration 33302
> FPS: 29.99
> URB: 1478135/4000 uS/qty: 369.533 avg 390.357 std 22.968 min 3337.865 max (uS)
> header: 79761/4000 uS/qty: 19.940 avg 18.495 std 1.875 min 336.719 max (uS)
> latency: 281077/4000 uS/qty: 70.269 avg 83.102 std 5.104 min 735.000 max (uS)
> decode: 1197057/4000 uS/qty: 299.264 avg 318.080 std 1.615 min 2806.667 max 
> (uS)
> raw decode speed: 365.470 Mbits/s
> raw URB handling speed: 295.986 Mbits/s
> throughput: 13.136 Mbits/s
> URB decode CPU usage 3.594500 %
> 
> Signed-off-by: Ricardo Ribalda 
> Reviewed-by: Tomasz Figa 
> Signed-off-by: Christoph Hellwig 
> ---
> 
> Changelog from v2: (Thanks Laurent)
> 
> - Fix typos
> - Use the right dma direction if not capturing
> - Clear sgt during free
> 
>  drivers/media/usb/uvc/uvc_video.c | 92 +++
>  drivers/media/usb/uvc/uvcvideo.h  |  5 +-
>  2 files changed, 74 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_video.c 
> b/drivers/media/usb/uvc/uvc_video.c
> index f2f565281e63..8e60f81e2257 100644
> --- a/drivers/media/usb/uvc/uvc_video.c
> +++ b/drivers/media/usb/uvc/uvc_video.c
> @@ -6,11 +6,14 @@
>   *  Laurent Pinchart (laurent.pinch...@ideasonboard.com)
>   */
>  
> +#include 
> +#include 
>  #include 
>  #include 
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -1096,6 +1099,34 @@ static int uvc_video_decode_start(struct uvc_streaming 
> *stream,
>   return data[0];
>  }
>  
> +static inline enum dma_data_direction stream_dir(struct uvc_streaming 
> *stream)
> +{
> + if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
> + return DMA_FROM_DEVICE;
> + else
> + return DMA_TO_DEVICE;
> +}
> +
> +static inline struct device *stream_to_dmadev(struct uvc_streaming *stream)
> +{
> + return bus_to_hcd(stream->dev->udev->bus)->self.sysdev;
> +}
> +
> +static void uvc_urb_dma_sync(struct uvc_urb *uvc_urb, bool for_device)

Maybe nitpicking a little bit, but wouldn't the code be clearer if you
created uvc_urb_dma_sync_for_cpu() and uvc_urb_dma_sync_for_device() ?
When reading

uvc_urb_dma_sync(uvc_urb, true);

I have to constantly look up the definition of the function to figure
out what boolean value corresponds to what direction.

Given that uvc_urb_dma_sync(..., true) is always called right before
submitting the URB, we could even create a uvc_submit_urb() function
that groups the dma_sync_sgtable_for_device() and usb_submit_urb()
calls, and do without uvc_urb_dma_sync_for_device(). Up to you on this
one.

With those small changes, and assuming there's no performance regression
on x86,

Reviewed-by: Laurent Pinchart 

> +{
> + struct device *dma_dev = stream_to_dmadev(uvc_urb->stream);
> +
> + if (for_device) {
> + dma_sync_sgtable_for_device(dma_dev, uvc_urb->sgt,
> + stream_dir(uvc_urb->stream));
> + } else {
> + dma_sync_sgtable

Re: [PATCH 6/6] media: uvcvideo: Use dma_alloc_noncontiguos API

2021-03-11 Thread Laurent Pinchart
And I forgot to mention:

On Fri, Mar 12, 2021 at 03:42:14AM +0200, Laurent Pinchart wrote:
> Hi Christoph and Ricardo,
> 
> Thank you for the patch.
> 
> On Mon, Mar 01, 2021 at 09:52:36AM +0100, Christoph Hellwig wrote:
> > From: Ricardo Ribalda 
> > 
> > On architectures where the is no coherent caching such as ARM use the
> 
> s/the is/there is/
> 
> > dma_alloc_noncontiguos API and handle manually the cache flushing using
> 
> s/dma_alloc_noncontiguos/dma_alloc_noncontiguous/
> 
> (and in the subject line too)
> 
> > dma_sync_sgtable().
> > 
> > With this patch on the affected architectures we can measure up to 20x
> > performance improvement in uvc_video_copy_data_work().

Wow, great work ! :-)

> > 
> > Eg: aarch64 with an external usb camera
> > 
> > NON_CONTIGUOUS
> > frames:  999
> > packets: 999
> > empty:   0 (0 %)
> > errors:  0
> > invalid: 0
> > pts: 0 early, 0 initial, 999 ok
> > scr: 0 count ok, 0 diff ok
> > sof: 2048 <= sof <= 0, freq 0.000 kHz
> > bytes 67034480 : duration 33303
> > FPS: 29.99
> > URB: 523446/4993 uS/qty: 104.836 avg 132.532 std 13.230 min 831.094 max (uS)
> > header: 76564/4993 uS/qty: 15.334 avg 15.229 std 3.438 min 186.875 max (uS)
> > latency: 468945/4992 uS/qty: 93.939 avg 132.577 std 9.531 min 824.010 max 
> > (uS)
> > decode: 54161/4993 uS/qty: 10.847 avg 6.313 std 1.614 min 111.458 max (uS)
> > raw decode speed: 9.931 Gbits/s
> > raw URB handling speed: 1.025 Gbits/s
> > throughput: 16.102 Mbits/s
> > URB decode CPU usage 0.162600 %
> > 
> > COHERENT
> > frames:  999
> > packets: 999
> > empty:   0 (0 %)
> > errors:  0
> > invalid: 0
> > pts: 0 early, 0 initial, 999 ok
> > scr: 0 count ok, 0 diff ok
> > sof: 2048 <= sof <= 0, freq 0.000 kHz
> > bytes 54683536 : duration 33302
> > FPS: 29.99
> > URB: 1478135/4000 uS/qty: 369.533 avg 390.357 std 22.968 min 3337.865 max 
> > (uS)
> > header: 79761/4000 uS/qty: 19.940 avg 18.495 std 1.875 min 336.719 max (uS)
> > latency: 281077/4000 uS/qty: 70.269 avg 83.102 std 5.104 min 735.000 max 
> > (uS)
> > decode: 1197057/4000 uS/qty: 299.264 avg 318.080 std 1.615 min 2806.667 max 
> > (uS)
> > raw decode speed: 365.470 Mbits/s
> > raw URB handling speed: 295.986 Mbits/s
> > throughput: 13.136 Mbits/s
> > URB decode CPU usage 3.594500 %
> > 
> > Signed-off-by: Ricardo Ribalda 
> > Reviewed-by: Tomasz Figa 
> > Signed-off-by: Christoph Hellwig 
> > ---
> >  drivers/media/usb/uvc/uvc_video.c | 79 ++++++-
> >  drivers/media/usb/uvc/uvcvideo.h  |  4 +-
> >  2 files changed, 60 insertions(+), 23 deletions(-)
> > 
> > diff --git a/drivers/media/usb/uvc/uvc_video.c 
> > b/drivers/media/usb/uvc/uvc_video.c
> > index f2f565281e63ff..d008c68fb6c806 100644
> > --- a/drivers/media/usb/uvc/uvc_video.c
> > +++ b/drivers/media/usb/uvc/uvc_video.c
> > @@ -6,11 +6,13 @@
> >   *  Laurent Pinchart (laurent.pinch...@ideasonboard.com)
> >   */
> >  
> 
> Should we include  ?
> 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -1096,6 +1098,26 @@ static int uvc_video_decode_start(struct 
> > uvc_streaming *stream,
> > return data[0];
> >  }
> >  
> > +static inline struct device *stream_to_dmadev(struct uvc_streaming *stream)
> > +{
> > +   return bus_to_hcd(stream->dev->udev->bus)->self.sysdev;
> > +}
> > +
> > +static void uvc_urb_dma_sync(struct uvc_urb *uvc_urb, bool for_device)
> > +{
> > +   struct device *dma_dev = stream_to_dmadev(uvc_urb->stream);
> > +
> > +   if (for_device) {
> > +   dma_sync_sgtable_for_device(dma_dev, uvc_urb->sgt,
> > +   DMA_FROM_DEVICE);
> 
> The uvcvideo driver also supports video output devices (they are fairly
> rare, but they exist). We thus need to handle DMA_TO_DEVICE too.
> 
> > +   } else {
> > +   dma_sync_sgtable_for_cpu(dma_dev, uvc_urb->sgt,
> > +DMA_FROM_DEVICE);
> > +   invalidate_kernel_vmap_range(uvc_urb->buffer,
> > +uvc_urb->stream->urb_size);
> > +   }
> > +}
> > +
> >  /*
> >   * uvc_video_decode_data_work: Asynchronous memcpy processing
>

Re: [PATCH 6/6] media: uvcvideo: Use dma_alloc_noncontiguos API

2021-03-11 Thread Laurent Pinchart
Hi Christoph and Ricardo,

Thank you for the patch.

On Mon, Mar 01, 2021 at 09:52:36AM +0100, Christoph Hellwig wrote:
> From: Ricardo Ribalda 
> 
> On architectures where the is no coherent caching such as ARM use the

s/the is/there is/

> dma_alloc_noncontiguos API and handle manually the cache flushing using

s/dma_alloc_noncontiguos/dma_alloc_noncontiguous/

(and in the subject line too)

> dma_sync_sgtable().
> 
> With this patch on the affected architectures we can measure up to 20x
> performance improvement in uvc_video_copy_data_work().
> 
> Eg: aarch64 with an external usb camera
> 
> NON_CONTIGUOUS
> frames:  999
> packets: 999
> empty:   0 (0 %)
> errors:  0
> invalid: 0
> pts: 0 early, 0 initial, 999 ok
> scr: 0 count ok, 0 diff ok
> sof: 2048 <= sof <= 0, freq 0.000 kHz
> bytes 67034480 : duration 33303
> FPS: 29.99
> URB: 523446/4993 uS/qty: 104.836 avg 132.532 std 13.230 min 831.094 max (uS)
> header: 76564/4993 uS/qty: 15.334 avg 15.229 std 3.438 min 186.875 max (uS)
> latency: 468945/4992 uS/qty: 93.939 avg 132.577 std 9.531 min 824.010 max (uS)
> decode: 54161/4993 uS/qty: 10.847 avg 6.313 std 1.614 min 111.458 max (uS)
> raw decode speed: 9.931 Gbits/s
> raw URB handling speed: 1.025 Gbits/s
> throughput: 16.102 Mbits/s
> URB decode CPU usage 0.162600 %
> 
> COHERENT
> frames:  999
> packets: 999
> empty:   0 (0 %)
> errors:  0
> invalid: 0
> pts: 0 early, 0 initial, 999 ok
> scr: 0 count ok, 0 diff ok
> sof: 2048 <= sof <= 0, freq 0.000 kHz
> bytes 54683536 : duration 33302
> FPS: 29.99
> URB: 1478135/4000 uS/qty: 369.533 avg 390.357 std 22.968 min 3337.865 max (uS)
> header: 79761/4000 uS/qty: 19.940 avg 18.495 std 1.875 min 336.719 max (uS)
> latency: 281077/4000 uS/qty: 70.269 avg 83.102 std 5.104 min 735.000 max (uS)
> decode: 1197057/4000 uS/qty: 299.264 avg 318.080 std 1.615 min 2806.667 max 
> (uS)
> raw decode speed: 365.470 Mbits/s
> raw URB handling speed: 295.986 Mbits/s
> throughput: 13.136 Mbits/s
> URB decode CPU usage 3.594500 %
> 
> Signed-off-by: Ricardo Ribalda 
> Reviewed-by: Tomasz Figa 
> Signed-off-by: Christoph Hellwig 
> ---
>  drivers/media/usb/uvc/uvc_video.c | 79 ++-
>  drivers/media/usb/uvc/uvcvideo.h  |  4 +-
>  2 files changed, 60 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_video.c 
> b/drivers/media/usb/uvc/uvc_video.c
> index f2f565281e63ff..d008c68fb6c806 100644
> --- a/drivers/media/usb/uvc/uvc_video.c
> +++ b/drivers/media/usb/uvc/uvc_video.c
> @@ -6,11 +6,13 @@
>   *  Laurent Pinchart (laurent.pinch...@ideasonboard.com)
>   */
>  

Should we include  ?

> +#include 
>  #include 
>  #include 
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -1096,6 +1098,26 @@ static int uvc_video_decode_start(struct uvc_streaming 
> *stream,
>   return data[0];
>  }
>  
> +static inline struct device *stream_to_dmadev(struct uvc_streaming *stream)
> +{
> + return bus_to_hcd(stream->dev->udev->bus)->self.sysdev;
> +}
> +
> +static void uvc_urb_dma_sync(struct uvc_urb *uvc_urb, bool for_device)
> +{
> + struct device *dma_dev = stream_to_dmadev(uvc_urb->stream);
> +
> + if (for_device) {
> + dma_sync_sgtable_for_device(dma_dev, uvc_urb->sgt,
> + DMA_FROM_DEVICE);

The uvcvideo driver also supports video output devices (they are fairly
rare, but they exist). We thus need to handle DMA_TO_DEVICE too.

> + } else {
> + dma_sync_sgtable_for_cpu(dma_dev, uvc_urb->sgt,
> +  DMA_FROM_DEVICE);
> + invalidate_kernel_vmap_range(uvc_urb->buffer,
> +  uvc_urb->stream->urb_size);
> + }
> +}
> +
>  /*
>   * uvc_video_decode_data_work: Asynchronous memcpy processing
>   *
> @@ -1117,6 +1139,8 @@ static void uvc_video_copy_data_work(struct work_struct 
> *work)
>   uvc_queue_buffer_release(op->buf);
>   }
>  
> + uvc_urb_dma_sync(uvc_urb, true);
> +
>   ret = usb_submit_urb(uvc_urb->urb, GFP_KERNEL);
>   if (ret < 0)
>   dev_err(_urb->stream->intf->dev,
> @@ -1541,10 +1565,12 @@ static void uvc_video_complete(struct urb *urb)
>* Process the URB headers, and optionally queue expensive memcpy tasks
>* to be deferred to a work queue.
>*/
> + uvc_urb_dma_sync(uvc_urb, false);
>   stream->decode(uvc_urb, buf, buf_meta);
>  
>   /* If no async work is needed, resubmit the URB immediately. *

Re: add a new dma_alloc_noncontiguous API v2

2021-02-11 Thread Laurent Pinchart
Hi Ricardo,

On Thu, Feb 11, 2021 at 02:20:30PM +0100, Ricardo Ribalda wrote:
> On Thu, Feb 11, 2021 at 2:06 PM Christoph Hellwig  wrote:
> > On Thu, Feb 11, 2021 at 10:08:18AM +0100, Ricardo Ribalda wrote:
> > > Hi Christoph
> > >
> > > What are your merge plans for the uvc change?
> > > http://git.infradead.org/users/hch/dma-mapping.git/commit/3dc47131f8aacc2093f68a9971d24c754e435520
> > >
> > > Are you going to remove the patch on your Merge request and then send
> > > it for review to Laurent? or merge it through your tree with a S-o-B
> > > him?
> >
> > I though I had all the ACKs to queue it up.  Is that not what was
> > intended?  Queueing up the API without a user is generally a bad idea.
> >
> 
> I am pretty sure we need the ack from Laurent. He maintains uvc
> 
> @Laurent Pinchart what are your thoughts?

I think it would have been nice to CC me on the patch in the first place
:-) I won't have time to review the series before next week at the
earliest.

-- 
Regards,

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


Re: [PATCH v5 29/38] drm: rcar-du: fix common struct sg_table related issues

2020-05-13 Thread Laurent Pinchart
Hi Marek,

Thank you for the patch.

On Wed, May 13, 2020 at 03:32:36PM +0200, Marek Szyprowski wrote:
> The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function
> returns the number of the created entries in the DMA address space.
> However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and
> dma_unmap_sg must be called with the original number of the entries
> passed to the dma_map_sg().
> 
> struct sg_table is a common structure used for describing a non-contiguous
> memory buffer, used commonly in the DRM and graphics subsystems. It
> consists of a scatterlist with memory pages and DMA addresses (sgl entry),
> as well as the number of scatterlist entries: CPU pages (orig_nents entry)
> and DMA mapped pages (nents entry).
> 
> It turned out that it was a common mistake to misuse nents and orig_nents
> entries, calling DMA-mapping functions with a wrong number of entries or
> ignoring the number of mapped entries returned by the dma_map_sg()
> function.
> 
> To avoid such issues, lets use a common dma-mapping wrappers operating
> directly on the struct sg_table objects and use scatterlist page
> iterators where possible. This, almost always, hides references to the
> nents and orig_nents entries, making the code robust, easier to follow
> and copy/paste safe.
> 
> dma_map_sgtable() function returns zero or an error code, so adjust the
> return value check for the vsp1_du_map_sg() function.
> 
> Signed-off-by: Marek Szyprowski 

This is a very nice simplification, I've always foudn the dma_map_sg API
cumbersome to use.

Reviewed-by: Laurent Pinchart 

I assume you will get the whole series merged in one go. If I need to
pick the patch up at any point, please let me know. Otherwise I'll wait
until I see it upstream, no reply needed :-)

> ---
> For more information, see '[PATCH v5 00/38] DRM: fix struct sg_table nents
> vs. orig_nents misuse' thread:
> https://lore.kernel.org/linux-iommu/20200513132114.6046-1-m.szyprow...@samsung.com/T/
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_vsp.c  | 3 +--
>  drivers/media/platform/vsp1/vsp1_drm.c | 8 
>  2 files changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> index 5e4faf2..2fc1816 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> @@ -197,9 +197,8 @@ int rcar_du_vsp_map_fb(struct rcar_du_vsp *vsp, struct 
> drm_framebuffer *fb,
>   goto fail;
>  
>   ret = vsp1_du_map_sg(vsp->vsp, sgt);
> - if (!ret) {
> + if (ret) {
>   sg_free_table(sgt);
> - ret = -ENOMEM;
>   goto fail;
>   }
>   }
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c 
> b/drivers/media/platform/vsp1/vsp1_drm.c
> index a4a45d6..86d5e3f 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -912,8 +912,8 @@ int vsp1_du_map_sg(struct device *dev, struct sg_table 
> *sgt)
>* skip cache sync. This will need to be revisited when support for
>* non-coherent buffers will be added to the DU driver.
>*/
> - return dma_map_sg_attrs(vsp1->bus_master, sgt->sgl, sgt->nents,
> - DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
> + return dma_map_sgtable(vsp1->bus_master, sgt, DMA_TO_DEVICE,
> +DMA_ATTR_SKIP_CPU_SYNC);
>  }
>  EXPORT_SYMBOL_GPL(vsp1_du_map_sg);
>  
> @@ -921,8 +921,8 @@ void vsp1_du_unmap_sg(struct device *dev, struct sg_table 
> *sgt)
>  {
>   struct vsp1_device *vsp1 = dev_get_drvdata(dev);
>  
> - dma_unmap_sg_attrs(vsp1->bus_master, sgt->sgl, sgt->nents,
> -DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
> + dma_unmap_sgtable(vsp1->bus_master, sgt, DMA_TO_DEVICE,
> +   DMA_ATTR_SKIP_CPU_SYNC);
>  }
>  EXPORT_SYMBOL_GPL(vsp1_du_unmap_sg);
>  

-- 
Regards,

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


Re: [PATCH] dma-mapping: remove dma_{alloc,free,mmap}_writecombine

2019-07-30 Thread Laurent Pinchart
Hi Christoph,

Thank you for the patch.

On Tue, Jul 30, 2019 at 09:18:49AM +0300, Christoph Hellwig wrote:
> We can already use DMA_ATTR_WRITE_COMBINE or the _wc prefixed version,
> so remove the third way of doing things.
> 
> Signed-off-by: Christoph Hellwig 
> ---
>  drivers/gpu/drm/omapdrm/dss/dispc.c | 11 +--
>  include/linux/dma-mapping.h |  9 -
>  2 files changed, 5 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c 
> b/drivers/gpu/drm/omapdrm/dss/dispc.c
> index 785c5546067a..c70f3246a552 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dispc.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
> @@ -4609,11 +4609,10 @@ static int dispc_errata_i734_wa_init(struct 
> dispc_device *dispc)
>   i734_buf.size = i734.ovli.width * i734.ovli.height *
>   color_mode_to_bpp(i734.ovli.fourcc) / 8;
>  
> - i734_buf.vaddr = dma_alloc_writecombine(>pdev->dev,
> - i734_buf.size, _buf.paddr,
> - GFP_KERNEL);
> + i734_buf.vaddr = dma_alloc_wc(>pdev->dev, i734_buf.size,
> + _buf.paddr, GFP_KERNEL);

I would have indented this line to match the rest. Apart from that,

Reviewed-by: Laurent Pinchart 

>   if (!i734_buf.vaddr) {
> - dev_err(>pdev->dev, "%s: dma_alloc_writecombine 
> failed\n",
> + dev_err(>pdev->dev, "%s: dma_alloc_wc failed\n",
>   __func__);
>   return -ENOMEM;
>   }
> @@ -4626,8 +4625,8 @@ static void dispc_errata_i734_wa_fini(struct 
> dispc_device *dispc)
>   if (!dispc->feat->has_gamma_i734_bug)
>   return;
>  
> - dma_free_writecombine(>pdev->dev, i734_buf.size, i734_buf.vaddr,
> -   i734_buf.paddr);
> + dma_free_wc(>pdev->dev, i734_buf.size, i734_buf.vaddr,
> + i734_buf.paddr);
>  }
>  
>  static void dispc_errata_i734_wa(struct dispc_device *dispc)
> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index f7d1eea32c78..633dae466097 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -786,9 +786,6 @@ static inline void *dma_alloc_wc(struct device *dev, 
> size_t size,
>  
>   return dma_alloc_attrs(dev, size, dma_addr, gfp, attrs);
>  }
> -#ifndef dma_alloc_writecombine
> -#define dma_alloc_writecombine dma_alloc_wc
> -#endif
>  
>  static inline void dma_free_wc(struct device *dev, size_t size,
>  void *cpu_addr, dma_addr_t dma_addr)
> @@ -796,9 +793,6 @@ static inline void dma_free_wc(struct device *dev, size_t 
> size,
>   return dma_free_attrs(dev, size, cpu_addr, dma_addr,
> DMA_ATTR_WRITE_COMBINE);
>  }
> -#ifndef dma_free_writecombine
> -#define dma_free_writecombine dma_free_wc
> -#endif
>  
>  static inline int dma_mmap_wc(struct device *dev,
> struct vm_area_struct *vma,
> @@ -808,9 +802,6 @@ static inline int dma_mmap_wc(struct device *dev,
>   return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size,
>     DMA_ATTR_WRITE_COMBINE);
>  }
> -#ifndef dma_mmap_writecombine
> -#define dma_mmap_writecombine dma_mmap_wc
> -#endif
>  
>  #ifdef CONFIG_NEED_DMA_MAP_STATE
>  #define DEFINE_DMA_UNMAP_ADDR(ADDR_NAME)dma_addr_t ADDR_NAME

-- 
Regards,

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


Re: [PATCH 7/7] iommu/ipmmu-vmsa: Add suspend/resume support

2019-02-20 Thread Laurent Pinchart
Hi Geert,

On Wed, Feb 20, 2019 at 05:05:49PM +0100, Geert Uytterhoeven wrote:
> On Wed, Feb 20, 2019 at 4:42 PM Laurent Pinchart wrote:
> > On Wed, Feb 20, 2019 at 04:05:31PM +0100, Geert Uytterhoeven wrote:
> >> During PSCI system suspend, R-Car Gen3 SoCs are powered down, and all
> >> IPMMU state is lost.  Hence after s2ram, devices wired behind an IPMMU,
> >> and configured to use it, will see their DMA operations hang.
> >>
> >> To fix this, restore all IPMMU contexts, and re-enable all active
> >> micro-TLBs during system resume.
> >>
> >> To avoid overhead on platforms not needing it, the resume code has a
> >> build time dependency on sleep and PSCI support, and a runtime
> >> dependency on PSCI.
> >>
> >> Signed-off-by: Geert Uytterhoeven 
> >> ---
> >> This patch takes a different approach than the BSP, which implements a
> >> bulk save/restore of all registers during system suspend/resume.
> >
> > I like this approach better too.
> 
> Thanks ;-)
> 
> >> --- a/drivers/iommu/ipmmu-vmsa.c
> >> +++ b/drivers/iommu/ipmmu-vmsa.c
> 
> >> @@ -58,6 +62,7 @@ struct ipmmu_vmsa_device {
> >>   spinlock_t lock;/* Protects ctx and 
> >> domains[] */
> >>   DECLARE_BITMAP(ctx, IPMMU_CTX_MAX);
> >>   struct ipmmu_vmsa_domain *domains[IPMMU_CTX_MAX];
> >> + s8 utlb_ctx[IPMMU_UTLB_MAX];
> >
> > How about making this a bitmask instead to save memory ? I would also
> > rename it as utlb_ctx doesn't really carry the meaning of the field,
> > whose purpose is to store whether the µTLB is enabled or disabled.
> 
> This field isn't just a binary flag, but stores the context used for the
> uTLB, so we can map from micro-TLB to context.
> Given there can be 8 contexts, plus the need to indicate unused contexts,
> that means 4 bits/micro-TLB.  So the overhead is just 24 bytes per IPMMU
> instance.

My bad, I've overlooked that.

> I considered allocating the array dynamically (by having s8 utlb_ctx[]
> at the end of the structure), but didn't go that route, as the domains[]
> array already uses more memory.
> 
> >> @@ -1158,10 +1166,52 @@ static int ipmmu_remove(struct platform_device 
> >> *pdev)
> >>   return 0;
> >>  }
> >>
> >> +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM_PSCI_FW)
> >> +static int ipmmu_resume_noirq(struct device *dev)
> >> +{
> >> + struct ipmmu_vmsa_device *mmu = dev_get_drvdata(dev);
> >> + unsigned int i;
> >> +
> >> + /* This is the best we can do to check for the presence of PSCI */
> >> + if (!psci_ops.cpu_suspend)
> >> + return 0;
> >
> > PSCI suspend disabling power to the SoC completely may be a common
> > behaviour on our development boards, but isn't mandated by the PSCI
> > specification if I'm not mistaken. Is there a way to instead detect that
> > power has been lost, perhaps by checking whether a register has been
> > reset to its default value ?
> 
> The approach here is the same as in the clk and pinctrl drivers.
> 
> I think we could check if the IMCTR registers for allocated domains in root
> IPMMUs are non-zero.  But that's about as expensive as doing the full
> restore, I think.

Would reading just one register be more expensive that full
reconfiguration ? Or is there no single register that could serve this
purpose ?

> And it may have to be done for each and every IPMMU instance, or do
> you trust caching for this?

If we can find a single register I think that reading it for every IPMMU
instance wouldn't be an issue.

> >> +
> >> + /* Reset root MMU and restore contexts */
> >
> > I think the rest of the code adds a period at the end of sentences in
> > comments.
> 
> The balance seems to be just under 50% ;-)
> 
> >> + if (ipmmu_is_root(mmu)) {
> >> + ipmmu_device_reset(mmu);
> >> +
> >> + for (i = 0; i < mmu->num_ctx; i++) {
> >> + if (!mmu->domains[i])
> >> + continue;
> >> +
> >> + ipmmu_context_init(mmu->domains[i]);
> >> + }
> >> + }
> >> +
> >> + /* Re-enable active micro-TLBs */
> >> + for (i = 0; i < mmu->features->num_utlbs; i++) {
> >> + if (mmu->utlb_ctx[i] == IPMMU_CTX_INVALID)
> >> + continue;
> >> +
> >> + ipmmu_u

Re: [PATCH 5/7] iommu/ipmmu-vmsa: Move num_utlbs to SoC-specific features

2019-02-20 Thread Laurent Pinchart
Hi Geert,

Thank you for the patch.

On Wed, Feb 20, 2019 at 04:05:29PM +0100, Geert Uytterhoeven wrote:
> The maximum number of micro-TLBs per IPMMU instance is not fixed, but
> depends on the SoC type.  Hence move it from struct ipmmu_vmsa_device to
> struct ipmmu_features, and set up the correct value for both R-Car Gen2
> and Gen3 SoCs.
> 
> Note that currently no code uses this value.
> 
> Signed-off-by: Geert Uytterhoeven 

Reviewed-by: Laurent Pinchart 

> ---
>  drivers/iommu/ipmmu-vmsa.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> index 4e3134a9a52f8d87..0a21e734466eb1bd 100644
> --- a/drivers/iommu/ipmmu-vmsa.c
> +++ b/drivers/iommu/ipmmu-vmsa.c
> @@ -42,6 +42,7 @@ struct ipmmu_features {
>   bool use_ns_alias_offset;
>   bool has_cache_leaf_nodes;
>   unsigned int number_of_contexts;
> + unsigned int num_utlbs;
>   bool setup_imbuscr;
>   bool twobit_imttbcr_sl0;
>   bool reserved_context;
> @@ -53,7 +54,6 @@ struct ipmmu_vmsa_device {
>   struct iommu_device iommu;
>   struct ipmmu_vmsa_device *root;
>   const struct ipmmu_features *features;
> - unsigned int num_utlbs;
>   unsigned int num_ctx;
>   spinlock_t lock;/* Protects ctx and domains[] */
>   DECLARE_BITMAP(ctx, IPMMU_CTX_MAX);
> @@ -972,6 +972,7 @@ static const struct ipmmu_features ipmmu_features_default 
> = {
>   .use_ns_alias_offset = true,
>   .has_cache_leaf_nodes = false,
>   .number_of_contexts = 1, /* software only tested with one context */
> + .num_utlbs = 32,
>   .setup_imbuscr = true,
>   .twobit_imttbcr_sl0 = false,
>   .reserved_context = false,
> @@ -981,6 +982,7 @@ static const struct ipmmu_features 
> ipmmu_features_rcar_gen3 = {
>   .use_ns_alias_offset = false,
>   .has_cache_leaf_nodes = true,
>   .number_of_contexts = 8,
> + .num_utlbs = 48,
>   .setup_imbuscr = false,
>   .twobit_imttbcr_sl0 = true,
>   .reserved_context = true,
> @@ -1033,7 +1035,6 @@ static int ipmmu_probe(struct platform_device *pdev)
>   }
>  
>   mmu->dev = >dev;
> -     mmu->num_utlbs = 48;
>   spin_lock_init(>lock);
>   bitmap_zero(mmu->ctx, IPMMU_CTX_MAX);
>   mmu->features = of_device_get_match_data(>dev);

-- 
Regards,

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


Re: [PATCH 7/7] iommu/ipmmu-vmsa: Add suspend/resume support

2019-02-20 Thread Laurent Pinchart
lb_ctx[i]], i);
> + }
> +
> + return 0;
> +}
> +
> +static const struct dev_pm_ops ipmmu_pm  = {
> + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(NULL, ipmmu_resume_noirq)
> +};
> +#define DEV_PM_OPS   _pm
> +#else
> +#define DEV_PM_OPS   NULL
> +#endif /* CONFIG_PM_SLEEP && CONFIG_ARM_PSCI_FW */
> +
>  static struct platform_driver ipmmu_driver = {
>   .driver = {
>   .name = "ipmmu-vmsa",
>   .of_match_table = of_match_ptr(ipmmu_of_ids),
> + .pm = DEV_PM_OPS,

I would have used conditional compilation here instead of using a
DEV_PM_OPS macro, as I think the macro decreases readability (and also
given how its generic name could later conflict with something else).

>   },
>   .probe = ipmmu_probe,
>   .remove = ipmmu_remove,

-- 
Regards,

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

Re: [PATCH 6/7] iommu/ipmmu-vmsa: Extract hardware context initialization

2019-02-20 Thread Laurent Pinchart
 ipmmu_domain_allocate_context(domain->mmu->root, domain);
> + if (ret < 0)
> +     return ret;
> +
> + domain->context_id = ret;
> +
> + domain->iop = alloc_io_pgtable_ops(ARM_32_LPAE_S1, >cfg,
> +domain);
> + if (!domain->iop) {
> + ipmmu_domain_free_context(domain->mmu->root,
> +   domain->context_id);
> + return -EINVAL;
> + }
>  
> + ipmmu_context_init(domain);
>   return 0;
>  }
>  

-- 
Regards,

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


Re: [PATCH 3/7] iommu/ipmmu-vmsa: Prepare to handle 40-bit error addresses

2019-02-20 Thread Laurent Pinchart
Hi Geert,

Thank you for the patch.

On Wed, Feb 20, 2019 at 04:05:27PM +0100, Geert Uytterhoeven wrote:
> On R-Car Gen3, the faulting virtual address is a 40-bit address, and
> comprised of two registers.  Read the upper address part, and combine
> both parts, when running on a 64-bit system.
> 
> Signed-off-by: Geert Uytterhoeven 
> ---
> Apart from this, the driver doesn't support 40-bit IOVA addresses yet.
> ---
>  drivers/iommu/ipmmu-vmsa.c | 16 ++--
>  1 file changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> index ac70cb967ff821c6..4d07c26c97848b65 100644
> --- a/drivers/iommu/ipmmu-vmsa.c
> +++ b/drivers/iommu/ipmmu-vmsa.c
> @@ -186,7 +186,9 @@ static struct ipmmu_vmsa_device *to_ipmmu(struct device 
> *dev)
>  #define IMMAIR_ATTR_IDX_WBRWA1
>  #define IMMAIR_ATTR_IDX_DEV  2
>  
> -#define IMEAR0x0030
> +#define IMEAR0x0030  /* R-Car Gen2 */
> +#define IMELAR   IMEAR   /* R-Car Gen3 */

I would have defined that as a single macro.

> +#define IMEUAR   0x0034  /* R-Car Gen3 */
>  
>  #define IMPCTR   0x0200
>  #define IMPSTR   0x0208
> @@ -521,14 +523,16 @@ static irqreturn_t ipmmu_domain_irq(struct 
> ipmmu_vmsa_domain *domain)
>  {
>   const u32 err_mask = IMSTR_MHIT | IMSTR_ABORT | IMSTR_PF | IMSTR_TF;
>   struct ipmmu_vmsa_device *mmu = domain->mmu;
> + unsigned long iova;

Isn't there a more appropriate type, such as dma_addr_t possibly ?

>   u32 status;
> - u32 iova;
>  
>   status = ipmmu_ctx_read_root(domain, IMSTR);
>   if (!(status & err_mask))
>   return IRQ_NONE;
>  
> - iova = ipmmu_ctx_read_root(domain, IMEAR);
> + iova = ipmmu_ctx_read_root(domain, IMELAR);
> + if (IS_ENABLED(CONFIG_64BIT))
> + iova |= (u64)ipmmu_ctx_read_root(domain, IMEUAR) << 32;
>  
>   /*
>* Clear the error status flags. Unlike traditional interrupt flag
> @@ -540,10 +544,10 @@ static irqreturn_t ipmmu_domain_irq(struct 
> ipmmu_vmsa_domain *domain)
>  
>   /* Log fatal errors. */
>   if (status & IMSTR_MHIT)
> - dev_err_ratelimited(mmu->dev, "Multiple TLB hits @0x%08x\n",
> + dev_err_ratelimited(mmu->dev, "Multiple TLB hits @0x%lx\n",
>   iova);
>   if (status & IMSTR_ABORT)
> - dev_err_ratelimited(mmu->dev, "Page Table Walk Abort @0x%08x\n",
> + dev_err_ratelimited(mmu->dev, "Page Table Walk Abort @0x%lx\n",
>   iova);
>  
>   if (!(status & (IMSTR_PF | IMSTR_TF)))
> @@ -559,7 +563,7 @@ static irqreturn_t ipmmu_domain_irq(struct 
> ipmmu_vmsa_domain *domain)
>   return IRQ_HANDLED;
>  
>   dev_err_ratelimited(mmu->dev,
> - "Unhandled fault: status 0x%08x iova 0x%08x\n",
> + "Unhandled fault: status 0x%08x iova 0x%lx\n",
>   status, iova);
>  
>   return IRQ_HANDLED;

-- 
Regards,

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


Re: [PATCH 4/7] iommu/ipmmu-vmsa: Make IPMMU_CTX_MAX unsigned

2019-02-20 Thread Laurent Pinchart
Hi Geert,

Thank you for the patch.

On Wed, Feb 20, 2019 at 04:05:28PM +0100, Geert Uytterhoeven wrote:
> Make the IPMMU_CTX_MAX constant unsigned, to match the type of
> ipmmu_features.number_of_contexts.
> 
> This allows to use plain min() instead of type-casting min_t().
> 
> Signed-off-by: Geert Uytterhoeven 

Reviewed-by: Laurent Pinchart 

> ---
>  drivers/iommu/ipmmu-vmsa.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> index 4d07c26c97848b65..4e3134a9a52f8d87 100644
> --- a/drivers/iommu/ipmmu-vmsa.c
> +++ b/drivers/iommu/ipmmu-vmsa.c
> @@ -36,7 +36,7 @@
>  #define arm_iommu_detach_device(...) do {} while (0)
>  #endif
>  
> -#define IPMMU_CTX_MAX 8
> +#define IPMMU_CTX_MAX 8U
>  
>  struct ipmmu_features {
>   bool use_ns_alias_offset;
> @@ -1060,8 +1060,7 @@ static int ipmmu_probe(struct platform_device *pdev)
>   if (mmu->features->use_ns_alias_offset)
>   mmu->base += IM_NS_ALIAS_OFFSET;
>  
> - mmu->num_ctx = min_t(unsigned int, IPMMU_CTX_MAX,
> -  mmu->features->number_of_contexts);
> + mmu->num_ctx = min(IPMMU_CTX_MAX, mmu->features->number_of_contexts);
>  
>   irq = platform_get_irq(pdev, 0);
>  

-- 
Regards,

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


Re: [PATCH 2/7] iommu/ipmmu-vmsa: Call ipmmu_ctx_write_root() instead of open coding

2019-02-20 Thread Laurent Pinchart
Hi Geert,

Thank you for the patch.

On Wed, Feb 20, 2019 at 04:05:26PM +0100, Geert Uytterhoeven wrote:
> There is a helper to write to the root IPMMU instance's registers, so
> let's use it.
> 
> Signed-off-by: Geert Uytterhoeven 
> ---
>  drivers/iommu/ipmmu-vmsa.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> index 9f2b781e20a0eba6..ac70cb967ff821c6 100644
> --- a/drivers/iommu/ipmmu-vmsa.c
> +++ b/drivers/iommu/ipmmu-vmsa.c
> @@ -280,8 +280,7 @@ static void ipmmu_ctx_write_all(struct ipmmu_vmsa_domain 
> *domain,
>   ipmmu_write(domain->mmu,
>   domain->context_id * IM_CTX_SIZE + reg, data);
>  
> - ipmmu_write(domain->mmu->root,
> - domain->context_id * IM_CTX_SIZE + reg, data);
> + ipmmu_ctx_write_root(domain, reg, data);

This makes the code harder to read in my opinion, and I don't think it
bring much optimization.

>  }
>  
>  /* 
> ---------

-- 
Regards,

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


Re: [PATCH 1/7] iommu/ipmmu-vmsa: Link IOMMUs and devices in sysfs

2019-02-20 Thread Laurent Pinchart
Hi Geert,

Thank you for the patch.

On Wed, Feb 20, 2019 at 04:05:25PM +0100, Geert Uytterhoeven wrote:
> As of commit 7af9a5fdb9e0ca33 ("iommu/ipmmu-vmsa: Use
> iommu_device_sysfs_add()/remove()"), IOMMU devices show up under
> /sys/class/iommus/, but their "devices" subdirectories are empty.
> Likewise, devices tied to an IOMMU do not have an "iommu" backlink.
> 
> Make sure all links are created, on both arm32 and arm64.
> 
> Signed-off-by: Geert Uytterhoeven 

Reviewed-by: Laurent Pinchart 

> ---
>  drivers/iommu/ipmmu-vmsa.c | 24 +---
>  1 file changed, 17 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> index 9a380c10655e182d..9f2b781e20a0eba6 100644
> --- a/drivers/iommu/ipmmu-vmsa.c
> +++ b/drivers/iommu/ipmmu-vmsa.c
> @@ -885,27 +885,37 @@ static int ipmmu_init_arm_mapping(struct device *dev)
>  
>  static int ipmmu_add_device(struct device *dev)
>  {
> + struct ipmmu_vmsa_device *mmu = to_ipmmu(dev);
>   struct iommu_group *group;
> + int ret;
>  
>   /*
>* Only let through devices that have been verified in xlate()
>*/
> - if (!to_ipmmu(dev))
> + if (!mmu)
>   return -ENODEV;
>  
> - if (IS_ENABLED(CONFIG_ARM) && !IS_ENABLED(CONFIG_IOMMU_DMA))
> - return ipmmu_init_arm_mapping(dev);
> + if (IS_ENABLED(CONFIG_ARM) && !IS_ENABLED(CONFIG_IOMMU_DMA)) {
> + ret = ipmmu_init_arm_mapping(dev);
> + if (ret)
> + return ret;
> + } else {
> + group = iommu_group_get_for_dev(dev);
> + if (IS_ERR(group))
> + return PTR_ERR(group);
>  
> - group = iommu_group_get_for_dev(dev);
> - if (IS_ERR(group))
> - return PTR_ERR(group);
> + iommu_group_put(group);
> + }
>  
> - iommu_group_put(group);
> + iommu_device_link(>iommu, dev);
>   return 0;
>  }
>  
>  static void ipmmu_remove_device(struct device *dev)
>  {
> + struct ipmmu_vmsa_device *mmu = to_ipmmu(dev);
> +
> + iommu_device_unlink(>iommu, dev);
>   arm_iommu_detach_device(dev);
>   iommu_group_remove_device(dev);
>  }

-- 
Regards,

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


Re: [PATCH] iommu/ipmmu-vmsa: fix device reference leaks

2019-02-12 Thread Laurent Pinchart
Hello,

Wen, thank you for the patch.

On Mon, Feb 11, 2019 at 11:24:15AM +0100, j...@8bytes.org wrote:
> Adding a few more people to Cc.
> 
> On Sun, Feb 03, 2019 at 10:27:09AM +, wen yang wrote:
> > Make sure to drop the reference to the device taken by
> > of_find_device_by_node() on driver unbind.
> > 
> > Signed-off-by: Wen Yang 
> > Cc: Joerg Roedel 
> > Cc: iommu@lists.linux-foundation.org
> > Cc: linux-ker...@vger.kernel.org
> > ---
> >  drivers/iommu/ipmmu-vmsa.c | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> > index 7a4529c..cebf56d 100644
> > --- a/drivers/iommu/ipmmu-vmsa.c
> > +++ b/drivers/iommu/ipmmu-vmsa.c
> > @@ -756,6 +756,9 @@ static int ipmmu_init_platform_device(struct device 
> > *dev,
> >  
> > fwspec->iommu_priv = platform_get_drvdata(ipmmu_pdev);
> >  
> > +   if (!fwspec->iommu_priv)
> > +   put_device(_pdev->dev);
> > +

This doesn't seem to match the patch's subject, and doesn't seem to fix
the problem.

> > return 0;
> >  }
> >  

-- 
Regards,

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


Re: [PATCH 1/1] iova: Allow compiling the library without IOMMU support

2019-01-02 Thread Laurent Pinchart
Hi Sakari,

Thank you for the patch.

On Wednesday, 2 January 2019 23:16:57 EET Sakari Ailus wrote:
> Drivers such as the Intel IPU3 ImgU driver use the IOVA library to manage
> the device's own virtual address space while not implementing the IOMMU
> API.

Why is that ? Could the IPU3 IOMMU be implemented as an IOMMU driver ?

> Currently the IOVA library is only compiled if the IOMMU support is
> enabled, resulting into a failure during linking due to missing symbols.
> 
> Fix this by defining IOVA library Kconfig bits independently of IOMMU
> support configuration, and descending to the iommu directory
> unconditionally during the build.
> 
> Signed-off-by: Sakari Ailus 
> ---
>  drivers/Makefile  | 2 +-
>  drivers/iommu/Kconfig | 7 ---
>  2 files changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/Makefile b/drivers/Makefile
> index 578f469f72fb..d9c469983592 100644
> --- a/drivers/Makefile
> +++ b/drivers/Makefile
> @@ -56,7 +56,7 @@ obj-y   += tty/
>  obj-y+= char/
> 
>  # iommu/ comes before gpu as gpu are using iommu controllers
> -obj-$(CONFIG_IOMMU_SUPPORT)  += iommu/
> +obj-y+= iommu/
> 
>  # gpu/ comes after char for AGP vs DRM startup and after iommu
>  obj-y+= gpu/
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index d9a25715650e..d2c83e62873d 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -1,3 +1,7 @@
> +# The IOVA library may also be used by non-IOMMU_API users
> +config IOMMU_IOVA
> + tristate
> +
>  # IOMMU_API always gets selected by whoever wants it.
>  config IOMMU_API
>   bool
> @@ -81,9 +85,6 @@ config IOMMU_DEFAULT_PASSTHROUGH
> 
> If unsure, say N here.
> 
> -config IOMMU_IOVA
> - tristate
> -
>  config OF_IOMMU
> def_bool y
> depends on OF && IOMMU_API


-- 
Regards,

Laurent Pinchart



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


Re: [PATCH 5/9] iommu: ipmmu-vmsa: make it explicitly non-modular

2018-11-28 Thread Laurent Pinchart
Hi Paul,

On Wednesday, 28 November 2018 17:32:05 EET Paul Gortmaker wrote:
> [Re: [PATCH 5/9] iommu: ipmmu-vmsa: make it explicitly non-modular] On 
28/11/2018 (Wed 12:50) Robin Murphy wrote:
> > On 26/11/2018 22:31, Paul Gortmaker wrote:
> [...]
> 
> >> diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> >> index 9e2655f1c1bf..de39ef992d8a 100644
> >> --- a/drivers/iommu/ipmmu-vmsa.c
> >> +++ b/drivers/iommu/ipmmu-vmsa.c
> >> @@ -1,6 +1,8 @@
> >>
> >>  // SPDX-License-Identifier: GPL-2.0
> >>  /*
> >>   * IPMMU VMSA
> > 
> > Nit: this line doesn't convey any information that the module description
> > below doesn't also say far more clearly, so you may as well just replace
> > it entirely.
> 
> No problem. Will do in v2.

With that change, the blank line after MODULE_DEVICE_TABLE() removed, and 
 moved to keep alphabetical order sorting of the includes, 
please add

Reviewed-by: Laurent Pinchart 

to v2. Thank you for the patch.

> > >+ * IOMMU API for Renesas VMSA-compatible IPMMU
> > >+ * Author: Laurent Pinchart 
> 
> [...]

-- 
Regards,

Laurent Pinchart



___
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-07-27 Thread Laurent Pinchart
Hi Dmitry,

(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 ?

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

-- 
Regards,

Laurent Pinchart



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


Re: [PATCH] iommu/ipmmu-vmsa: Clarify supported platforms

2018-07-25 Thread Laurent Pinchart
Hi Geert,

Thank you for the patch.

On Wednesday, 25 July 2018 16:10:29 EEST Geert Uytterhoeven wrote:
> The Renesas IPMMU-VMSA driver supports not just R-Car H2 and M2 SoCs,
> but also other R-Car Gen2 and R-Car Gen3 SoCs.
> 
> Drop a superfluous "Renesas" while at it.
> 
> Signed-off-by: Geert Uytterhoeven 

Reviewed-by: Laurent Pinchart 

> ---
>  drivers/iommu/Kconfig | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index 568ae81b0e99b67b..c69dc0b29b5df37f 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -306,8 +306,8 @@ config IPMMU_VMSA
>   select IOMMU_IO_PGTABLE_LPAE
>   select ARM_DMA_USE_IOMMU
>   help
> -   Support for the Renesas VMSA-compatible IPMMU Renesas found in the
> -   R-Mobile APE6 and R-Car H2/M2 SoCs.
> +   Support for the Renesas VMSA-compatible IPMMU found in the R-Mobile
> +   APE6, R-Car Gen2, and R-Car Gen3 SoCs.
> 
> If unsure, say N.


-- 
Regards,

Laurent Pinchart



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


Re: [PATCH] iommu/ipmmu-vmsa: Fix allocation in atomic context

2018-07-21 Thread Laurent Pinchart
Hi Geert,

Thank you for the patch.

On Friday, 20 July 2018 19:16:59 EEST Geert Uytterhoeven wrote:
> When attaching a device to an IOMMU group with
> CONFIG_DEBUG_ATOMIC_SLEEP=y:
> 
> BUG: sleeping function called from invalid context at mm/slab.h:421
> in_atomic(): 1, irqs_disabled(): 128, pid: 61, name: kworker/1:1
> ...
> Call trace:
>  ...
>  arm_lpae_alloc_pgtable+0x114/0x184
>  arm_64_lpae_alloc_pgtable_s1+0x2c/0x128
>  arm_32_lpae_alloc_pgtable_s1+0x40/0x6c
>  alloc_io_pgtable_ops+0x60/0x88
>  ipmmu_attach_device+0x140/0x334
> 
> ipmmu_attach_device() takes a spinlock, while arm_lpae_alloc_pgtable()
> allocates memory using GFP_KERNEL.  Originally, the ipmmu-vmsa driver
> had its own custom page table allocation implementation using
> GFP_ATOMIC, hence the spinlock was fine.
> 
> Fix this by replacing the spinlock by a mutex, like the arm-smmu driver
> does.
> 
> Fixes: f20ed39f53145e45 ("iommu/ipmmu-vmsa: Use the ARM LPAE page table
> allocator") Signed-off-by: Geert Uytterhoeven 
> ---
>  drivers/iommu/ipmmu-vmsa.c | 9 -
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> index 6a0e7142f41bf667..8f54f25404456035 100644
> --- a/drivers/iommu/ipmmu-vmsa.c
> +++ b/drivers/iommu/ipmmu-vmsa.c
> @@ -73,7 +73,7 @@ struct ipmmu_vmsa_domain {
>   struct io_pgtable_ops *iop;
> 
>   unsigned int context_id;
> - spinlock_t lock;/* Protects mappings */
> + struct mutex mutex; /* Protects mappings */
>  };
> 
>  static struct ipmmu_vmsa_domain *to_vmsa_domain(struct iommu_domain *dom)
> @@ -599,7 +599,7 @@ static struct iommu_domain
> *__ipmmu_domain_alloc(unsigned type) if (!domain)
>   return NULL;
> 
> - spin_lock_init(>lock);
> + mutex_init(>mutex);
> 
>   return >io_domain;
>  }
> @@ -645,7 +645,6 @@ static int ipmmu_attach_device(struct iommu_domain
> *io_domain, struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>   struct ipmmu_vmsa_device *mmu = to_ipmmu(dev);
>   struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
> - unsigned long flags;
>   unsigned int i;
>   int ret = 0;
> 
> @@ -654,7 +653,7 @@ static int ipmmu_attach_device(struct iommu_domain
> *io_domain, return -ENXIO;
>   }
> 
> - spin_lock_irqsave(>lock, flags);
> + mutex_lock(>mutex);

As the ipmmu_attach_device() function is called from a sleepable context this 
should be fine.

Reviewed-by: Laurent Pinchart 

> 
>   if (!domain->mmu) {
>   /* The domain hasn't been used yet, initialize it. */
> @@ -678,7 +677,7 @@ static int ipmmu_attach_device(struct iommu_domain
> *io_domain, } else
>   dev_info(dev, "Reusing IPMMU context %u\n", domain->context_id);
> 
> - spin_unlock_irqrestore(>lock, flags);
> + mutex_unlock(>mutex);
> 
>   if (ret < 0)
>   return ret;


-- 
Regards,

Laurent Pinchart



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


Re: [RFC v2 2/2] base: dma-mapping: Postpone page_to_pfn() on mmap()

2018-04-09 Thread Laurent Pinchart
Hi Rich,

On Monday, 9 April 2018 18:11:13 EEST Rich Felker wrote:
> On Mon, Apr 09, 2018 at 04:06:15PM +0300, Laurent Pinchart wrote:
> > On Monday, 9 April 2018 14:11:22 EEST Robin Murphy wrote:
> >> On 09/04/18 08:25, jacopo mondi wrote:
> >>> Hi Robin, Laurent,
> >>> 
> >>>  a long time passed, sorry about this.
> >>> 
> >>> On Wed, Nov 15, 2017 at 01:38:23PM +, Robin Murphy wrote:
> >>>> On 14/11/17 17:08, Jacopo Mondi wrote:
> >>>>> On SH4 architecture, with SPARSEMEM memory model, translating page
> >>>>> to pfn hangs the CPU. Post-pone translation to pfn after
> >>>>> dma_mmap_from_dev_coherent() function call as it succeeds and make
> >>>>> page translation not necessary.
> >>>>> 
> >>>>> This patch was suggested by Laurent Pinchart and he's working to
> >>>>> submit a proper fix mainline. Not sending for inclusion at the
> >>>>> moment.
> >>>> 
> >>>> Y'know, I think this patch does have some merit by itself - until we
> >>>> know that cpu_addr *doesn't* represent some device-private memory
> >>>> which is not guaranteed to be backed by a struct page, calling
> >>>> virt_to_page() on it is arguably semantically incorrect, even if it
> >>>> might happen to be benign in most cases.
> >>> 
> >>> I still need to carry this patch in my trees to have a working dma
> >>> memory mapping on SH4 platforms. My understanding from your comment is
> >>> that there may be a way forward for this patch, do you still think the
> >>> same? Have you got any suggestion on how to improve this eventually
> >>> for inclusion?
> >> 
> >> As before, the change itself does seem reasonable; it might be worth
> >> rewording the commit message in more general terms rather than making it
> >> sound like an SH-specific workaround (which I really don't think it is),
> >> but otherwise I'd say just repost it as a non-RFC patch.
> > 
> > I actually can't remember any better fix I would have in mind, so this
> > looks good to me :-) I agree with Robin, the commit message should be
> > reworded. Robin's explanation of why virt_to_page() should be postponed
> > until we know that cpu_addr represents memory that is guaranteed to be
> > backed by a struct page is a good starting point. You can mention SH4 as
> > an example of an architecture that will crash when calling virt_to_page()
> > in such a case, but the fix isn't specific to SH4.
> 
> Just checking since I joined late -- is the consensus that this does
> not require any action/review specific to SH (in my role as maintainer
> way behind on maintenance)?

I don't think it requires any action specific to SH. If you want to review the 
patch in the context of SH though, please feel free to do so :-)

-- 
Regards,

Laurent Pinchart



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


Re: [RFC v2 2/2] base: dma-mapping: Postpone page_to_pfn() on mmap()

2018-04-09 Thread Laurent Pinchart
Hello,

On Monday, 9 April 2018 14:11:22 EEST Robin Murphy wrote:
> On 09/04/18 08:25, jacopo mondi wrote:
> > Hi Robin, Laurent,
> > 
> >  a long time passed, sorry about this.
> > 
> > On Wed, Nov 15, 2017 at 01:38:23PM +, Robin Murphy wrote:
> >> On 14/11/17 17:08, Jacopo Mondi wrote:
> >>> On SH4 architecture, with SPARSEMEM memory model, translating page to
> >>> pfn hangs the CPU. Post-pone translation to pfn after
> >>> dma_mmap_from_dev_coherent() function call as it succeeds and make page
> >>> translation not necessary.
> >>> 
> >>> This patch was suggested by Laurent Pinchart and he's working to submit
> >>> a proper fix mainline. Not sending for inclusion at the moment.
> >> 
> >> Y'know, I think this patch does have some merit by itself - until we know
> >> that cpu_addr *doesn't* represent some device-private memory which is not
> >> guaranteed to be backed by a struct page, calling virt_to_page() on it is
> >> arguably semantically incorrect, even if it might happen to be benign in
> >> most cases.
> > 
> > I still need to carry this patch in my trees to have a working dma memory
> > mapping on SH4 platforms. My understanding from your comment is that
> > there may be a way forward for this patch, do you still think the same?
> > Have you got any suggestion on how to improve this eventually for
> > inclusion?
> 
> As before, the change itself does seem reasonable; it might be worth
> rewording the commit message in more general terms rather than making it
> sound like an SH-specific workaround (which I really don't think it is),
> but otherwise I'd say just repost it as a non-RFC patch.

I actually can't remember any better fix I would have in mind, so this looks 
good to me :-) I agree with Robin, the commit message should be reworded. 
Robin's explanation of why virt_to_page() should be postponed until we know 
that cpu_addr represents memory that is guaranteed to be backed by a struct 
page is a good starting point. You can mention SH4 as an example of an 
architecture that will crash when calling virt_to_page() in such a case, but 
the fix isn't specific to SH4.

> >>> Suggested-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
> >>> Signed-off-by: Jacopo Mondi <jacopo+rene...@jmondi.org>
> >>> ---
> >>> 
> >>>   drivers/base/dma-mapping.c | 3 ++-
> >>>   1 file changed, 2 insertions(+), 1 deletion(-)
> >>> 
> >>> diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
> >>> index e584edd..73d64d3 100644
> >>> --- a/drivers/base/dma-mapping.c
> >>> +++ b/drivers/base/dma-mapping.c
> >>> @@ -227,8 +227,8 @@ int dma_common_mmap(struct device *dev, struct
> >>> vm_area_struct *vma,
> >>>   #ifndef CONFIG_ARCH_NO_COHERENT_DMA_MMAP
> >>>   unsigned long user_count = vma_pages(vma);
> >>>   unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
> >>> - unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
> >>>   unsigned long off = vma->vm_pgoff;
> >>> + unsigned long pfn;
> >>> 
> >>>   vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> >>> 
> >>> @@ -236,6 +236,7 @@ int dma_common_mmap(struct device *dev, struct
> >>> vm_area_struct *vma,
> >>>   return ret;
> >>>   
> >>>   if (off < count && user_count <= (count - off)) {
> >>> + pfn = page_to_pfn(virt_to_page(cpu_addr));
> >>>   ret = remap_pfn_range(vma, vma->vm_start,
> >>> pfn + off,
> >>> user_count << PAGE_SHIFT,

-- 
Regards,

Laurent Pinchart



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


Re: [PATCH] iommu/ipmmu-vmsa: Document R-Car M3-N IPMMU DT bindings

2018-03-20 Thread Laurent Pinchart
Hi Magnus,

Thank you for the patch.

On Tuesday, 20 March 2018 08:48:11 EET Magnus Damm wrote:
> From: Magnus Damm <damm+rene...@opensource.se>
> 
> Update the IPMMU DT binding documentation to include the r8a77965 compat
> string for the IPMMU devices included in the R-Car M3-N SoC.
> 
> Signed-off-by: Magnus Damm <damm+rene...@opensource.se>

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> ---
> 
>  Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt |1 +
>  1 file changed, 1 insertion(+)
> 
> --- 0001/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
> +++
> work/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt   
2018-03
> -20 15:30:50.640607110 +0900 @@ -17,6 +17,7 @@ Required Properties:
>  - "renesas,ipmmu-r8a7794" for the R8A7794 (R-Car E2) IPMMU.
>  - "renesas,ipmmu-r8a7795" for the R8A7795 (R-Car H3) IPMMU.
>  - "renesas,ipmmu-r8a7796" for the R8A7796 (R-Car M3-W) IPMMU.
> +- "renesas,ipmmu-r8a77965" for the R8A77965 (R-Car M3-N) IPMMU.
>  - "renesas,ipmmu-r8a77970" for the R8A77970 (R-Car V3M) IPMMU.
>  - "renesas,ipmmu-r8a77995" for the R8A77995 (R-Car D3) IPMMU.
>  - "renesas,ipmmu-vmsa" for generic R-Car Gen2 VMSA-compatible IPMMU.

-- 
Regards,

Laurent Pinchart

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


Re: Seeing conflict with IPMMU driver under ACPI

2017-09-19 Thread Laurent Pinchart
Hi Ananth,

On Tuesday, 19 September 2017 09:54:49 EEST Jasty, Ananth wrote:
> On Sep 18, 2017, at 11:49 PM, Laurent Pinchart wrote:
> > On Tuesday, 19 September 2017 03:43:05 EEST Jasty, Ananth wrote:
> >> Hi, with your IPMMU driver enabled under 4.13 we’re seeing a crash on
> >> boot:
> >> 
> >> [ 13.785164] Unable to handle kernel NULL pointer dereference at virtual
> >> address 0018
> >> [ 13.793254] [0018] user address but active_mm is swapper
> >> [ 13.799600] Internal error: Oops: 9604 [#1] SMP
> >> [ 13.804466] Modules linked in: aes_neon_bs aes_neon_blk crypto_simd
> >> cryptd
> >> [ 13.811334] CPU: 152 PID: 1529 Comm: kworker/152:1 Not tainted
> >> 4.13.0-9-generic #10-Ubuntu
> >> [ 13.819584] Hardware name: Default string Cavium ThunderX2/Default
> >> string, BIOS 5.13 07/20/2017
> >> [ 13.828285] Workqueue: events deferred_probe_work_func
> >> [ 13.833410] task: 80bee93d task.stack: 80bee93dc000
> >> [ 13.839330] PC is at iommu_ops_from_fwnode+0x4c/0x90
> >> [ 13.844282] LR is at iommu_ops_from_fwnode+0x28/0x90
> >> 
> >> The ARM SMMUv3 driver (which our platform implements) seems to be losing
> >> iommu_ops to the IPMMU driver.
> > 
> > You seem not to be the first one to notice:
> > 
> > https://patchwork.kernel.org/patch/9956449/
> 
> Wow, he did not beat me by much.
> 
> >> Note: our platform uses ACPI for device enumeration.
> >> 
> >> I have no way to test this, but is there a reason the set_iommu isn’t in
> >> _probe?
> > 
> > I can't recall what the reason was I'm afraid.
> 
> arm-smmu-v3.c does do the set_iommu in probe, and thus far there have been
> no confirmed fatalities, but I can't speak authoritatively.
> 
> I'll leave you all to it then.

After digging a bit I realized that calling bus_set_iommu() from the init 
function is needed to support ARM32 (the same driver supports both ARM32 and 
ARM64). Let's discuss the matter in a reply to https://patchwork.kernel.org/
patch/9956449/.

-- 
Regards,

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

Re: [PATCH] iommu/ipmmu-vmsa: Do not replace bus IOMMU ops on driver init.

2017-09-19 Thread Laurent Pinchart
Hi Liviu,

Thank you for the patch.

On Monday, 18 September 2017 13:04:44 EEST Liviu Dudau wrote:
> If the IPMMU driver is compiled in the kernel it will replace the
> platform bus IOMMU ops on running the ipmmu_init() function, regardless
> if there is any IPMMU hardware present or not. This screws up systems
> that just want to build a generic kernel that runs on multiple platforms
> and use a different IOMMU implementation.
> 
> Move the bus_set_iommu() call at the end of the ipmmu_probe() function
> when we know that hardware is present. With current IOMMU framework it
> should be safe (at least for OF case).

If I recall correctly the issue is that the IPMMU might be probed after bus 
master devices when using the legacy IOMMU DT integration, which the ipmmu-
vmsa driver does on ARM32. Calling bus_set_iommu() from the probe function 
will then result in some devices losing IOMMU support.

> Now that the ipmmu_init() and ipmmu_exit() functions are simple calls to
> platform_driver_register() and platform_driver_unregister(), replace
> them with the module_platform_driver() macro call.
> 
> Signed-off-by: Liviu Dudau <liviu.du...@arm.com>
> Cc: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
> ---
>  drivers/iommu/ipmmu-vmsa.c | 29 +
>  1 file changed, 5 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> index 2a38aa15be17d..c60569c74678d 100644
> --- a/drivers/iommu/ipmmu-vmsa.c
> +++ b/drivers/iommu/ipmmu-vmsa.c
> @@ -1055,10 +1055,11 @@ static int ipmmu_probe(struct platform_device *pdev)
> ipmmu_device_reset(mmu);
> 
>   /*
> -  * We can't create the ARM mapping here as it requires the bus to have
> -  * an IOMMU, which only happens when bus_set_iommu() is called in
> -  * ipmmu_init() after the probe function returns.
> +  * Now that we have validated the presence of the hardware, set
> +  * the bus IOMMU ops to enable future domain and device setup.
>*/
> + if (!iommu_present(_bus_type))
> + bus_set_iommu(_bus_type, _ops);
> 
>   spin_lock(_devices_lock);
>   list_add(>list, _devices);

What branch is this patch based on ? ipmmu_devices_lock isn't in mainline.

> @@ -1100,27 +1101,7 @@ static struct platform_driver ipmmu_driver = {
>   .remove = ipmmu_remove,
>  };
> 
> -static int __init ipmmu_init(void)
> -{
> - int ret;
> -
> - ret = platform_driver_register(_driver);
> - if (ret < 0)
> - return ret;
> -
> - if (!iommu_present(_bus_type))
> - bus_set_iommu(_bus_type, _ops);
> -
> - return 0;
> -}
> -
> -static void __exit ipmmu_exit(void)
> -{
> - return platform_driver_unregister(_driver);
> -}
> -
> -subsys_initcall(ipmmu_init);
> -module_exit(ipmmu_exit);
> +module_platform_driver(ipmmu_driver);
> 
>  MODULE_DESCRIPTION("IOMMU API for Renesas VMSA-compatible IPMMU");
>  MODULE_AUTHOR("Laurent Pinchart <laurent.pinch...@ideasonboard.com>");

-- 
Regards,

Laurent Pinchart

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


Re: Seeing conflict with IPMMU driver under ACPI

2017-09-19 Thread Laurent Pinchart
Hi Ananth,

On Tuesday, 19 September 2017 03:43:05 EEST Jasty, Ananth wrote:
> Hi, with your IPMMU driver enabled under 4.13 we’re seeing a crash on boot:
> 
> [ 13.785164] Unable to handle kernel NULL pointer dereference at virtual
> address 0018
> [ 13.793254] [0018] user address but active_mm is swapper
> [ 13.799600] Internal error: Oops: 9604 [#1] SMP
> [ 13.804466] Modules linked in: aes_neon_bs aes_neon_blk crypto_simd cryptd
> [ 13.811334] CPU: 152 PID: 1529 Comm: kworker/152:1 Not tainted
> 4.13.0-9-generic #10-Ubuntu
> [ 13.819584] Hardware name: Default string Cavium ThunderX2/Default string,
> BIOS 5.13 07/20/2017
> [ 13.828285] Workqueue: events deferred_probe_work_func
> [ 13.833410] task: 80bee93d task.stack: 80bee93dc000
> [ 13.839330] PC is at iommu_ops_from_fwnode+0x4c/0x90
> [ 13.844282] LR is at iommu_ops_from_fwnode+0x28/0x90
> 
> The ARM SMMUv3 driver (which our platform implements) seems to be losing
> iommu_ops to the IPMMU driver.

You seem not to be the first one to notice:

https://patchwork.kernel.org/patch/9956449/

> Note: our platform uses ACPI for device enumeration.
> 
> I have no way to test this, but is there a reason the set_iommu isn’t in
> _probe?

I can't recall what the reason was I'm afraid.

> diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> index 2a38aa1..d4c72da 100644
> --- a/drivers/iommu/ipmmu-vmsa.c
> +++ b/drivers/iommu/ipmmu-vmsa.c
> @@ -1066,6 +1066,9 @@ static int ipmmu_probe(struct platform_device *pdev)
> 
> platform_set_drvdata(pdev, mmu);
> 
> +   if (!iommu_present(_bus_type))
> +   bus_set_iommu(_bus_type, _ops);
> +
> return 0;
>  }
> 
> @@ -1108,9 +,6 @@ static int __init ipmmu_init(void)
> if (ret < 0)
> return ret;
> 
> -   if (!iommu_present(_bus_type))
> -   bus_set_iommu(_bus_type, _ops);
> -
> return 0;
>  }
> 
> 
> If I’m wrong, my apologies.

-- 
Regards,

Laurent Pinchart

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

Re: [PATCH v1] iommu/ipmmu-vmsa: Set context_id to non-existent value if allocation failed

2017-08-23 Thread Laurent Pinchart
Hi Oleksandr,

On Wednesday, 23 August 2017 14:58:47 EEST Oleksandr Tyshchenko wrote:
> On Wed, Aug 23, 2017 at 1:05 PM, Robin Murphy wrote:
> > On 23/08/17 10:36, Oleksandr Tyshchenko wrote:
> >> On Wed, Aug 23, 2017 at 12:25 AM, Laurent Pinchart wrote:
> >>> On Monday, 21 August 2017 15:40:41 EEST Oleksandr Tyshchenko wrote:
> >>>> From: Oleksandr Tyshchenko <oleksandr_tyshche...@epam.com>
> >>>> 
> >>>> In ipmmu_domain_init_context() we are trying to allocate context and
> >>>> if allocation fails we will call free_io_pgtable_ops(),
> >>>> but "domain->context_id" hasn't been initialized yet (likely it is 0
> >>>> because of kzalloc). Having the following call stack:
> >>>> free_io_pgtable_ops() -> io_pgtable_tlb_flush_all() ->
> >>>> ipmmu_tlb_flush_all() -> ipmmu_tlb_invalidate()
> >>>> we will get a mistaken cache flush for a context pointed by
> >>>> uninitialized "domain->context_id".
> >>>> 
> >>>> So, set context_id to non-existent value (IPMMU_CTX_MAX) before calling
> >>>> free_io_pgtable_ops() and check it for a valid value (< IPMMU_CTX_MAX)
> >>>> before calling ipmmu_tlb_invalidate().
> >>>> 
> >>>> Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshche...@epam.com>
> >>>> ---
> >>>> 
> >>>>  drivers/iommu/ipmmu-vmsa.c | 4 
> >>>>  1 file changed, 4 insertions(+)
> >>>> 
> >>>> diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> >>>> index 2a38aa1..5b226c0 100644
> >>>> --- a/drivers/iommu/ipmmu-vmsa.c
> >>>> +++ b/drivers/iommu/ipmmu-vmsa.c
> >>>> @@ -303,6 +303,9 @@ static void ipmmu_tlb_flush_all(void *cookie)
> >>>>  {
> >>>>   struct ipmmu_vmsa_domain *domain = cookie;
> >>>> 
> >>>> + if (domain->context_id >= IPMMU_CTX_MAX)
> >>>> + return;
> >>>> +
> >>>>   ipmmu_tlb_invalidate(domain);
> >>>>  }
> >>>> 
> >>>> @@ -380,6 +383,7 @@ static int ipmmu_domain_init_context(struct
> >>>> ipmmu_vmsa_domain *domain)
> >>>>  */
> >>>>   ret = ipmmu_domain_allocate_context(domain->mmu, domain);
> >>>>   if (ret == IPMMU_CTX_MAX) {
> >>>> + domain->context_id = IPMMU_CTX_MAX;
> >>> 
> >>> Wouldn't it make more sense to allocate the pgtable ops after
> >>> initializing the context (moving the ipmmu_domain_allocate_context()
> >>> call to the very end of the function) ? That way we would be less
> >>> dependent on changes to pgtable ops init/cleanup code that could
> >>> require the context to be set up.
> >> 
> >> Why not. But, not sure about the very end of the function. Since for
> >> writing some HW registers down the function (IMTTLBR0/IMTTUBR0,
> >> IMMAIR0) we need to have what pgtable ops sets up for us (ttbr, mair).
> >> What about to just swap alloc_io_pgtable_ops() and
> >> ipmmu_domain_allocate_context()?
> > 
> > This looks a lot more reasonable - reserving a free context is both
> > quicker and more likely to fail (due to limited hardware resources) than
> > setting up a pagetable, so it makes a lot of sense to do that before
> > anything else.
> 
> Agree.

That looks good to me too. In general I prefer initializing everything needed 
by the error path before calling anything that could trigger that error path, 
instead of initializing variables to magic values that mean part of the 
cleanup should be skipped.

Will you send a v2 ?

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v1] iommu/ipmmu-vmsa: Set context_id to non-existent value if allocation failed

2017-08-22 Thread Laurent Pinchart
Hi Oleksandr,

Thank you for the patch.

On Monday, 21 August 2017 15:40:41 EEST Oleksandr Tyshchenko wrote:
> From: Oleksandr Tyshchenko <oleksandr_tyshche...@epam.com>
> 
> In ipmmu_domain_init_context() we are trying to allocate context and
> if allocation fails we will call free_io_pgtable_ops(),
> but "domain->context_id" hasn't been initialized yet (likely it is 0
> because of kzalloc). Having the following call stack:
> free_io_pgtable_ops() -> io_pgtable_tlb_flush_all() ->
> ipmmu_tlb_flush_all() -> ipmmu_tlb_invalidate()
> we will get a mistaken cache flush for a context pointed by
> uninitialized "domain->context_id".
> 
> So, set context_id to non-existent value (IPMMU_CTX_MAX) before calling
> free_io_pgtable_ops() and check it for a valid value (< IPMMU_CTX_MAX)
> before calling ipmmu_tlb_invalidate().
> 
> Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshche...@epam.com>
> ---
>  drivers/iommu/ipmmu-vmsa.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> index 2a38aa1..5b226c0 100644
> --- a/drivers/iommu/ipmmu-vmsa.c
> +++ b/drivers/iommu/ipmmu-vmsa.c
> @@ -303,6 +303,9 @@ static void ipmmu_tlb_flush_all(void *cookie)
>  {
>   struct ipmmu_vmsa_domain *domain = cookie;
> 
> + if (domain->context_id >= IPMMU_CTX_MAX)
> + return;
> +
>   ipmmu_tlb_invalidate(domain);
>  }
> 
> @@ -380,6 +383,7 @@ static int ipmmu_domain_init_context(struct
> ipmmu_vmsa_domain *domain) */
>   ret = ipmmu_domain_allocate_context(domain->mmu, domain);
>   if (ret == IPMMU_CTX_MAX) {
> + domain->context_id = IPMMU_CTX_MAX;

Wouldn't it make more sense to allocate the pgtable ops after initializing the 
context (moving the ipmmu_domain_allocate_context() call to the very end of 
the function) ? That way we would be less dependent on changes to pgtable ops 
init/cleanup code that could require the context to be set up.

>   free_io_pgtable_ops(domain->iop);
>   return -EBUSY;
>   }


-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v1] iommu/ipmmu-vmsa: Set context_id to non-existent value if allocation failed

2017-08-22 Thread Laurent Pinchart
Hi Joerg,

On Tuesday, 22 August 2017 17:24:30 EEST Joerg Roedel wrote:
> On Mon, Aug 21, 2017 at 03:40:41PM +0300, Oleksandr Tyshchenko wrote:
> > From: Oleksandr Tyshchenko <oleksandr_tyshche...@epam.com>
> > 
> > In ipmmu_domain_init_context() we are trying to allocate context and
> > if allocation fails we will call free_io_pgtable_ops(),
> > but "domain->context_id" hasn't been initialized yet (likely it is 0
> > because of kzalloc). Having the following call stack:
> > free_io_pgtable_ops() -> io_pgtable_tlb_flush_all() ->
> > ipmmu_tlb_flush_all() -> ipmmu_tlb_invalidate()
> > we will get a mistaken cache flush for a context pointed by
> > uninitialized "domain->context_id".
> > 
> > So, set context_id to non-existent value (IPMMU_CTX_MAX) before calling
> > free_io_pgtable_ops() and check it for a valid value (< IPMMU_CTX_MAX)
> > before calling ipmmu_tlb_invalidate().
> > 
> > Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshche...@epam.com>
> > ---
> > 
> >  drivers/iommu/ipmmu-vmsa.c | 4 
> >  1 file changed, 4 insertions(+)
> 
> Applied, thanks.

It would be nice to give reviewers a week before applying a patch, especially 
when it has no review at all.

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v2] arm: dma-mapping: Reset the device's dma_ops

2017-05-26 Thread Laurent Pinchart
Hi Sricharan,

Thank you for the patch.

On Friday 26 May 2017 16:13:37 Sricharan R wrote:
> arch_teardown_dma_ops() being the inverse of arch_setup_dma_ops()
> ,dma_ops should be cleared in the teardown path. Currently, only the
> device's iommu mapping structures are cleared in arch_teardown_dma_ops,
> but not the dma_ops. So on the next reprobe, dma_ops left in place is
> stale from the first IOMMU setup, but iommu mappings has been disposed
> of. This is a problem when the probe of the device is deferred and
> recalled with the IOMMU probe deferral.
> 
> So for fixing this, slightly refactor by moving the code from
> __arm_iommu_detach_device to arm_iommu_detach_device and cleanup
> the former. This takes care of resetting the dma_ops in the teardown
> path.
> 
> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
> Fixes: 09515ef5ddad ("of/acpi: Configure dma operations at probe time for
> platform/amba/pci bus devices")

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

Could you please push this upstream along with "[PATCH] ARM: dma-mapping: 
Don't tear third-party mappings" ?

(And feel free to s/tear/tear down/ in the subject of that patch, I've only 
noticed now that I forgot one word)

> ---
>  arch/arm/mm/dma-mapping.c | 25 ++---
>  1 file changed, 10 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index c742dfd..6e82e87 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -2311,7 +2311,14 @@ int arm_iommu_attach_device(struct device *dev,
>  }
>  EXPORT_SYMBOL_GPL(arm_iommu_attach_device);
> 
> -static void __arm_iommu_detach_device(struct device *dev)
> +/**
> + * arm_iommu_detach_device
> + * @dev: valid struct device pointer
> + *
> + * Detaches the provided device from a previously attached map.
> + * This voids the dma operations (dma_map_ops pointer)
> + */
> +void arm_iommu_detach_device(struct device *dev)
>  {
>   struct dma_iommu_mapping *mapping;
> 
> @@ -2324,22 +2331,10 @@ static void __arm_iommu_detach_device(struct device
> *dev) iommu_detach_device(mapping->domain, dev);
>   kref_put(>kref, release_iommu_mapping);
>   to_dma_iommu_mapping(dev) = NULL;
> + set_dma_ops(dev, NULL);
> 
>   pr_debug("Detached IOMMU controller from %s device.\n", 
dev_name(dev));
>  }
> -
> -/**
> - * arm_iommu_detach_device
> - * @dev: valid struct device pointer
> - *
> - * Detaches the provided device from a previously attached map.
> - * This voids the dma operations (dma_map_ops pointer)
> - */
> -void arm_iommu_detach_device(struct device *dev)
> -{
> - __arm_iommu_detach_device(dev);
> - set_dma_ops(dev, NULL);
> -}
>  EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
> 
>  static const struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
> @@ -2379,7 +2374,7 @@ static void arm_teardown_iommu_dma_ops(struct device
> *dev) if (!mapping)
>   return;
> 
> - __arm_iommu_detach_device(dev);
> + arm_iommu_detach_device(dev);
>   arm_iommu_release_mapping(mapping);
>  }

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH V3 6/8] arm: dma-mapping: Reset the device's dma_ops

2017-05-26 Thread Laurent Pinchart
Hi Russell,

On Thursday 25 May 2017 16:05:41 Russell King - ARM Linux wrote:
> On Wed, May 24, 2017 at 02:26:13PM +0300, Laurent Pinchart wrote:
> > Again, the patch I propose is the simplest v4.12-rc fix I can think of,
> > short of reverting your complete IOMMU probe deferral patch series. Let's
> > focus on the v4.12-rc fix, and then discuss how to move forward in v4.13
> > and beyond.
>
> Except, I don't think it fixes the problem that Sricharan is trying to
> fix, namely that of DMA ops that have been setup, torn down, and are
> trying to be re-setup again.

You're right, it's two separate problems, and we need to fix them both.

> The issue here is that results in a stale setup, because the dma_ops are
> left in-place from the first iommu setup, but the iommu mapping has been
> disposed of.
> 
> Your patch only avoids the problem of tearing down someone else's DMA
> ops.  We need a combination of both patches together.

Yes exactly. I should read e-mails to the end before starting typing the reply 
:-)

> What needs to happen for Sricharan's problem to be resolved is:
> 
> 1. move all of __arm_iommu_detach_device() into arm_iommu_detach_device().
> 2. replace the __arm_iommu_detach_device() call in
> arm_teardown_iommu_dma_ops() with arm_iommu_detach_device().
> 
> as I don't see any need to have a different order in
> arm_teardown_iommu_dma_ops().

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH V3 6/8] arm: dma-mapping: Reset the device's dma_ops

2017-05-24 Thread Laurent Pinchart
Hello,

On Wednesday 24 May 2017 16:01:45 Sricharan R wrote:
> On 5/24/2017 4:12 AM, Russell King - ARM Linux wrote:
> > On Wed, May 24, 2017 at 12:46:51AM +0300, Laurent Pinchart wrote:
> >> On Tuesday 23 May 2017 18:53:19 Russell King - ARM Linux wrote:
> >>> On Tue, May 23, 2017 at 05:55:57PM +0100, Robin Murphy wrote:
> >>>> On 23/05/17 17:25, Russell King - ARM Linux wrote:
> >>>>> So, I've come to apply this patch (since it's finally landed in the
> >>>>> patch system), and I'm not convinced that the commit message is really
> >>>>> up to scratch.
> >>>>> 
> >>>>> The current commit message looks like this:
> >>>>> 
> >>>>> "   ARM: 8674/1: dma-mapping: Reset the device's dma_ops
> >>>>> 
> >>>>> arch_teardown_dma_ops() being the inverse of arch_setup_dma_ops(),
> >>>>> dma_ops should be cleared in the teardown path. Otherwise this
> >>>>> causes problem when the probe of device is retried after being
> >>>>> deferred. The device's iommu structures are cleared after
> >>>>> EPROBEDEFER error, but on the next try dma_ops will still be set
> >>>>> to old value, which is not right."
> >>>>> 
> >>>>> It is obviously a fix, but a fix for which patch?  Looking at the
> >>>>> history, we have "arm: dma-mapping: Don't override dma_ops in
> >>>>> arch_setup_dma_ops()" which I would have guessed is the appropriate
> >>>>> one, but this post-dates your patch (it's very recent, v4.12-rc
> >>>>> recent.)
> >>>>> 
> >>>>> So, I need more description about the problem you were seeing when
> >>>>> you first proposed this patch.
> >>>>> 
> >>>>> How does leaving the dma_ops in place prior to "arm: dma-mapping:
> >>>>> Don't override dma_ops in arch_setup_dma_ops()" cause problems for
> >>>>> deferred probing?
> >>>>> 
> >>>>> What patch is your change trying to fix?  In other words, how far
> >>>>> back does this patch need to be backported?
> >>>> 
> >>>> In effect, it's fixing a latent inconsistency that's been present since
> >>>> its introduction in 4bb25789ed28. However, that has clearly not proven
> >>>> to be an issue in practice since then. With 09515ef5ddad we start
> >>>> actually calling arch_teardown_dma_ops() in a manner that might leave
> >>>> things partially initialised if anyone starts removing and reprobing
> >>>> drivers, but so far that's still from code inspection[1] rather than
> >>>> anyone hitting it.
> >>>> 
> >>>> Given that the changes which tickle it are fresh in -rc1 I'd say
> >>>> there's no need to backport this, but at the same time it shouldn't do
> >>>> any damage if you really want to.
> >>> 
> >>> Well, looking at this, I'm not convinced that much of it is correct.
> >>> 
> >>> 1) set_dma_ops() is in arch_setup_dma_ops() but this patch adds
> >>>the unsetting of the DMA ops inside arm_teardown_iommu_dma_ops()
> >>>rather than arch_teardown_dma_ops().
> >>>
> >>>This doesn't strike me as being particularly symmetric.
> >>>arm_teardown_iommu_dma_ops() is arm_setup_iommu_dma_ops()'s
> >>>counterpart.
> >>> 
> >>> 2) arch_setup_dma_ops(), the recent patch to add the existing dma_ops
> >>>check, and Xen - Xen wants to override the DMA ops if in the
> >>>initial domain.  It's not clear (at least to me) whether the recent
> >>>patch adding the dma_ops check took account of this or not.
> >>> 
> >>> 3) random places seem to fiddle with the dma_ops - notice that
> >>>arm_iommu_detach_device() sets the dma_ops to NULL.
> >>>
> >>>In fact, I think moving __arm_iommu_detach_device() into
> >>>arm_iommu_detach_device(), calling arm_iommu_detach_device(),
> >>>and getting rid of the explicit set_dma_ops(, NULL) in this
> >>>path would be a good first step.
> >>> 
> >>> 4) I think arch_setup_dma_ops() is over-complex.
> >>> 
> >>> So, in summary, this code is a mess today, and that means it's not
> >>> o

Re: [PATCH V3 6/8] arm: dma-mapping: Reset the device's dma_ops

2017-05-23 Thread Laurent Pinchart
Hi Russell,

On Tuesday 23 May 2017 18:53:19 Russell King - ARM Linux wrote:
> On Tue, May 23, 2017 at 05:55:57PM +0100, Robin Murphy wrote:
> > On 23/05/17 17:25, Russell King - ARM Linux wrote:
> >> So, I've come to apply this patch (since it's finally landed in the
> >> patch system), and I'm not convinced that the commit message is really
> >> up to scratch.
> >> 
> >> The current commit message looks like this:
> >> 
> >> "   ARM: 8674/1: dma-mapping: Reset the device's dma_ops
> >> arch_teardown_dma_ops() being the inverse of arch_setup_dma_ops(),
> >> dma_ops should be cleared in the teardown path. Otherwise this
> >> causes problem when the probe of device is retried after being
> >> deferred. The device's iommu structures are cleared after
> >> EPROBEDEFER error, but on the next try dma_ops will still be set to
> >> old value, which is not right."
> >> 
> >> It is obviously a fix, but a fix for which patch?  Looking at the
> >> history, we have "arm: dma-mapping: Don't override dma_ops in
> >> arch_setup_dma_ops()" which I would have guessed is the appropriate
> >> one, but this post-dates your patch (it's very recent, v4.12-rc
> >> recent.)
> >> 
> >> So, I need more description about the problem you were seeing when
> >> you first proposed this patch.
> >> 
> >> How does leaving the dma_ops in place prior to "arm: dma-mapping:
> >> Don't override dma_ops in arch_setup_dma_ops()" cause problems for
> >> deferred probing?
> >> 
> >> What patch is your change trying to fix?  In other words, how far
> >> back does this patch need to be backported?
> > 
> > In effect, it's fixing a latent inconsistency that's been present since
> > its introduction in 4bb25789ed28. However, that has clearly not proven
> > to be an issue in practice since then. With 09515ef5ddad we start
> > actually calling arch_teardown_dma_ops() in a manner that might leave
> > things partially initialised if anyone starts removing and reprobing
> > drivers, but so far that's still from code inspection[1] rather than
> > anyone hitting it.
> > 
> > Given that the changes which tickle it are fresh in -rc1 I'd say there's
> > no need to backport this, but at the same time it shouldn't do any
> > damage if you really want to.
> 
> Well, looking at this, I'm not convinced that much of it is correct.
> 
> 1) set_dma_ops() is in arch_setup_dma_ops() but this patch adds
>the unsetting of the DMA ops inside arm_teardown_iommu_dma_ops()
>rather than arch_teardown_dma_ops().
> 
>This doesn't strike me as being particularly symmetric.
>arm_teardown_iommu_dma_ops() is arm_setup_iommu_dma_ops()'s
>counterpart.
> 
> 2) arch_setup_dma_ops(), the recent patch to add the existing dma_ops
>check, and Xen - Xen wants to override the DMA ops if in the
>initial domain.  It's not clear (at least to me) whether the recent
>patch adding the dma_ops check took account of this or not.
> 
> 3) random places seem to fiddle with the dma_ops - notice that
>arm_iommu_detach_device() sets the dma_ops to NULL.
> 
>In fact, I think moving __arm_iommu_detach_device() into
>arm_iommu_detach_device(), calling arm_iommu_detach_device(),
>and getting rid of the explicit set_dma_ops(, NULL) in this
>path would be a good first step.
> 
> 4) I think arch_setup_dma_ops() is over-complex.
> 
> So, in summary, this code is a mess today, and that means it's not
> obviously correct - which is bad.  This needs sorting.

We've reached the same conclusion independently, but I'll refrain from 
commenting on whether that's a good or bad thing :-)

I don't think this patch should be applied, as it could break Xen (and other 
platforms/drivers that set the DMA operations manually) by resetting DMA 
operations at device remove() time even if they have been set independently of 
arch_setup_dma_ops().

The IOMMU probe deferral support patch series was merged in v4.12-rc1 and 
breaks IOMMU operations on several platforms. We need a fix for v4.12-rc that 
should be as nonintrusive as possible, as a larger cleanup is likely not -rc 
material. Beside reverting the whole series, the simplest option I came up 
with was [1]. Note that this is not the only fix needed to fix v4.12-rc1 IOMMU 
breakage, there are four more patches in the series that Sricharan plans to 
get merged soon. I don't think there are dependencies between the other four 
drivers/ patches and the arch/arm/ patch, so the latter could be merged 
independently through your tree as soon as it's deemed ready.

[1] https://www.spinics.net/lists/arm-kernel/msg583019.html

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH V4 2/4] iommu: of: Ignore all errors except EPROBE_DEFER

2017-05-18 Thread Laurent Pinchart
Hi Sricharan,

Thank you for the patch.

On Thursday 18 May 2017 20:24:15 Sricharan R wrote:
> While deferring the probe of IOMMU masters, xlate and
> add_device callbacks called from of_iommu_configure
> can pass back error values like -ENODEV, which means
> the IOMMU cannot be connected with that master for real
> reasons. Before the IOMMU probe deferral, all such errors
> were ignored. Now all those errors are propagated back,
> killing the master's probe for such errors. Instead ignore
> all the errors except EPROBE_DEFER, which is the only one
> of concern and let the master work without IOMMU, thus
> restoring the old behavior.
> 
> Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred
> probing or error") Reported-by: Geert Uytterhoeven <ge...@linux-m68k.org>
> Tested-by: Magnus Damn <magnus.d...@gmail.com>
> Signed-off-by: Sricharan R <sricha...@codeaurora.org>

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> ---
> [V4] Reworded commit log and changed dev_info to dev_dbg
> 
>  drivers/iommu/of_iommu.c | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index e6e9bec..19779b8 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -237,6 +237,12 @@ const struct iommu_ops *of_iommu_configure(struct
> device *dev, ops = ERR_PTR(err);
>   }
> 
> + /* Ignore all other errors apart from EPROBE_DEFER */
> + if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
> + dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
> + ops = NULL;
> + }
> +
>   return ops;
>  }

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH V2 2/3] iommu: of: Ignore all errors except EPROBE_DEFER

2017-05-18 Thread Laurent Pinchart
Hi Sricharan

On Thursday 18 May 2017 19:08:12 Sricharan R wrote:
> On 5/18/2017 6:00 PM, Laurent Pinchart wrote:
> > On Thursday 18 May 2017 17:26:14 Sricharan R wrote:
> >> On 5/18/2017 4:09 PM, Laurent Pinchart wrote:
> >>> On Thursday 18 May 2017 15:37:09 Sricharan R wrote:
> >>>> While deferring the probe of IOMMU masters,
> >>>> xlate and add_device callback can pass back error values
> >>>> like -ENODEV, which means IOMMU cannot be connected
> >>>> with that master for real reasons. So rather than
> >>>> killing the master's probe for such errors, just
> >>>> ignore the errors and let the master work without
> >>>> an IOMMU.
> >>> 
> >>> I don't think this is a good idea. Why should we allow IOMMU drivers to
> >>> return an error if we're always going to ignore the error value ? That
> >>> will lead to drivers implementing slightly different behaviours, which
> >>> will be painful the day we'll need to start acting based on the error
> >>> value.
> >> 
> >> The of_iommu_configure interface, before this series, was returning
> >> either correct 'iommu_ops' or NULL. Also there was no return value from
> >> of_dma_configure which calls of_iommu_configure. This means that if we
> >> block only -ENODEV now and let the other errors, the probe of the master
> >> devices can be killed for reasons apart from deferring. This would be a
> >> change in behavior introduced. All of xlate, add_device, of_pci_map_rid
> >> and others can return values apart from -ENODEV. So was thinking that
> >> restoring the old behavior, except for returning EPROBE_DEFER was the
> >> better thing to do ?
> > 
> > We went from a situation where of_iommu_configure() could return either
> > valid operations in the case the device was to be handled by the IOMMU or
> > NULL otherwise, to a situation where we needed a third option for probe
> > deferral. The way we've done this, through error pointers, allows lots of
> > other errors to be returned as well from the of_xlate and add_device
> > operations.
>
> right, this was difference in the behavior now.
> 
> > There is currently no use for returning error codes other than
> > -EPROBE_DEFFER from of_iommu_configure(), so your proposal is to block
> > errors returned from the of_xlate and add_device operations inside
> > of_iommu_configure(). My point is that, by doing so, we allow IOMMU
> > drivers to return random error codes that are then ignored. I believe
> > this can cause problems in the future when we will need to extend the API
> > and standardize more error codes, as by then IOMMU drivers will return
> > random errors (they actually do so already to some extent).
> > 
> > For of_xlate I agree with you to some extent. v4.11 just checked whether
> > of_xlate succeeded or not, and just didn't use the IOMMU in case it
> > failed. The exact error value was ignored, and drivers already return
> > random errors. Going back to the v4.11 behaviour is what we need to do in
> > the short-term, even if I believe we should standardize the error values
> > returned from of_xlate after v4.12.
> > 
> > For add_device, however, the situation is a bit different. The add_device
> > operation is called from the IOMMU bus notifier, and the -ENODEV error is
> > ignored by add_iommu_group(). Any other error will cause bus_set_iommu()
> > to fail, which makes IOMMU probing fail for the drivers that check the
> > return value of bus_set_iommu() (some of them don't :-/).
> > 
> > Fixing all this properly requires standardizing the error codes, and going
> > through the existing IOMMU drivers to comply with the standardized
> > behaviour.
>
> I understand your concern on standardizing the error codes from xlate,
> add_device, others and handling them properly. As you said there are quite
> some errors returned from them today. Also another thing is standardizing
> the behavior of of_iommu_configure itself. So that API serves to connect a
> device to its correct iommu_ops. When that's not possible, what should be
> the output and how should that be handled by the caller. The current
> behavior is to either 1) connect to correct ops or 2) wait for it or 3)
> progress further with plain/default dma_ops. Anyways as you said
> standardizing the iommu api ops, would make the of_iommu_configure handling
> more specific. Having said that i think similar fix needs to be done for
> acpi's iort_iommu_configure as well.

I'm less knowledgeable about ACPI but I think you're right. Would

Re: [PATCH V2 2/3] iommu: of: Ignore all errors except EPROBE_DEFER

2017-05-18 Thread Laurent Pinchart
Hi Sricharan,

On Thursday 18 May 2017 17:26:14 Sricharan R wrote:
> On 5/18/2017 4:09 PM, Laurent Pinchart wrote:
> > On Thursday 18 May 2017 15:37:09 Sricharan R wrote:
> >> While deferring the probe of IOMMU masters,
> >> xlate and add_device callback can pass back error values
> >> like -ENODEV, which means IOMMU cannot be connected
> >> with that master for real reasons. So rather than
> >> killing the master's probe for such errors, just
> >> ignore the errors and let the master work without
> >> an IOMMU.
> > 
> > I don't think this is a good idea. Why should we allow IOMMU drivers to
> > return an error if we're always going to ignore the error value ? That
> > will lead to drivers implementing slightly different behaviours, which
> > will be painful the day we'll need to start acting based on the error
> > value.
> 
> The of_iommu_configure interface, before this series, was returning either
> correct 'iommu_ops' or NULL. Also there was no return value from
> of_dma_configure which calls of_iommu_configure. This means that if we block
> only -ENODEV now and let the other errors, the probe of the master devices
> can be killed for reasons apart from deferring. This would be a change in
> behavior introduced. All of xlate, add_device, of_pci_map_rid and others
> can return values apart from -ENODEV. So was thinking that restoring the
> old behavior, except for returning EPROBE_DEFER was the better thing to do
> ?

We went from a situation where of_iommu_configure() could return either valid 
operations in the case the device was to be handled by the IOMMU or NULL 
otherwise, to a situation where we needed a third option for probe deferral. 
The way we've done this, through error pointers, allows lots of other errors 
to be returned as well from the of_xlate and add_device operations.

There is currently no use for returning error codes other than -EPROBE_DEFFER 
from of_iommu_configure(), so your proposal is to block errors returned from 
the of_xlate and add_device operations inside of_iommu_configure(). My point 
is that, by doing so, we allow IOMMU drivers to return random error codes that 
are then ignored. I believe this can cause problems in the future when we will 
need to extend the API and standardize more error codes, as by then IOMMU 
drivers will return random errors (they actually do so already to some 
extent).

For of_xlate I agree with you to some extent. v4.11 just checked whether 
of_xlate succeeded or not, and just didn't use the IOMMU in case it failed. 
The exact error value was ignored, and drivers already return random errors. 
Going back to the v4.11 behaviour is what we need to do in the short-term, 
even if I believe we should standardize the error values returned from 
of_xlate after v4.12.

For add_device, however, the situation is a bit different. The add_device 
operation is called from the IOMMU bus notifier, and the -ENODEV error is 
ignored by add_iommu_group(). Any other error will cause bus_set_iommu() to 
fail, which makes IOMMU probing fail for the drivers that check the return 
value of bus_set_iommu() (some of them don't :-/).

Fixing all this properly requires standardizing the error codes, and going 
through the existing IOMMU drivers to comply with the standardized behaviour. 
While this shouldn't be very difficult, it's likely not material for a v4.12-
rc fix. We will thus likely need to merge this patch (or something very 
similar to it), but I'd really like to see this fixed properly for v4.13.

> > At the very least, if you want to give a specific meaning to -ENODEV, you
> > should check for that value specifically and not ignore all errors other
> > than -EPROBE_DEFER. You also need to document the meaning of the error
> > value. This can be done in the documentation of the of_xlate operation in
> > include/linux/iommu.h:
> > 
> > diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> > index 2cb54adc4a33..6ba553e7384a 100644
> > --- a/include/linux/iommu.h
> > +++ b/include/linux/iommu.h
> > @@ -181,7 +181,6 @@ struct iommu_resv_region {
> >   * @domain_window_disable: Disable a particular window for a domain
> >   * @domain_set_windows: Set the number of windows for a domain
> >   * @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
> >   */
> >  
> >  struct iommu_ops {
> > @@ -224,6 +223,11 @@ struct iommu_ops {
> > /* Get the number of windows per domain */
> > u32 (*domain_get_windows)(struct iommu_domain *domain);
> > 
> > +   /**
> > +* @of_xlate:
> > +*
> > +* Add OF master IDs to iom

Re: [PATCH V2 2/3] iommu: of: Ignore all errors except EPROBE_DEFER

2017-05-18 Thread Laurent Pinchart
Hi Sricharan,

Thank you for the patch.

On Thursday 18 May 2017 15:37:09 Sricharan R wrote:
> While deferring the probe of IOMMU masters,
> xlate and add_device callback can pass back error values
> like -ENODEV, which means IOMMU cannot be connected
> with that master for real reasons. So rather than
> killing the master's probe for such errors, just
> ignore the errors and let the master work without
> an IOMMU.

I don't think this is a good idea. Why should we allow IOMMU drivers to return 
an error if we're always going to ignore the error value ? That will lead to 
drivers implementing slightly different behaviours, which will be painful the 
day we'll need to start acting based on the error value.

At the very least, if you want to give a specific meaning to -ENODEV, you 
should check for that value specifically and not ignore all errors other than 
-EPROBE_DEFER. You also need to document the meaning of the error value. This 
can be done in the documentation of the of_xlate operation in 
include/linux/iommu.h:

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 2cb54adc4a33..6ba553e7384a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -181,7 +181,6 @@ struct iommu_resv_region {
  * @domain_window_disable: Disable a particular window for a domain
  * @domain_set_windows: Set the number of windows for a domain
  * @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
  */
 struct iommu_ops {
@@ -224,6 +223,11 @@ struct iommu_ops {
/* Get the number of windows per domain */
u32 (*domain_get_windows)(struct iommu_domain *domain);
 
+   /**
+* @of_xlate:
+*
+* Add OF master IDs to iommu grouping.
+*/
int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
 
unsigned long pgsize_bitmap;


And add documentation for the error codes there.

If you want to ignore some errors returned from the add_device operation you 
should document it similarly, and in particular document which error check(s) 
need to be performed by of_xlate and which are the responsibility of 
add_device.

> Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred
> probing or error")
> Reported-by: Geert Uytterhoeven <ge...@linux-m68k.org>
> Tested-by: Magnus Damn <magnus.d...@gmail.com>
> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
> ---
> [V2] Corrected spelling/case in commit log
> 
>  drivers/iommu/of_iommu.c | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index e6e9bec..f0d22c0 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -237,6 +237,12 @@ const struct iommu_ops *of_iommu_configure(struct
> device *dev, ops = ERR_PTR(err);
>   }
> 
> + /* Ignore all other errors apart from EPROBE_DEFER */
> + if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
> + dev_info(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
> + ops = NULL;
> + }
> +
>   return ops;
>  }

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH V2 1/3] iommu: of: Fix check for returning EPROBE_DEFER

2017-05-18 Thread Laurent Pinchart
Hi Sricharan,

Thank you for the patch.

On Thursday 18 May 2017 15:37:08 Sricharan R wrote:
> Now with IOMMU probe deferral, we return -EPROBE_DEFER
> for masters that are connected to an IOMMU which is not
> probed yet, but going to get probed, so that we can attach
> the correct dma_ops. So while trying to defer the probe of
> the master, check if the of_iommu node that it is connected
> to is marked in DT as 'status=disabled', then the IOMMU is never
> is going to get probed. So simply return NULL and let the master
> work without an IOMMU.
> 
> Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred
> probing or error") Signed-off-by: Sricharan R <sricha...@codeaurora.org>
> Reported-by: Geert Uytterhoeven <ge...@linux-m68k.org>
> Tested-by: Will Deacon <will.dea...@arm.com>
> Tested-by: Magnus Damn <magnus.d...@gmail.com>
> Acked-by: Will Deacon <will.dea...@arm.com>

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> ---
> [V2] Corrected spelling/case in commit log
> 
>  drivers/iommu/of_iommu.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 9f44ee8..e6e9bec 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -118,6 +118,7 @@ static bool of_iommu_driver_present(struct device_node
> *np)
> 
>   ops = iommu_ops_from_fwnode(fwnode);
>   if ((ops && !ops->of_xlate) ||
> + !of_device_is_available(iommu_spec->np) ||
>   (!ops && !of_iommu_driver_present(iommu_spec->np)))
>   return NULL;

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH] ARM: dma-mapping: Don't tear third-party mappings

2017-05-16 Thread Laurent Pinchart
Hi Robin,

On Tuesday 16 May 2017 16:47:36 Robin Murphy wrote:
> On 16/05/17 16:14, Laurent Pinchart wrote:
> > arch_setup_dma_ops() is used in device probe code paths to create an
> > IOMMU mapping and attach it to the device. The function assumes that the
> > device is attached to a device-specific IOMMU instance (or at least a
> > device-specific TLB in a shared IOMMU instance) and thus creates a
> > separate mapping for every device.
> > 
> > On several systems (Renesas R-Car Gen2 being one of them), that
> > assumption is not true, and IOMMU mappings must be shared between
> > multiple devices. In those cases the IOMMU driver knows better than the
> > generic ARM dma-mapping layer and attaches mapping to devices manually
> > with arm_iommu_attach_device(), which sets the DMA ops for the device.
> > 
> > The arch_setup_dma_ops() function takes this into account and bails out
> > immediately if the device already has DMA ops assigned. However, the
> > corresponding arch_teardown_dma_ops() function, called from driver
> > unbind code paths (including probe deferral), will tear the mapping down
> > regardless of who created it. When the device is reprobed
> > arch_setup_dma_ops() will be called again but won't perform any
> > operation as the DMA ops will still be set.
> > 
> > We need to reset the DMA ops in arch_teardown_dma_ops() to fix this.
> > However, we can't do so unconditionally, as then a new mapping would be
> > created by arch_setup_dma_ops() when the device is reprobed, regardless
> > of whether the device needs to share a mapping or not. We must thus keep
> > track of whether arch_setup_dma_ops() created the mapping, and only in
> > that case tear it down in arch_teardown_dma_ops().
> > 
> > Keep track of that information in the dev_archdata structure. As the
> > structure is embedded in all instances of struct device let's not grow
> > it, but turn the existing dma_coherent bool field into a bitfield that
> > can be used for other purposes.
> > 
> > Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred
> > probing or error") Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+rene...@ideasonboard.com> ---
> > 
> >  arch/arm/include/asm/device.h | 3 ++-
> >  arch/arm/mm/dma-mapping.c | 5 +
> >  2 files changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
> > index 36ec9c8f6e16..3234fe9bba6e 100644
> > --- a/arch/arm/include/asm/device.h
> > +++ b/arch/arm/include/asm/device.h
> > @@ -19,7 +19,8 @@ struct dev_archdata {
> >  #ifdef CONFIG_XEN
> > const struct dma_map_ops *dev_dma_ops;
> >  #endif
> > -   bool dma_coherent;
> > +   unsigned int dma_coherent:1;
> 
> This should only ever be accessed by the Xen DMA code via the
> is_device_dma_coherent() helper, so I can't see the change of storage
> type causing any problems.

Thank you for double-checking. I agree with your analysis.

> > +   unsigned int dma_ops_setup:1;
> >  };
> >  
> >  struct omap_device;
> > diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> > index c742dfd2967b..e0272f9140e2 100644
> > --- a/arch/arm/mm/dma-mapping.c
> > +++ b/arch/arm/mm/dma-mapping.c
> > @@ -2430,9 +2430,14 @@ void arch_setup_dma_ops(struct device *dev, u64
> > dma_base, u64 size,
> > dev->dma_ops = xen_dma_ops;
> > }
> >  #endif
> > +   dev->archdata.dma_ops_setup = true;
> >  }
> >  
> >  void arch_teardown_dma_ops(struct device *dev)
> >  {
> > +   if (!dev->archdata.dma_ops_setup)
> > +   return;
> > +
> > arm_teardown_iommu_dma_ops(dev);
> > +   set_dma_ops(dev, NULL);
> 
> Should we clear dma_ops_setup here for symmetry? I guess in practice
> it's down to the IOMMU driver so will never change after the first
> probe, but it still feels like a bit of a nagging loose end.

To make a difference, we would need an IOMMU driver that creates a mapping 
after a first round of arch_setup_dma_ops() / arch_teardown_dma_ops() calls, 
follow by a second round. I don't think this could happen, but if it did, I 
believe we'd be screwed already, as there would be a time were an incorrect 
mapping (created by arch_setup_dma_ops() while the IOMMU driver needs to take 
care of mapping creation) exists.

> With that (or firm reassurance that it's OK not to),
> 
> Reviewed-by: Robin Murphy <robin.mur...@arm.com>
> 
> Apologies for being too arm64-focused in the earlier 

[PATCH] ARM: dma-mapping: Don't tear third-party mappings

2017-05-16 Thread Laurent Pinchart
arch_setup_dma_ops() is used in device probe code paths to create an
IOMMU mapping and attach it to the device. The function assumes that the
device is attached to a device-specific IOMMU instance (or at least a
device-specific TLB in a shared IOMMU instance) and thus creates a
separate mapping for every device.

On several systems (Renesas R-Car Gen2 being one of them), that
assumption is not true, and IOMMU mappings must be shared between
multiple devices. In those cases the IOMMU driver knows better than the
generic ARM dma-mapping layer and attaches mapping to devices manually
with arm_iommu_attach_device(), which sets the DMA ops for the device.

The arch_setup_dma_ops() function takes this into account and bails out
immediately if the device already has DMA ops assigned. However, the
corresponding arch_teardown_dma_ops() function, called from driver
unbind code paths (including probe deferral), will tear the mapping down
regardless of who created it. When the device is reprobed
arch_setup_dma_ops() will be called again but won't perform any
operation as the DMA ops will still be set.

We need to reset the DMA ops in arch_teardown_dma_ops() to fix this.
However, we can't do so unconditionally, as then a new mapping would be
created by arch_setup_dma_ops() when the device is reprobed, regardless
of whether the device needs to share a mapping or not. We must thus keep
track of whether arch_setup_dma_ops() created the mapping, and only in
that case tear it down in arch_teardown_dma_ops().

Keep track of that information in the dev_archdata structure. As the
structure is embedded in all instances of struct device let's not grow
it, but turn the existing dma_coherent bool field into a bitfield that
can be used for other purposes.

Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred 
probing or error")
Signed-off-by: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
---
 arch/arm/include/asm/device.h | 3 ++-
 arch/arm/mm/dma-mapping.c | 5 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index 36ec9c8f6e16..3234fe9bba6e 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -19,7 +19,8 @@ struct dev_archdata {
 #ifdef CONFIG_XEN
const struct dma_map_ops *dev_dma_ops;
 #endif
-   bool dma_coherent;
+   unsigned int dma_coherent:1;
+   unsigned int dma_ops_setup:1;
 };
 
 struct omap_device;
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index c742dfd2967b..e0272f9140e2 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2430,9 +2430,14 @@ void arch_setup_dma_ops(struct device *dev, u64 
dma_base, u64 size,
dev->dma_ops = xen_dma_ops;
}
 #endif
+   dev->archdata.dma_ops_setup = true;
 }
 
 void arch_teardown_dma_ops(struct device *dev)
 {
+   if (!dev->archdata.dma_ops_setup)
+   return;
+
arm_teardown_iommu_dma_ops(dev);
+   set_dma_ops(dev, NULL);
 }
-- 
Regards,

Laurent Pinchart

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


Re: [PATCH V8 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-05-16 Thread Laurent Pinchart
Hi Sricharan,

On Tuesday 16 May 2017 19:59:01 sricha...@codeaurora.org wrote:
> On 2017-05-16 19:40, Laurent Pinchart wrote:
> > On Tuesday 16 May 2017 15:04:55 Robin Murphy wrote:
> >> On 16/05/17 08:17, Laurent Pinchart wrote:
> >> > On Tuesday 16 May 2017 07:53:57 sricha...@codeaurora.org wrote:
> > [snip]
> > 
> >>>> arch_teardown_dma_ops() being the inverse of arch_setup_dma_ops(),
> >>>> dma_ops should be cleared in the teardown path. Otherwise
> >>>> this causes problem when the probe of device is retried after
> >>>> being deferred. The device's iommu structures are cleared
> >>>> after EPROBEDEFER error, but on the next try dma_ops will still
> >>>> be set to old value, which is not right.
> >>>> 
> >>>> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
> >>>> Reviewed-by: Robin Murphy <robin.mur...@arm.com>
> >>>> ---
> >>>> 
> >>>>   arch/arm/mm/dma-mapping.c | 1 +
> >>>>   1 file changed, 1 insertion(+)
> >>>> 
> >>>> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> >>>> index ab4f745..a40f03e 100644
> >>>> --- a/arch/arm/mm/dma-mapping.c
> >>>> +++ b/arch/arm/mm/dma-mapping.c
> >>>> @@ -2358,6 +2358,7 @@ static void arm_teardown_iommu_dma_ops(struct
> >>>> device *dev)
> >>>>
> >>>>  __arm_iommu_detach_device(dev);
> >>>>  arm_iommu_release_mapping(mapping);
> >>>> +set_dma_ops(dev, NULL);
> >>>>   }
> >>>>   #else
> >>> 
> >>> The subject mentions arch_teardown_dma_ops(), which I think is correct,
> >>> but the patch adds the set_dma_ops() call to
> >>> arm_teardown_iommu_dma_ops().
> >>> 
> >>> However, the situation is perhaps more complex. Note the check at the
> >>> beginning of arch_setup_dma_ops():
> >>> 
> >>>   /*
> >>>* Don't override the dma_ops if they have already been set. Ideally
> >>>* this should be the only location where dma_ops are set, remove this
> >>>* check when all other callers of set_dma_ops will have disappeared.
> >>>*/
> >>>   if (dev->dma_ops)
> >>>   return;
> >>> 
> >>> If you set the dma_ops to NULL in arm_teardown_iommu_dma_ops() or
> >>> arch_teardown_dma_ops(), the next call to arch_setup_dma_ops() will
> >>> override them. To be safe you should only set them to NULL if they have
> >>> been set by arch_setup_dma_ops(). More than that,
> >>> arch_teardown_dma_ops()
> >>> should probably not call arm_teardown_iommu_dma_ops() at all if the
> >>> dma_ops were set by arm_iommu_attach_device() and not
> >>> arch_teardown_dma_ops().
> >> 
> >> Under what circumstances is that an issue? We'll only be tearing down
> >> the DMA ops when unbinding the driver,
> > 
> > Or when deferring probe.
> > 
> >> and I think it would be erroneous to expect the device to retain much
> >> state after that. Everything else would be set up from scratch again if
> >> it get reprobed later, so why not the DMA ops?
> > 
> > Because the DMA ops might have been set elsewhere than
> > arch_setup_dma_ops(). If you look at the patch that added the above
> > warning, its commit message states
> > 
> > commit 26b37b946a5c2658dbc37dd5d6df40aaa9685d70 (iommu-joerg/arm/core)
> > Author: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
> > Date:   Fri May 15 02:00:02 2015 +0300
> > 
> > arm: dma-mapping: Don't override dma_ops in arch_setup_dma_ops()
> > 
> > The arch_setup_dma_ops() function is in charge of setting dma_ops
> > with a call to set_dma_ops(). set_dma_ops() is also called from
> > 
> > - highbank and mvebu bus notifiers
> > - dmabounce (to be replaced with swiotlb)
> > - arm_iommu_attach_device
> > 
> > (arm_iommu_attach_device is itself called from IOMMU and bus master
> > device drivers)
> > 
> > To allow the arch_setup_dma_ops() call to be moved from device add
> > time to device probe time we must ensure that dma_ops already setup by
> > any of the above callers will not be overriden.
> > 
> > Aftering replacing dmabounce with swiotlb, converting IOMMU drivers
> >

Re: [PATCH V8 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-05-16 Thread Laurent Pinchart
Hi Robin,

On Tuesday 16 May 2017 15:04:55 Robin Murphy wrote:
> On 16/05/17 08:17, Laurent Pinchart wrote:
> > On Tuesday 16 May 2017 07:53:57 sricha...@codeaurora.org wrote:

[snip]

> >> arch_teardown_dma_ops() being the inverse of arch_setup_dma_ops()
> >> ,dma_ops should be cleared in the teardown path. Otherwise
> >> this causes problem when the probe of device is retried after
> >> being deferred. The device's iommu structures are cleared
> >> after EPROBEDEFER error, but on the next try dma_ops will still
> >> be set to old value, which is not right.
> >> 
> >> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
> >> Reviewed-by: Robin Murphy <robin.mur...@arm.com>
> >> ---
> >> 
> >>   arch/arm/mm/dma-mapping.c | 1 +
> >>   1 file changed, 1 insertion(+)
> >> 
> >> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> >> index ab4f745..a40f03e 100644
> >> --- a/arch/arm/mm/dma-mapping.c
> >> +++ b/arch/arm/mm/dma-mapping.c
> >> @@ -2358,6 +2358,7 @@ static void arm_teardown_iommu_dma_ops(struct
> >> device *dev)
> > 
> >>__arm_iommu_detach_device(dev);
> >>arm_iommu_release_mapping(mapping);
> >> +  set_dma_ops(dev, NULL);
> >>   }
> >>   #else
> > 
> > The subject mentions arch_teardown_dma_ops(), which I think is correct,
> > but the patch adds the set_dma_ops() call to arm_teardown_iommu_dma_ops().
> > 
> > However, the situation is perhaps more complex. Note the check at the
> > beginning of arch_setup_dma_ops():
> > /*
> >  * Don't override the dma_ops if they have already been set. Ideally
> >  * this should be the only location where dma_ops are set, remove this
> >  * check when all other callers of set_dma_ops will have disappeared.
> >  */
> > if (dev->dma_ops)
> > return;
> > 
> > If you set the dma_ops to NULL in arm_teardown_iommu_dma_ops() or
> > arch_teardown_dma_ops(), the next call to arch_setup_dma_ops() will
> > override them. To be safe you should only set them to NULL if they have
> > been set by arch_setup_dma_ops(). More than that, arch_teardown_dma_ops()
> > should probably not call arm_teardown_iommu_dma_ops() at all if the
> > dma_ops were set by arm_iommu_attach_device() and not
> > arch_teardown_dma_ops().
> 
> Under what circumstances is that an issue? We'll only be tearing down
> the DMA ops when unbinding the driver,

Or when deferring probe.

> and I think it would be erroneous to expect the device to retain much state
> after that. Everything else would be set up from scratch again if it get
> reprobed later, so why not the DMA ops?

Because the DMA ops might have been set elsewhere than arch_setup_dma_ops(). 
If you look at the patch that added the above warning, its commit message 
states

commit 26b37b946a5c2658dbc37dd5d6df40aaa9685d70 (iommu-joerg/arm/core)
Author: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
Date:   Fri May 15 02:00:02 2015 +0300

arm: dma-mapping: Don't override dma_ops in arch_setup_dma_ops()

The arch_setup_dma_ops() function is in charge of setting dma_ops with a
call to set_dma_ops(). set_dma_ops() is also called from

- highbank and mvebu bus notifiers
- dmabounce (to be replaced with swiotlb)
- arm_iommu_attach_device

(arm_iommu_attach_device is itself called from IOMMU and bus master
device drivers)

To allow the arch_setup_dma_ops() call to be moved from device add time
to device probe time we must ensure that dma_ops already setup by any of
the above callers will not be overriden.

Aftering replacing dmabounce with swiotlb, converting IOMMU drivers to
of_xlate and taking care of highbank and mvebu, the workaround should be
removed.

I'm concerned about potentially breaking these if we unconditionally remove 
the DMA ops and mapping.

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH V8 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-05-16 Thread Laurent Pinchart
Hi Sricharan,

On Tuesday 16 May 2017 19:10:03 sricha...@codeaurora.org wrote:
> On 2017-05-16 12:47, Laurent Pinchart wrote:
> > On Tuesday 16 May 2017 07:53:57 sricha...@codeaurora.org wrote:
> >> On 2017-05-16 03:04, Laurent Pinchart wrote:
> >>> On Monday 15 May 2017 23:37:16 Laurent Pinchart wrote:
> >>>> On Wednesday 03 May 2017 15:54:59 Sricharan R wrote:
> >>>>> On 5/3/2017 3:24 PM, Robin Murphy wrote:
> >>>>>> On 02/05/17 19:35, Geert Uytterhoeven wrote:
> >>>>>>> On Fri, Feb 3, 2017 at 4:48 PM, Sricharan R wrote:
> >>>>>>>> From: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
> >>>>>>>> 
> >>>>>>>> Failures to look up an IOMMU when parsing the DT iommus property
> >>>>>>>> need to be handled separately from the .of_xlate() failures to
> >>>>>>>> support deferred probing.
> >>>>>>>> 
> >>>>>>>> The lack of a registered IOMMU can be caused by the lack of a
> >>>>>>>> driver for the IOMMU, the IOMMU device probe not having been
> >>>>>>>> performed yet, having been deferred, or having failed.
> >>>>>>>> 
> >>>>>>>> The first case occurs when the device tree describes the bus
> >>>>>>>> master and IOMMU topology correctly but no device driver exists for
> >>>>>>>> the IOMMU yet or the device driver has not been compiled in. Return
> >>>>>>>> NULL, the caller will configure the device without an IOMMU.
> >>>>>>>> 
> >>>>>>>> The second and third cases are handled by deferring the probe of
> >>>>>>>> the bus master device which will eventually get reprobed after the
> >>>>>>>> IOMMU.
> >>>>>>>> 
> >>>>>>>> The last case is currently handled by deferring the probe of the
> >>>>>>>> bus master device as well. A mechanism to either configure the bus
> >>>>>>>> master device without an IOMMU or to fail the bus master device
> >>>>>>>> probe depending on whether the IOMMU is optional or mandatory would
> >>>>>>>> be a good enhancement.
> >>>>>>>> 
> >>>>>>>> Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
> >>>>>>>> Signed-off-by: Laurent Pichart
> >>>>>>>> <laurent.pinchart+rene...@ideasonboard.com>
> >>>>>>>> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
> >>>>>>> 
> >>>>>>> This patch broke Renesas R-Car Gen3 platforms in renesas-drivers.
> >>>>>>> As the IOMMU nodes in DT are not yet enabled, all devices having
> >>>>>>> iommus properties in DT now fail to probe.
> >>>>>> 
> >>>>>> How exactly do they fail to probe? Per d7b0558230e4, if there are no
> >>>>>> ops registered then they should merely defer until we reach the
> >>>>>> point of giving up and ignoring the IOMMU. Is it just that you have
> >>>>>> no other late-probing drivers or post-init module loads to kick the
> >>>>>> deferred queue after that point? I did try to find a way to
> >>>>>> explicitly kick it from a suitably late initcall, but there didn't
> >>>>>> seem to be any obvious public interface - anyone have any
> >>>>>> suggestions?
> >>>>>> 
> >>>>>> I think that's more of a general problem with the probe deferral
> >>>>>> mechanism itself (I've seen the same thing happen with some of the
> >>>>>> CoreSight stuff on Juno due to the number of inter-component
> >>>>>> dependencies) rather than any specific fault of this series.
> >>>>> 
> >>>>> I was thinking of an additional check like below to avoid the
> >>>>> situation ?
> >>>>> 
> >>>>> From 499b6e662f60f23740b8880882b0a16f16434501 Mon Sep 17 00:00:00
> >>>>> 2001
> >>>>> From: Sricharan R <sricha...@codeaurora.org>
> >>>>> Date: Wed, 3 May 2017 13:16:59 +0530
> >>>>> Subject: [PATCH] iommu: of: Fix check 

Re: [PATCH V8 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-05-16 Thread Laurent Pinchart
Hi Sricharan,

On Tuesday 16 May 2017 07:53:57 sricha...@codeaurora.org wrote:
> On 2017-05-16 03:04, Laurent Pinchart wrote:
> > On Monday 15 May 2017 23:37:16 Laurent Pinchart wrote:
> >> On Wednesday 03 May 2017 15:54:59 Sricharan R wrote:
> >>> On 5/3/2017 3:24 PM, Robin Murphy wrote:
> >>>> On 02/05/17 19:35, Geert Uytterhoeven wrote:
> >>>>> On Fri, Feb 3, 2017 at 4:48 PM, Sricharan R wrote:
> >>>>>> From: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
> >>>>>> 
> >>>>>> Failures to look up an IOMMU when parsing the DT iommus property
> >>>>>> need to be handled separately from the .of_xlate() failures to
> >>>>>> support deferred probing.
> >>>>>> 
> >>>>>> The lack of a registered IOMMU can be caused by the lack of a driver
> >>>>>> for the IOMMU, the IOMMU device probe not having been performed yet,
> >>>>>> having been deferred, or having failed.
> >>>>>> 
> >>>>>> The first case occurs when the device tree describes the bus master
> >>>>>> and IOMMU topology correctly but no device driver exists for the
> >>>>>> IOMMU yet or the device driver has not been compiled in. Return NULL,
> >>>>>> the caller will configure the device without an IOMMU.
> >>>>>> 
> >>>>>> The second and third cases are handled by deferring the probe of the
> >>>>>> bus master device which will eventually get reprobed after the
> >>>>>> IOMMU.
> >>>>>> 
> >>>>>> The last case is currently handled by deferring the probe of the bus
> >>>>>> master device as well. A mechanism to either configure the bus
> >>>>>> master device without an IOMMU or to fail the bus master device probe
> >>>>>> depending on whether the IOMMU is optional or mandatory would be a
> >>>>>> good enhancement.
> >>>>>> 
> >>>>>> Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
> >>>>>> Signed-off-by: Laurent Pichart
> >>>>>> <laurent.pinchart+rene...@ideasonboard.com>
> >>>>>> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
> >>>>> 
> >>>>> This patch broke Renesas R-Car Gen3 platforms in renesas-drivers.
> >>>>> As the IOMMU nodes in DT are not yet enabled, all devices having
> >>>>> iommus properties in DT now fail to probe.
> >>>> 
> >>>> How exactly do they fail to probe? Per d7b0558230e4, if there are no
> >>>> ops registered then they should merely defer until we reach the point
> >>>> of giving up and ignoring the IOMMU. Is it just that you have no other
> >>>> late-probing drivers or post-init module loads to kick the deferred
> >>>> queue after that point? I did try to find a way to explicitly kick it
> >>>> from a suitably late initcall, but there didn't seem to be any obvious
> >>>> public interface - anyone have any suggestions?
> >>>> 
> >>>> I think that's more of a general problem with the probe deferral
> >>>> mechanism itself (I've seen the same thing happen with some of the
> >>>> CoreSight stuff on Juno due to the number of inter-component
> >>>> dependencies) rather than any specific fault of this series.
> >>> 
> >>> I was thinking of an additional check like below to avoid the
> >>> situation ?
> >>> 
> >>> From 499b6e662f60f23740b8880882b0a16f16434501 Mon Sep 17 00:00:00 2001
> >>> From: Sricharan R <sricha...@codeaurora.org>
> >>> Date: Wed, 3 May 2017 13:16:59 +0530
> >>> Subject: [PATCH] iommu: of: Fix check for returning EPROBE_DEFER
> >>> 
> >>> While returning EPROBE_DEFER for iommu masters
> >>> take in to account of iommu nodes that could be
> >>> marked in DT as 'status=disabled', in which case
> >>> simply return NULL and let the master's probe
> >>> continue rather than deferring.
> >>> 
> >>> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
> >>> ---
> >>> 
> >>>  drivers/iommu/of_iommu.c | 1 +
> >>>  1 file changed, 1 insertion(+)
> >>> 
> >>> diff --git a/drivers/iommu/of

Re: [PATCH V8 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-05-15 Thread Laurent Pinchart
Hi Sricharan,

On Monday 15 May 2017 23:37:16 Laurent Pinchart wrote:
> On Wednesday 03 May 2017 15:54:59 Sricharan R wrote:
> > On 5/3/2017 3:24 PM, Robin Murphy wrote:
> >> On 02/05/17 19:35, Geert Uytterhoeven wrote:
> >>> On Fri, Feb 3, 2017 at 4:48 PM, Sricharan R wrote:
> >>>> From: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
> >>>> 
> >>>> Failures to look up an IOMMU when parsing the DT iommus property need
> >>>> to be handled separately from the .of_xlate() failures to support
> >>>> deferred probing.
> >>>> 
> >>>> The lack of a registered IOMMU can be caused by the lack of a driver
> >>>> for the IOMMU, the IOMMU device probe not having been performed yet,
> >>>> having been deferred, or having failed.
> >>>> 
> >>>> The first case occurs when the device tree describes the bus master
> >>>> and IOMMU topology correctly but no device driver exists for the IOMMU
> >>>> yet or the device driver has not been compiled in. Return NULL, the
> >>>> caller will configure the device without an IOMMU.
> >>>> 
> >>>> The second and third cases are handled by deferring the probe of the
> >>>> bus master device which will eventually get reprobed after the IOMMU.
> >>>> 
> >>>> The last case is currently handled by deferring the probe of the bus
> >>>> master device as well. A mechanism to either configure the bus master
> >>>> device without an IOMMU or to fail the bus master device probe
> >>>> depending on whether the IOMMU is optional or mandatory would be a good
> >>>> enhancement.
> >>>> 
> >>>> Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
> >>>> Signed-off-by: Laurent Pichart
> >>>> <laurent.pinchart+rene...@ideasonboard.com>
> >>>> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
> >>> 
> >>> This patch broke Renesas R-Car Gen3 platforms in renesas-drivers.
> >>> As the IOMMU nodes in DT are not yet enabled, all devices having iommus
> >>> properties in DT now fail to probe.
> >> 
> >> How exactly do they fail to probe? Per d7b0558230e4, if there are no ops
> >> registered then they should merely defer until we reach the point of
> >> giving up and ignoring the IOMMU. Is it just that you have no other
> >> late-probing drivers or post-init module loads to kick the deferred
> >> queue after that point? I did try to find a way to explicitly kick it
> >> from a suitably late initcall, but there didn't seem to be any obvious
> >> public interface - anyone have any suggestions?
> >> 
> >> I think that's more of a general problem with the probe deferral
> >> mechanism itself (I've seen the same thing happen with some of the
> >> CoreSight stuff on Juno due to the number of inter-component
> >> dependencies) rather than any specific fault of this series.
> > 
> > I was thinking of an additional check like below to avoid the
> > situation ?
> > 
> > From 499b6e662f60f23740b8880882b0a16f16434501 Mon Sep 17 00:00:00 2001
> > From: Sricharan R <sricha...@codeaurora.org>
> > Date: Wed, 3 May 2017 13:16:59 +0530
> > Subject: [PATCH] iommu: of: Fix check for returning EPROBE_DEFER
> > 
> > While returning EPROBE_DEFER for iommu masters
> > take in to account of iommu nodes that could be
> > marked in DT as 'status=disabled', in which case
> > simply return NULL and let the master's probe
> > continue rather than deferring.
> > 
> > Signed-off-by: Sricharan R <sricha...@codeaurora.org>
> > ---
> > 
> >  drivers/iommu/of_iommu.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> > index 9f44ee8..e6e9bec 100644
> > --- a/drivers/iommu/of_iommu.c
> > +++ b/drivers/iommu/of_iommu.c
> > @@ -118,6 +118,7 @@ static bool of_iommu_driver_present(struct device_node
> > *np)
> > 
> > ops = iommu_ops_from_fwnode(fwnode);
> > if ((ops && !ops->of_xlate) ||
> > +   !of_device_is_available(iommu_spec->np) ||
> > (!ops && !of_iommu_driver_present(iommu_spec->np)))
> > return NULL;
> 
> This looks good to me, but won't be enough. The ipmmu-vmsa driver in
> v4.12-rc1 doesn't call iommu_device_register() and thus won

Re: [PATCH V8 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-05-15 Thread Laurent Pinchart
Hi Sricharan,

On Wednesday 03 May 2017 15:54:59 Sricharan R wrote:
> On 5/3/2017 3:24 PM, Robin Murphy wrote:
> > On 02/05/17 19:35, Geert Uytterhoeven wrote:
> >> On Fri, Feb 3, 2017 at 4:48 PM, Sricharan R wrote:
> >>> From: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
> >>> 
> >>> Failures to look up an IOMMU when parsing the DT iommus property need to
> >>> be handled separately from the .of_xlate() failures to support deferred
> >>> probing.
> >>> 
> >>> The lack of a registered IOMMU can be caused by the lack of a driver for
> >>> the IOMMU, the IOMMU device probe not having been performed yet, having
> >>> been deferred, or having failed.
> >>> 
> >>> The first case occurs when the device tree describes the bus master and
> >>> IOMMU topology correctly but no device driver exists for the IOMMU yet
> >>> or the device driver has not been compiled in. Return NULL, the caller
> >>> will configure the device without an IOMMU.
> >>> 
> >>> The second and third cases are handled by deferring the probe of the bus
> >>> master device which will eventually get reprobed after the IOMMU.
> >>> 
> >>> The last case is currently handled by deferring the probe of the bus
> >>> master device as well. A mechanism to either configure the bus master
> >>> device without an IOMMU or to fail the bus master device probe depending
> >>> on whether the IOMMU is optional or mandatory would be a good
> >>> enhancement.
> >>> 
> >>> Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
> >>> Signed-off-by: Laurent Pichart
> >>> <laurent.pinchart+rene...@ideasonboard.com>
> >>> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
> >> 
> >> This patch broke Renesas R-Car Gen3 platforms in renesas-drivers.
> >> As the IOMMU nodes in DT are not yet enabled, all devices having iommus
> >> properties in DT now fail to probe.
> > 
> > How exactly do they fail to probe? Per d7b0558230e4, if there are no ops
> > registered then they should merely defer until we reach the point of
> > giving up and ignoring the IOMMU. Is it just that you have no other
> > late-probing drivers or post-init module loads to kick the deferred
> > queue after that point? I did try to find a way to explicitly kick it
> > from a suitably late initcall, but there didn't seem to be any obvious
> > public interface - anyone have any suggestions?
> > 
> > I think that's more of a general problem with the probe deferral
> > mechanism itself (I've seen the same thing happen with some of the
> > CoreSight stuff on Juno due to the number of inter-component
> > dependencies) rather than any specific fault of this series.
> 
> I was thinking of an additional check like below to avoid the
> situation ?
> 
> From 499b6e662f60f23740b8880882b0a16f16434501 Mon Sep 17 00:00:00 2001
> From: Sricharan R <sricha...@codeaurora.org>
> Date: Wed, 3 May 2017 13:16:59 +0530
> Subject: [PATCH] iommu: of: Fix check for returning EPROBE_DEFER
> 
> While returning EPROBE_DEFER for iommu masters
> take in to account of iommu nodes that could be
> marked in DT as 'status=disabled', in which case
> simply return NULL and let the master's probe
> continue rather than deferring.
> 
> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
> ---
>  drivers/iommu/of_iommu.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 9f44ee8..e6e9bec 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -118,6 +118,7 @@ static bool of_iommu_driver_present(struct device_node
> *np)
> 
> ops = iommu_ops_from_fwnode(fwnode);
> if ((ops && !ops->of_xlate) ||
> +   !of_device_is_available(iommu_spec->np) ||
> (!ops && !of_iommu_driver_present(iommu_spec->np)))
> return NULL;

This looks good to me, but won't be enough. The ipmmu-vmsa driver in v4.12-rc1 
doesn't call iommu_device_register() and thus won't be found by 
iommu_ops_from_fwnode(). Furthermore, it doesn't IOMMU_OF_DECLARE(), and thus 
will always be considered as absent.

I agree that the ipmmu-vmsa driver needs to be fixed, but it would have been 
nice to check existing IOMMU drivers before merging this patch series...

> >> This can be fixed by either:
> >>   - Disabling CONFIG_IPMMU_VMSA, or
> >>   - Reverting commit 7b07cbefb68d486f (but keeping "int ret = 0;").
> >> 
> >> Note that this was a bit hard to investigate, as R-Car Gen3 support
> >> wasn't upstreamed yet, so bisection pointed to a merge commit.

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH] iommu/ipmmu-vmsa: Add r8a7795 DT binding

2017-02-03 Thread Laurent Pinchart
Hi Rob,

On Monday 29 Feb 2016 23:33:09 Magnus Damm wrote:
> From: Magnus Damm <damm+rene...@opensource.se>
> 
> Update the IPMMU DT binding documentation to include the r8a7795 compat
> string as well as the "renesas,ipmmu-main" property that on r8a7795 will
> be used to describe the topology and the relationship between the various
> cache IPMMU instances and the main IPMMU.
> 
> Signed-off-by: Magnus Damm <damm+rene...@opensource.se>

This DT binding has been merged already, but isn't used upstream (nor in the 
dts nor in the drivers). We plan to start using it, and I'd like to seize this 
last opportunity to change it if needed and ask you for a review.

> ---
> 
>  Written against linux-next tag next-20160229
> 
>  Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt |   15 -
>  1 file changed, 13 insertions(+), 2 deletions(-)
> 
> --- 0001/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
> +++
> work/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt   
2016-02
> -29 23:25:15.540513000 +0900 @@ -7,23 +7,34 @@ connected to the IPMMU
> through a port ca
> 
>  Required Properties:
> 
> -  - compatible: Must contain SoC-specific and generic entries from below.
> +  - compatible: Must contain SoC-specific and generic entry below in case
> +the device is compatible with the R-Car Gen2 VMSA-compatible IPMMU.
> 
>  - "renesas,ipmmu-r8a73a4" for the R8A73A4 (R-Mobile APE6) IPMMU.
>  - "renesas,ipmmu-r8a7790" for the R8A7790 (R-Car H2) IPMMU.
>  - "renesas,ipmmu-r8a7791" for the R8A7791 (R-Car M2-W) IPMMU.
>  - "renesas,ipmmu-r8a7793" for the R8A7793 (R-Car M2-N) IPMMU.
>  - "renesas,ipmmu-r8a7794" for the R8A7794 (R-Car E2) IPMMU.
> +- "renesas,ipmmu-r8a7795" for the R8A7795 (R-Car H3) IPMMU.
>  - "renesas,ipmmu-vmsa" for generic R-Car Gen2 VMSA-compatible IPMMU.
> 
>- reg: Base address and size of the IPMMU registers.
>- interrupts: Specifiers for the MMU fault interrupts. For instances that
> support secure mode two interrupts must be specified, for non-secure and
> secure mode, in that order. For instances that don't support secure mode a
> -single interrupt must be specified.
> +single interrupt must be specified. Not required for cache IPMMUs.
> 
>- #iommu-cells: Must be 1.
> 
> +Optional properties:
> +
> +  - renesas,ipmmu-main: reference to the main IPMMU instance in two cells.
> +The first cell is a phandle to the main IPMMU and the second cell is
> +the interrupt bit number associated with the particular cache IPMMU
> device.
> +The interrupt bit number needs to match the main IPMMU IMSSTR register.
> +Only used by cache IPMMU instances.
> +
> +
>  Each bus master connected to an IPMMU must reference the IPMMU in its
> device node with the following property:

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v2] iommu/ipmmu-vmsa: Restrict IOMMU Domain Geometry to 32-bit address space

2017-02-01 Thread Laurent Pinchart
Hi Geert,

Thank you for the patch.

On Tuesday 31 Jan 2017 12:17:07 Geert Uytterhoeven wrote:
> Currently, the IPMMU/VMSA driver supports 32-bit I/O Virtual Addresses
> only, and thus sets io_pgtable_cfg.ias = 32.  However, it doesn't force
> a 32-bit IOVA space through the IOMMU Domain Geometry.
> 
> Hence if a device (e.g. SYS-DMAC) rightfully configures a 40-bit DMA
> mask, it will still be handed out a 40-bit IOVA, outside the 32-bit IOVA
> space, leading to out-of-bounds accesses of the PGD when mapping the
> IOVA.
> 
> Force a 32-bit IOMMU Domain Geometry to fix this.
> 
> Signed-off-by: Geert Uytterhoeven <geert+rene...@glider.be>
> Reviewed-by: Robin Murphy <robin.mur...@arm.com>

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> ---
> v2:
>   - Add Reviewed-by.
> ---
>  drivers/iommu/ipmmu-vmsa.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> index 798578f1676480c6..eb8b3df8733b15fb 100644
> --- a/drivers/iommu/ipmmu-vmsa.c
> +++ b/drivers/iommu/ipmmu-vmsa.c
> @@ -424,6 +424,8 @@ static int ipmmu_domain_init_context(struct
> ipmmu_vmsa_domain *domain) domain->cfg.ias = 32;
>   domain->cfg.oas = 40;
>   domain->cfg.tlb = _gather_ops;
> + domain->io_domain.geometry.aperture_end = DMA_BIT_MASK(32);
> + domain->io_domain.geometry.force_aperture = true;
>   /*
>* TODO: Add support for coherent walk through CCI with DVM and remove
>* cache handling. For now, delegate it to the io-pgtable code.

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v2 2/2] arm64: Add support for DMA_ATTR_FORCE_CONTIGUOUS to IOMMU

2017-01-28 Thread Laurent Pinchart
Hi Geert,

Thank you for the patch.

On Friday 27 Jan 2017 16:34:19 Geert Uytterhoeven wrote:
> Add support for allocation physically contiguous DMA buffers on arm64
> systems with an IOMMU, by dispatching DMA buffer allocations with the
> DMA_ATTR_FORCE_CONTIGUOUS attribute to the appropriate IOMMU DMA
> helpers.
> 
> Note that as this uses the CMA allocator, setting this attribute has a
> runtime-dependency on CONFIG_DMA_CMA, just like on arm32.
> 
> For arm64 systems using swiotlb, no changes are needed to support the
> allocation of physically contiguous DMA buffers:
>   - swiotlb always uses physically contiguous buffers (up to
> IO_TLB_SEGSIZE = 128 pages),
>   - arm64's __dma_alloc_coherent() already calls
> dma_alloc_from_contiguous() when CMA is available.
> 
> Signed-off-by: Geert Uytterhoeven <geert+rene...@glider.be>
> ---
> v2:
>   - New, handle dispatching in the arch (arm64) code, as requested by
> Robin Murphy.
> ---
>  arch/arm64/mm/dma-mapping.c | 51 +-
>  1 file changed, 37 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index 1d7d5d2881db7c19..325803e0ba79ef26 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -577,20 +577,7 @@ static void *__iommu_alloc_attrs(struct device *dev,
> size_t size, */
>   gfp |= __GFP_ZERO;
> 
> - if (gfpflags_allow_blocking(gfp)) {
> - struct page **pages;
> - pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL, 
coherent);
> -
> - pages = iommu_dma_alloc(dev, iosize, gfp, attrs, ioprot,
> - handle, flush_page);
> - if (!pages)
> - return NULL;
> -
> - addr = dma_common_pages_remap(pages, size, VM_USERMAP, prot,
> -   __builtin_return_address(0));
> - if (!addr)
> - iommu_dma_free(dev, pages, iosize, handle);
> - } else {
> + if (!gfpflags_allow_blocking(gfp)) {
>   struct page *page;
>   /*
>* In atomic context we can't remap anything, so we'll only
> @@ -614,6 +601,35 @@ static void *__iommu_alloc_attrs(struct device *dev,
> size_t size, __free_from_pool(addr, size);
>   addr = NULL;
>   }
> + } else if (attrs & DMA_ATTR_FORCE_CONTIGUOUS) {
> + pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL, 
coherent);
> + struct page *page;
> +
> + page = iommu_dma_alloc_contiguous(dev, iosize, ioprot, 
handle);
> + if (!page)
> + return NULL;
> +
> + if (!coherent)
> + __dma_flush_area(page_to_virt(page), iosize);
> +
> + addr = dma_common_contiguous_remap(page, size, VM_USERMAP,
> +prot,
> +
__builtin_return_address(0));
> + if (!addr)
> + iommu_dma_free_contiguous(dev, page, iosize, handle);
> + } else {
> + pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL, 
coherent);
> + struct page **pages;
> +
> + pages = iommu_dma_alloc(dev, iosize, gfp, attrs, ioprot,
> + handle, flush_page);
> + if (!pages)
> + return NULL;
> +
> + addr = dma_common_pages_remap(pages, size, VM_USERMAP, prot,
> +   __builtin_return_address(0));
> + if (!addr)
> + iommu_dma_free(dev, pages, iosize, handle);
>   }
>   return addr;
>  }
> @@ -626,6 +642,8 @@ static void __iommu_free_attrs(struct device *dev,
> size_t size, void *cpu_addr, size = PAGE_ALIGN(size);
>   /*
>* @cpu_addr will be one of 3 things depending on how it was 
allocated:

s/one of 3/one of 4/

Apart from that,

Acked-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> +  * - A remapped array of pages from iommu_dma_alloc_contiguous()
> +  *   for contiguous allocations.
>* - A remapped array of pages from iommu_dma_alloc(), for all
>*   non-atomic allocations.
>* - A non-cacheable alias from the atomic pool, for atomic
> @@ -637,6 +655,11 @@ static void __iommu_free_attrs(struct device *dev,
> size_t size, void *cpu_addr, if (__in_atomic_pool(cpu_addr, size)) {
>   iommu_dma_unmap_page(dev, handle, iosize, 0, 0);
>   __free_from_pool(cpu_addr, size);
> + } else if (attrs &

Re: [PATCHv9 6/6] dmaengine: rcar-dmac: add iommu support for slave transfers

2017-01-01 Thread Laurent Pinchart
Hi Niklas,

On Monday 05 Sep 2016 12:52:44 Laurent Pinchart wrote:
> On Wednesday 10 Aug 2016 13:22:19 Niklas Söderlund wrote:
> > Enable slave transfers to a device behind a IPMMU by mapping the slave
> > addresses using the dma-mapping API.
> > 
> > Signed-off-by: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>
> > ---
> > drivers/dma/sh/rcar-dmac.c | 82 -
> > 1 file changed, 74 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
> > index cf983a9..22a5e40 100644
> > --- a/drivers/dma/sh/rcar-dmac.c
> > +++ b/drivers/dma/sh/rcar-dmac.c

[snip]

> > +static int rcar_dmac_map_slave_addr(struct dma_chan *chan,
> > +   enum dma_transfer_direction dir)
> > +{
> > +   struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan);
> > +   struct rcar_dmac_chan_map *map = >map;
> > +   phys_addr_t dev_addr;
> > +   size_t dev_size;
> > +   enum dma_data_direction dev_dir;
> > +
> > +   if (dir == DMA_DEV_TO_MEM) {
> > +   dev_addr = rchan->src.slave_addr;
> > +   dev_size = rchan->src.xfer_size;
> > +   dev_dir = DMA_TO_DEVICE;
> 
> Shouldn't this be DMA_FROM_DEVICE, and DMA_TO_DEVICE below ?

This comment can be ignored (thank you Robin for the explanation), but ...

> > +   } else {
> > +   dev_addr = rchan->dst.slave_addr;
> > +   dev_size = rchan->dst.xfer_size;
> > +   dev_dir = DMA_FROM_DEVICE;
> > +   }
> > +
> > +   /* Reuse current map if possible. */
> > +   if (dev_addr == map->slave.slave_addr &&
> > +   dev_size == map->slave.xfer_size &&
> > +   dev_dir == map->dir)
> > +   return 0;
> > +
> > +   /* Remove old mapping if present. */
> > +   if (map->slave.xfer_size)
> > +   dma_unmap_resource(chan->device->dev, map->addr,
> > +  map->slave.xfer_size, map->dir, 0);
> 
> Unless I'm mistaken the resource will not be unmapped when freeing channel
> resources, will it ?

I believe this one still needs to be addressed.

> > +   map->slave.xfer_size = 0;
> > +
> > +   /* Create new slave address map. */
> > +   map->addr = dma_map_resource(chan->device->dev, dev_addr, dev_size,
> > +dev_dir, 0);
> > +
> > +   if (dma_mapping_error(chan->device->dev, map->addr)) {
> > +   dev_err(chan->device->dev,
> > +   "chan%u: failed to map %zx@%pap", rchan->index,
> > +   dev_size, _addr);
> > +   return -EIO;
> > +   }
> > +
> > +   dev_dbg(chan->device->dev, "chan%u: map %zx@%pap to %pad dir: %s\n",
> > +   rchan->index, dev_size, _addr, >addr,
> 
> > +   dev_dir == DMA_TO_DEVICE ? "DMA_TO_DEVICE" :
> "DMA_FROM_DEVICE");
> 
> > +
> > +   map->slave.slave_addr = dev_addr;
> > +   map->slave.xfer_size = dev_size;
> > +   map->dir = dev_dir;
> > +
> > +   return 0;
> > +}

[snip]

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v6 05/07] iommu/ipmmu-vmsa: Add new IOMMU_DOMAIN_DMA ops

2016-11-11 Thread Laurent Pinchart
Hi Robin,

On Friday 11 Nov 2016 14:44:29 Robin Murphy wrote:
> On 11/11/16 01:50, Laurent Pinchart wrote:
> > On Friday 21 Oct 2016 18:52:53 Robin Murphy wrote:
> >> On 20/10/16 00:36, Magnus Damm wrote:
> >>> From: Magnus Damm <damm+rene...@opensource.se>
> >>> 
> >>> Introduce an alternative set of iommu_ops suitable for 64-bit ARM
> >>> as well as 32-bit ARM when CONFIG_IOMMU_DMA=y. Also adjust the
> >>> Kconfig to depend on ARM or IOMMU_DMA.
> >>> 
> >>> Signed-off-by: Magnus Damm <damm+rene...@opensource.se>
> >>> ---
> >>> 
> >>>  Changes since V5:
> >>>  - Made domain allocation/free code more consistent - thanks Joerg!
> >>>  
> >>>  Changes since V4:
> >>>  - Added Kconfig hunk to depend on ARM or IOMMU_DMA
> >>>  
> >>>  Changes since V3:
> >>>  - Removed group parameter from ipmmu_init_platform_device()
> >>>  
> >>>  Changes since V2:
> >>>  
> >>>  - Included this new patch from the following series:
> >>>[PATCH 00/04] iommu/ipmmu-vmsa: IPMMU CONFIG_IOMMU_DMA update
> >>>  
> >>>  - Use only a single iommu_ops structure with #ifdef CONFIG_IOMMU_DMA
> >>>  - Folded in #ifdefs to handle CONFIG_ARM and CONFIG_IOMMU_DMA
> >>>  - of_xlate() is now used without #ifdefs
> >>>  - Made sure code compiles on both 32-bit and 64-bit ARM.
> >>>  
> >>>  drivers/iommu/Kconfig  |1
> >>>  drivers/iommu/ipmmu-vmsa.c |  122 +---
> >>>  2 files changed, 115 insertions(+), 8 deletions(-)
> > 
> > [snip]
> > 
> >>> --- 0006/drivers/iommu/ipmmu-vmsa.c
> >>> +++ work/drivers/iommu/ipmmu-vmsa.c
> >>> 2016-10-20 08:16:48.440607110 +0900
> > 
> > [snip]
> > 
> >>> -static struct iommu_domain *ipmmu_domain_alloc(unsigned type)
> >>> -{
> >>> - if (type != IOMMU_DOMAIN_UNMANAGED)
> >>> - return NULL;
> >> 
> >> I *think* that if we did the initial check thus:
> >>if (type != IOMMU_DOMAIN_UNMANAGED ||
> >>(IS_ENABLED(CONFIG_IOMMU_DMA) && type != IOMMU_DOMAIN_DMA))
> >>return NULL;
> > 
> > I assume you meant
> > 
> > if (type != IOMMU_DOMAIN_UNMANAGED &&
> > (!IS_ENABLED(CONFIG_IOMMU_DMA) || type != IOMMU_DOMAIN_DMA))
> > return NULL;
> > 
> > But how about just
> > 
> > if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA))
> > return NULL;
> > 
> > as type will never be set to IOMMU_DOMAIN_DMA on ARM32 ?
> 
> Actually it can be, but *only* at this point, because
> iommu_group_get_for_dev() will always attempt to allocate a default
> domain.

If I'm not mistaken iommu_group_get_for_dev() is the only function that tries 
to create an IOMMU_DOMAIN_DMA domain, and is only called in core code by 
iommu_request_dm_for_dev(). That function isn't called by the IPMMU driver, 
and with Magnus' patches the IPMMU driver calls iommu_group_get_for_dev() on 
ARM64 platforms only (in ipmmu_add_device_dma(), only compiled in when 
CONFIG_IOMMU_DMA is set, which only happens on ARM64).

> Having the additional check up-front just saves going through
> the whole IOVA domain allocation only to tear it all down again when
> get_cookie() returns -ENODEV. You're right that it's not strictly
> necessary (and that I got my DeMorganning wrong), though.
> 
> Robin.
> 
> >> it shouldn't be necessary to split the function at all - we then just
> >> wrap the {get,put}_cookie() bits in "if (type ==  IOMMU_DOMAIN_DMA)" and
> >> in the 32-bit ARM case they just don't run as that can never be true.
> >> 
> >>> -
> >>> - return __ipmmu_domain_alloc(type);
> >>> -}
> >>> -

-- 
Regards,

Laurent Pinchart

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


[PATCH] iommu/ipmmu-vmsa: Unify domain alloc/free implementations

2016-11-10 Thread Laurent Pinchart
The ARM and ARM64 implementations of the IOMMU domain alloc/free
operations can be unified with the correct combination of type checking,
as the domain type can never be IOMMU_DOMAIN_DMA on 32-bit ARM due to
the driver calling iommu_group_get_for_dev() on ARM64 only. Do so.

Signed-off-by: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
---
 drivers/iommu/ipmmu-vmsa.c | 58 +++---
 1 file changed, 14 insertions(+), 44 deletions(-)

Hi Magnus,

This cleans up patch 5/7, making patch 4/7 unnecessary. I proposed squashing
4/7, 5/7 and this one in v7.

diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 11550ac90d65..827aa72aaf28 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -529,16 +529,22 @@ static irqreturn_t ipmmu_irq(int irq, void *dev)
  * IOMMU Operations
  */
 
-static struct iommu_domain *__ipmmu_domain_alloc(unsigned type)
+static struct iommu_domain *ipmmu_domain_alloc(unsigned int type)
 {
struct ipmmu_vmsa_domain *domain;
 
+   if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
+   return NULL;
+
domain = kzalloc(sizeof(*domain), GFP_KERNEL);
if (!domain)
return NULL;
 
spin_lock_init(>lock);
 
+   if (type == IOMMU_DOMAIN_DMA)
+   iommu_get_dma_cookie(>io_domain);
+
return >io_domain;
 }
 
@@ -546,6 +552,9 @@ static void ipmmu_domain_free(struct iommu_domain 
*io_domain)
 {
struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
 
+   if (io_domain->type)
+   iommu_put_dma_cookie(io_domain);
+
/*
 * Free the domain resources. We assume that all devices have already
 * been detached.
@@ -821,14 +830,6 @@ static void ipmmu_remove_device(struct device *dev)
set_archdata(dev, NULL);
 }
 
-static struct iommu_domain *ipmmu_domain_alloc(unsigned type)
-{
-   if (type != IOMMU_DOMAIN_UNMANAGED)
-   return NULL;
-
-   return __ipmmu_domain_alloc(type);
-}
-
 static const struct iommu_ops ipmmu_ops = {
.domain_alloc = ipmmu_domain_alloc,
.domain_free = ipmmu_domain_free,
@@ -847,42 +848,11 @@ static const struct iommu_ops ipmmu_ops = {
 
 #ifdef CONFIG_IOMMU_DMA
 
-static struct iommu_domain *ipmmu_domain_alloc_dma(unsigned type)
-{
-   struct iommu_domain *io_domain = NULL;
-
-   switch (type) {
-   case IOMMU_DOMAIN_UNMANAGED:
-   io_domain = __ipmmu_domain_alloc(type);
-   break;
-
-   case IOMMU_DOMAIN_DMA:
-   io_domain = __ipmmu_domain_alloc(type);
-   if (io_domain)
-   iommu_get_dma_cookie(io_domain);
-   break;
-   }
-
-   return io_domain;
-}
-
-static void ipmmu_domain_free_dma(struct iommu_domain *io_domain)
-{
-   switch (io_domain->type) {
-   case IOMMU_DOMAIN_DMA:
-   iommu_put_dma_cookie(io_domain);
-   /* fall-through */
-   default:
-   ipmmu_domain_free(io_domain);
-   break;
-   }
-}
-
 static int ipmmu_add_device_dma(struct device *dev)
 {
struct iommu_group *group;
 
-   /* only accept devices with iommus property */
+   /* Only accept devices with an iommus property. */
if (of_count_phandle_with_args(dev->of_node, "iommus",
   "#iommu-cells") < 0)
return -ENODEV;
@@ -920,13 +890,13 @@ static struct iommu_group *ipmmu_device_group_dma(struct 
device *dev)
 static int ipmmu_of_xlate_dma(struct device *dev,
  struct of_phandle_args *spec)
 {
-   /* dummy callback to satisfy of_iommu_configure() */
+   /* Dummy callback to satisfy of_iommu_configure(). */
return 0;
 }
 
 static const struct iommu_ops ipmmu_ops = {
-   .domain_alloc = ipmmu_domain_alloc_dma,
-   .domain_free = ipmmu_domain_free_dma,
+   .domain_alloc = ipmmu_domain_alloc,
+   .domain_free = ipmmu_domain_free,
.attach_dev = ipmmu_attach_device,
.detach_dev = ipmmu_detach_device,
    .map = ipmmu_map,
-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v6 06/07] iommu/ipmmu-vmsa: ARM and ARM64 archdata access

2016-11-10 Thread Laurent Pinchart
igned to device %s\n",
> > 
> >  dev_name(dev));
> > 
> > return -EINVAL;
> > 
> > @@ -754,8 +772,7 @@ static int ipmmu_add_device(struct devic
> > 
> >  * - Make the mapping size configurable ? We currently use a 2GB 
mapping
> >  *   at a 1GB offset to ensure that NULL VAs will fault.
> >  */
> > 
> > -   archdata = dev->archdata.iommu;
> > -   mmu = archdata->mmu;
> > +   mmu = to_archdata(dev)->mmu;
> > 
> > if (!mmu->mapping) {
> > 
> > struct dma_iommu_mapping *mapping;
> > 
> > @@ -783,7 +800,7 @@ error:
> >     if (mmu)
> > 
> > arm_iommu_release_mapping(mmu->mapping);
> > 
> > -   dev->archdata.iommu = NULL;
> > +   set_archdata(dev, NULL);
> > 
> > if (!IS_ERR_OR_NULL(group))
> > 
> > iommu_group_remove_device(dev);
> > 
> > @@ -793,7 +810,7 @@ error:
> >  static void ipmmu_remove_device(struct device *dev)
> >  {
> > 
> > -   struct ipmmu_vmsa_archdata *archdata = dev->archdata.iommu;
> > +   struct ipmmu_vmsa_archdata *archdata = to_archdata(dev);
> > 
> > arm_iommu_detach_device(dev);
> > iommu_group_remove_device(dev);
> > 
> > @@ -801,7 +818,7 @@ static void ipmmu_remove_device(struct d
> > 
> > kfree(archdata->utlbs);
> > kfree(archdata);
> > 
> > -   dev->archdata.iommu = NULL;
> > +   set_archdata(dev, NULL);
> > 
> >  }
> >  
> >  static struct iommu_domain *ipmmu_domain_alloc(unsigned type)

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v6 05/07] iommu/ipmmu-vmsa: Add new IOMMU_DOMAIN_DMA ops

2016-11-10 Thread Laurent Pinchart
Hello,

On Thursday 10 Nov 2016 12:42:06 Joerg Roedel wrote:
> On Fri, Oct 21, 2016 at 06:52:53PM +0100, Robin Murphy wrote:
> > > -static struct iommu_domain *ipmmu_domain_alloc(unsigned type)
> > > -{
> > > - if (type != IOMMU_DOMAIN_UNMANAGED)
> > > - return NULL;
> > 
> > I *think* that if we did the initial check thus:
> > if (type != IOMMU_DOMAIN_UNMANAGED ||
> > 
> > (IS_ENABLED(CONFIG_IOMMU_DMA) && type != IOMMU_DOMAIN_DMA))
> > 
> > return NULL;
> > 
> > it shouldn't be necessary to split the function at all - we then just
> > wrap the {get,put}_cookie() bits in "if (type ==  IOMMU_DOMAIN_DMA)" and
> > in the 32-bit ARM case they just don't run as that can never be true.
> 
> This would be a good improvement. Magnus, Robin, can either of you send
> a follow-on patch to implement this suggestion? I have applied these
> patches to my arm/renesas branch (not pushed yet). The patch can be
> based on it.

I like the suggestion too, a patch is on its way.

Joerg, as I've sent a few comments about the other patches (sorry for the late 
review, I got delayed by KS and LPC), the follow-up patch should probably be 
squashed into this one when Magnus addresses my comments. Could you please 
hold off pushing the arm/renesas branch until Magnus replies to this ?

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v6 04/07] iommu/ipmmu-vmsa: Break out domain allocation code

2016-11-10 Thread Laurent Pinchart
Hi Magnus,

Thank you for the patch.

On Thursday 20 Oct 2016 08:36:13 Magnus Damm wrote:
> From: Magnus Damm <damm+rene...@opensource.se>
> 
> Break out the domain allocation code into a separate function.
> This is preparation for future code sharing.
> 
> Signed-off-by: Magnus Damm <damm+rene...@opensource.se>
> Reviewed-by: Joerg Roedel <jroe...@suse.de>

This looks good to me,

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

(assuming my review of the next patches in the series won't make me conclude 
that this patch isn't needed :-))

> ---
> 
>  Changes since V5:
>  - None
> 
>  Changes since V4:
>  - None
> 
>  Changes since V3:
>  - None
> 
>  Changes since V2:
>  - Included this new patch as-is from the following series:
>[PATCH 00/04] iommu/ipmmu-vmsa: IPMMU CONFIG_IOMMU_DMA update
> 
>  drivers/iommu/ipmmu-vmsa.c |   13 +
>  1 file changed, 9 insertions(+), 4 deletions(-)
> 
> --- 0008/drivers/iommu/ipmmu-vmsa.c
> +++ work/drivers/iommu/ipmmu-vmsa.c   2016-09-20 21:56:59.220607110 +0900
> @@ -507,13 +507,10 @@ static irqreturn_t ipmmu_irq(int irq, vo
>   * IOMMU Operations
>   */
> 
> -static struct iommu_domain *ipmmu_domain_alloc(unsigned type)
> +static struct iommu_domain *__ipmmu_domain_alloc(unsigned type)
>  {
>   struct ipmmu_vmsa_domain *domain;
> 
> - if (type != IOMMU_DOMAIN_UNMANAGED)
> - return NULL;
> -
>   domain = kzalloc(sizeof(*domain), GFP_KERNEL);
>   if (!domain)
>   return NULL;
> @@ -523,6 +520,14 @@ static struct iommu_domain *ipmmu_domain
>   return >io_domain;
>  }
> 
> +static struct iommu_domain *ipmmu_domain_alloc(unsigned type)
> +{
> + if (type != IOMMU_DOMAIN_UNMANAGED)
> + return NULL;
> +
> + return __ipmmu_domain_alloc(type);
> +}
> +
>  static void ipmmu_domain_free(struct iommu_domain *io_domain)
>  {
>   struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v6 03/07] iommu/ipmmu-vmsa: Break out utlb parsing code

2016-11-10 Thread Laurent Pinchart
Hi Magnus,

Thank you for the patch.

On Thursday 20 Oct 2016 08:36:03 Magnus Damm wrote:
> From: Magnus Damm <damm+rene...@opensource.se>
> 
> Break out the utlb parsing code and dev_data allocation into a
> separate function. This is preparation for future code sharing.
> 
> Signed-off-by: Magnus Damm <damm+rene...@opensource.se>
> Reviewed-by: Joerg Roedel <jroe...@suse.de>
> ---
> 
>  Changes since V5:
>  - None
> 
>  Changes since V4:
>  - Dropped hunk with fix to apply on top of:
>b1e2afc iommu/ipmmu-vmsa: Fix wrong error handle of ipmmu_add_device
> 
>  Changes since V3:
>  - Initialize "mmu" to NULL, check before accessing
>  - Removed group parameter from ipmmu_init_platform_device()
> 
>  Changes since V2:
>  - Included this new patch from the following series:
>[PATCH 00/04] iommu/ipmmu-vmsa: IPMMU CONFIG_IOMMU_DMA update
>  - Reworked code to fit on top on previous two patches in current series.
> 
>  drivers/iommu/ipmmu-vmsa.c |   58 ++---
>  1 file changed, 37 insertions(+), 21 deletions(-)
> 
> --- 0006/drivers/iommu/ipmmu-vmsa.c
> +++ work/drivers/iommu/ipmmu-vmsa.c   2016-09-20 21:49:34.580607110 +0900
> @@ -647,22 +647,15 @@ static int ipmmu_find_utlbs(struct ipmmu
>   return 0;
>  }
> 
> -static int ipmmu_add_device(struct device *dev)
> +static int ipmmu_init_platform_device(struct device *dev)

The device doesn't have to be a platform device, how about calling this 
ipmmu_init_device_archdata() ?

>  {
>   struct ipmmu_vmsa_archdata *archdata;
>   struct ipmmu_vmsa_device *mmu;
> - struct iommu_group *group = NULL;
>   unsigned int *utlbs;
>   unsigned int i;
>   int num_utlbs;
>   int ret = -ENODEV;
> 
> - if (dev->archdata.iommu) {
> - dev_warn(dev, "IOMMU driver already assigned to device %s\n",
> -  dev_name(dev));
> - return -EINVAL;
> - }
> -
>   /* Find the master corresponding to the device. */
> 
>   num_utlbs = of_count_phandle_with_args(dev->of_node, "iommus",
> @@ -699,6 +692,36 @@ static int ipmmu_add_device(struct devic
>   }
>   }
> 
> + archdata = kzalloc(sizeof(*archdata), GFP_KERNEL);
> + if (!archdata) {
> + ret = -ENOMEM;
> + goto error;
> + }
> +
> + archdata->mmu = mmu;
> + archdata->utlbs = utlbs;
> + archdata->num_utlbs = num_utlbs;
> + dev->archdata.iommu = archdata;
> + return 0;
> +
> +error:
> + kfree(utlbs);
> + return ret;
> +}
> +
> +static int ipmmu_add_device(struct device *dev)
> +{
> + struct ipmmu_vmsa_archdata *archdata;
> + struct ipmmu_vmsa_device *mmu = NULL;
> + struct iommu_group *group;
> + int ret;
> +
> + if (dev->archdata.iommu) {
> + dev_warn(dev, "IOMMU driver already assigned to device %s\n",
> +  dev_name(dev));
> + return -EINVAL;
> + }
> +
>   /* Create a device group and add the device to it. */
>   group = iommu_group_alloc();
>   if (IS_ERR(group)) {
> @@ -716,16 +739,9 @@ static int ipmmu_add_device(struct devic
>   goto error;
>   }
> 
> - archdata = kzalloc(sizeof(*archdata), GFP_KERNEL);
> - if (!archdata) {
> - ret = -ENOMEM;
> + ret = ipmmu_init_platform_device(dev);
> + if (ret < 0)
>   goto error;
> - }
> -
> - archdata->mmu = mmu;
> - archdata->utlbs = utlbs;
> - archdata->num_utlbs = num_utlbs;
> - dev->archdata.iommu = archdata;
> 
>   /*
>* Create the ARM mapping, used by the ARM DMA mapping core to 
allocate
> @@ -736,6 +752,8 @@ static int ipmmu_add_device(struct devic
>* - Make the mapping size configurable ? We currently use a 2GB 
mapping
>*   at a 1GB offset to ensure that NULL VAs will fault.
>*/
> + archdata = dev->archdata.iommu;
> + mmu = archdata->mmu;
>   if (!mmu->mapping) {
>   struct dma_iommu_mapping *mapping;
> 
> @@ -760,10 +778,8 @@ static int ipmmu_add_device(struct devic
>   return 0;
> 
>  error:
> - arm_iommu_release_mapping(mmu->mapping);
> -
> - kfree(dev->archdata.iommu);
> - kfree(utlbs);
> + if (mmu)
> + arm_iommu_release_mapping(mmu->mapping);

Looking at the surrounding code, shouldn't the mapping only be destroyed here 
if it has been created by the same call to the function ? If there's an 
existing mapping for the IPMMU instance and the arm_iommu_attach_device() call 
fails, releasing the mapping seems to be a bug. As the bug isn't introduced by 
this patch, we can fix it separately, but if you end up resubmitting due to 
the first comment you could also add a fix.

> 
>   dev->archdata.iommu = NULL;

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v6 02/07] iommu/ipmmu-vmsa: Rework interrupt code and use bitmap for context

2016-11-10 Thread Laurent Pinchart
ore(>lock, flags);
> +}
> +
>  static void ipmmu_domain_destroy_context(struct ipmmu_vmsa_domain *domain)
>  {
>   /*
> @@ -380,6 +424,7 @@ static void ipmmu_domain_destroy_context
>*/
>   ipmmu_ctx_write(domain, IMCTR, IMCTR_FLUSH);
>   ipmmu_tlb_sync(domain);
> + ipmmu_domain_free_context(domain->mmu, domain->context_id);
>  }
> 
>  /*
> ---
> -- @@ -437,16 +482,25 @@ static irqreturn_t ipmmu_domain_irq(stru
>  static irqreturn_t ipmmu_irq(int irq, void *dev)
>  {
>   struct ipmmu_vmsa_device *mmu = dev;
> - struct iommu_domain *io_domain;
> - struct ipmmu_vmsa_domain *domain;
> + irqreturn_t status = IRQ_NONE;
> + unsigned int i;
> + unsigned long flags;

Nitpicking again I like to arrange variable declarations by decreasing line 
length when there's no reason not to :-)

> - if (!mmu->mapping)
> - return IRQ_NONE;
> + spin_lock_irqsave(>lock, flags);
> +
> + /*
> +  * Check interrupts for all active contexts.
> +  */

This comment holds on a single line too.

With all these small comments addressed,

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> + for (i = 0; i < IPMMU_CTX_MAX; i++) {
> + if (!mmu->domains[i])
> + continue;
> + if (ipmmu_domain_irq(mmu->domains[i]) == IRQ_HANDLED)
> + status = IRQ_HANDLED;
> + }
> 
> - io_domain = mmu->mapping->domain;
> - domain = to_vmsa_domain(io_domain);
> + spin_unlock_irqrestore(>lock, flags);
> 
> - return ipmmu_domain_irq(domain);
> + return status;
>  }
> 
>  /*
> ---
> -- @@ -774,6 +828,8 @@ static int ipmmu_probe(struct platform_d
> 
>   mmu->dev = >dev;
>   mmu->num_utlbs = 32;
> + spin_lock_init(>lock);
> + bitmap_zero(mmu->ctx, IPMMU_CTX_MAX);
> 
>   /* Map I/O memory and request IRQ. */
>   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

-- 
Regards,

Laurent Pinchart

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


Re: [PATCHv9 0/6] dmaengine: rcar-dmac: add iommu support for slave transfers

2016-09-16 Thread Laurent Pinchart
Hi Arnd,

On Friday 16 Sep 2016 14:22:31 Arnd Bergmann wrote:
> On Friday, September 16, 2016 3:09:29 PM CEST Laurent Pinchart wrote:
> >> I wasn't thinking quite that far, though that is also a theoretical
> >> problem. However, the simple solution would be to have a bit in the DMA
> >> specifier let the driver know whether translation is needed or not.
> >> 
> >> The simpler case I was thinking of is where the entire DMA engine
> >> either goes through an IOMMU or doesn't (depending on the integration
> >> into the SoC), so we'd have to find out through some DT property
> >> or compatible string in the DMA enginen driver.
> > 
> > Don't we already get that information from the iommus DT property ? If the
> > DMA engine goes through an IOMMU the property will be set, otherwise it
> > will not.
>
> It depends. A dmaengine typically at least has two DMA masters,
> possibly more. It's likely that some dmaengine implementations are
> connected to RAM through an IOMMU, but have direct access to an
> I/O bus for the slave FIFOs.

Sure, but I expect the DMA engine DT node to list all the relevant IOMMU(s) 
(if any) in the iommus property in a way that allows the DMA engine driver to 
know what IOMMU port is used for what purpose. It will then be up to the DMA 
engine driver to select the right port identifier to pass to the DMA mapping 
API.

I'm not sure how this would work with Robin's proposal of creating one device 
per channel though, as there would still be a single node in DT for the DMA 
engine device. Furthermore, a single channel might indeed have multiple DMA 
masters, not all of them being served by an IOMMU. We would thus still need 
memory port identifiers in the DMA mapping API.

> >>> The problem is a bit broader than that, we'll also have an issue with
> >>> DMA engines that have different channels served by different IOMMUs.
> >> 
> >> Do you mean a theoretical problem, or a chip that you already know
> >> exists?
> > 
> > That's theoretical. The problem I'm facing today is a DMA engine whose
> > channels are served by different ports of the same IOMMU. This works in a
> > suboptimal way because I have to keep all the IOMMU ports enabled
> > regardless of whether they're used or not, as the DMA engine and IOMMU
> > APIs don't carry channel information.
> 
> Ok

-- 
Regards,

Laurent Pinchart

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


Re: [PATCHv9 0/6] dmaengine: rcar-dmac: add iommu support for slave transfers

2016-09-16 Thread Laurent Pinchart
Hi Arnd,

On Friday 16 Sep 2016 14:02:35 Arnd Bergmann wrote:
> On Friday, September 16, 2016 12:48:23 PM CEST Laurent Pinchart wrote:
> > On Friday 16 Sep 2016 11:07:48 Arnd Bergmann wrote:
> >> On Thursday, September 15, 2016 9:56:51 PM CEST Vinod Koul wrote:
> >>> On Wed, Aug 10, 2016 at 11:07:10PM +0530, Vinod Koul wrote:
> >>>> On Wed, Aug 10, 2016 at 01:22:13PM +0200, Niklas Söderlund wrote:
> >>
> >> I had not looked at the series earlier, but this version looks entirely
> >> reasonable to me, so
> >> 
> >> Acked-by: Arnd Bergmann <a...@arndb.de>
> >> 
> >> 
> >> One concern I have is that we might get an awkward situation if we ever
> >> encounter one DMA engine hardware that is used in different systems that
> >> all have an IOMMU, but on some of them the connection between the DMA
> >> master and the slave FIFO bypasses the IOMMU while on others the IOMMU
> >> is required.
> >
> > Do you mean systems where some of the channels of a specific DMA engine go
> > through the IOMMU while others do not ? We indeed have no solution today
> > for such a situation.
> 
> I wasn't thinking quite that far, though that is also a theoretical
> problem. However, the simple solution would be to have a bit in the DMA
> specifier let the driver know whether translation is needed or not.
> 
> The simpler case I was thinking of is where the entire DMA engine
> either goes through an IOMMU or doesn't (depending on the integration
> into the SoC), so we'd have to find out through some DT property
> or compatible string in the DMA enginen driver.

Don't we already get that information from the iommus DT property ? If the DMA 
engine goes through an IOMMU the property will be set, otherwise it will not.

> > The problem is a bit broader than that, we'll also have an issue with DMA
> > engines that have different channels served by different IOMMUs.
> 
> Do you mean a theoretical problem, or a chip that you already know exists?

That's theoretical. The problem I'm facing today is a DMA engine whose 
channels are served by different ports of the same IOMMU. This works in a 
suboptimal way because I have to keep all the IOMMU ports enabled regardless 
of whether they're used or not, as the DMA engine and IOMMU APIs don't carry 
channel information.

> > I recall discussing this in the past with you, and the solution you
> > proposed was to add a channel index to struct dma_attrs seems good to me.
> > To support the case where some channels don't go through an IOMMU we would
> > only need support for null entries in the IOMMUs list associated with a
> > device (for instance in the DT case null entries in the iommus property).
> > 
> > Now I see that struct dma_attrs has been replaced by unsigned long in
> > 
> > commit 00085f1efa387a8ce100e3734920f7639c80caa3
> > Author: Krzysztof Kozlowski <k.kozlow...@samsung.com>
> > Date:   Wed Aug 3 13:46:00 2016 -0700
> > 
> > dma-mapping: use unsigned long for dma_attrs
> > 
> > We still have enough bits to reserve some of them for a channel number,
> > but I'm not very happy with that patch as I can see how a future proposal
> > to handle the channel number through the DMA attributes will get rejected
> > on the grounds of bits starvation then :-(
> 
> Agreed, that can become interesting.

Does the above-mentioned patch really fix a performance, memory consumption or 
other issue ?

-- 
Regards,

Laurent Pinchart

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


Re: [PATCHv9 0/6] dmaengine: rcar-dmac: add iommu support for slave transfers

2016-09-16 Thread Laurent Pinchart
Hi Rubin,

On Friday 16 Sep 2016 11:36:29 Robin Murphy wrote:
> On 16/09/16 10:48, Laurent Pinchart wrote:
> > On Friday 16 Sep 2016 11:07:48 Arnd Bergmann wrote:
> >> On Thursday, September 15, 2016 9:56:51 PM CEST Vinod Koul wrote:
> >>> On Wed, Aug 10, 2016 at 11:07:10PM +0530, Vinod Koul wrote:
> >>>> On Wed, Aug 10, 2016 at 01:22:13PM +0200, Niklas Söderlund wrote:
> >>>>> Hi,
> >>>>> 
> >>>>> This series tries to solve the problem with DMA with device registers
> >>>>> (MMIO registers) that are behind an IOMMU for the rcar-dmac driver. A
> >>>>> recent patch '9575632 (dmaengine: make slave address physical)'
> >>>>> clarifies that DMA slave address provided by clients is the physical
> >>>>> address. This puts the task of mapping the DMA slave address from a
> >>>>> phys_addr_t to a dma_addr_t on the DMA engine.
> >>>>> 
> >>>>> Without an IOMMU this is easy since the phys_addr_t and dma_addr_t are
> >>>>> the same and no special care is needed. However if you have a IOMMU
> >>>>> you need to map the DMA slave phys_addr_t to a dma_addr_t using
> >>>>> something like this.
> >>>>> 
> >>>>> This series is based on top of v4.8-rc1. And I'm hoping to be able to
> >>>>> collect a Ack from Russell King on patch 4/6 that adds the ARM
> >>>>> specific part and then be able to take the whole series through the
> >>>>> dmaengine tree. If this is not the best route I'm more then happy to
> >>>>> do it another way.
> >>>>> 
> >>>>> It's tested on a Koelsch with CONFIG_IPMMU_VMSA and by enabling the
> >>>>> ipmmu_ds node in r8a7791.dtsi. I verified operation by interacting
> >>>>> with /dev/mmcblk1, i2c and the serial console which are devices behind
> >>>>> the iommu.
> >>>> 
> >>>> As I said in last one, the dmaengine parts look fine to me. But to go
> >>>> thru dmaengine tree I would need ACK on non dmaengine patches.
> >>> 
> >>> I havent heard back from this one and I am inclined to merge this one
> >>> now. If anyone has any objects, please speak up now...
> >>> 
> >>> Also ACKs welcome...
> >> 
> >> I had not looked at the series earlier, but this version looks entirely
> >> reasonable to me, so
> >> 
> >> Acked-by: Arnd Bergmann <a...@arndb.de>
> >> 
> >> 
> >> One concern I have is that we might get an awkward situation if we ever
> >> encounter one DMA engine hardware that is used in different systems that
> >> all have an IOMMU, but on some of them the connection between the DMA
> >> master and the slave FIFO bypasses the IOMMU while on others the IOMMU
> >> is required.
> >
> > Do you mean systems where some of the channels of a specific DMA engine go
> > through the IOMMU while others do not ? We indeed have no solution today
> > for such a situation.
> > 
> > The problem is a bit broader than that, we'll also have an issue with DMA
> > engines that have different channels served by different IOMMUs. I recall
> > discussing this in the past with you, and the solution you proposed was to
> > add a channel index to struct dma_attrs seems good to me. To support the
> > case where some channels don't go through an IOMMU we would only need
> > support for null entries in the IOMMUs list associated with a device (for
> > instance in the DT case null entries in the iommus property).
> 
> I think at that point we just create the channels as child devices of
> the main dmaengine device so they each get their own DMA ops, and can do
> whatever. The Qualcomm HIDMA driver already does that for a very similar
> reason (so that the IOMMU can map individual channels into different
> guest VMs).

That's another option, but it seems more like a workaround to me, instead of a 
proper solution to fix the more global problem of multiple memory paths within 
a single device. I have other hardware devices that can act as bus masters 
through different paths (for instance a display-related device that fetches 
data and commands through different paths). Luckily so far all those paths are 
served by the same IOMMU, but there's no guarantee this will remain true in 
the future. Furthermore, even today, the IOMMU connected to that device has 
the ability to selectively enable and disable its ports. I have to keep them 
all enabled due to the lack of ch

Re: [PATCHv9 0/6] dmaengine: rcar-dmac: add iommu support for slave transfers

2016-09-16 Thread Laurent Pinchart
Hi Arnd,

On Friday 16 Sep 2016 11:07:48 Arnd Bergmann wrote:
> On Thursday, September 15, 2016 9:56:51 PM CEST Vinod Koul wrote:
> > On Wed, Aug 10, 2016 at 11:07:10PM +0530, Vinod Koul wrote:
> >> On Wed, Aug 10, 2016 at 01:22:13PM +0200, Niklas Söderlund wrote:
> >>> Hi,
> >>> 
> >>> This series tries to solve the problem with DMA with device registers
> >>> (MMIO registers) that are behind an IOMMU for the rcar-dmac driver. A
> >>> recent patch '9575632 (dmaengine: make slave address physical)'
> >>> clarifies that DMA slave address provided by clients is the physical
> >>> address. This puts the task of mapping the DMA slave address from a
> >>> phys_addr_t to a dma_addr_t on the DMA engine.
> >>> 
> >>> Without an IOMMU this is easy since the phys_addr_t and dma_addr_t are
> >>> the same and no special care is needed. However if you have a IOMMU
> >>> you need to map the DMA slave phys_addr_t to a dma_addr_t using
> >>> something like this.
> >>> 
> >>> This series is based on top of v4.8-rc1. And I'm hoping to be able to
> >>> collect a Ack from Russell King on patch 4/6 that adds the ARM
> >>> specific part and then be able to take the whole series through the
> >>> dmaengine tree. If this is not the best route I'm more then happy to
> >>> do it another way.
> >>> 
> >>> It's tested on a Koelsch with CONFIG_IPMMU_VMSA and by enabling the
> >>> ipmmu_ds node in r8a7791.dtsi. I verified operation by interacting
> >>> with /dev/mmcblk1, i2c and the serial console which are devices behind
> >>> the iommu.
> >> 
> >> As I said in last one, the dmaengine parts look fine to me. But to go
> >> thru dmaengine tree I would need ACK on non dmaengine patches.
> > 
> > I havent heard back from this one and I am inclined to merge this one now.
> > If anyone has any objects, please speak up now...
> > 
> > Also ACKs welcome...
> 
> I had not looked at the series earlier, but this version looks entirely
> reasonable to me, so
> 
> Acked-by: Arnd Bergmann <a...@arndb.de>
> 
> 
> One concern I have is that we might get an awkward situation if we ever
> encounter one DMA engine hardware that is used in different systems that all
> have an IOMMU, but on some of them the connection between the DMA master and
> the slave FIFO bypasses the IOMMU while on others the IOMMU is required.

Do you mean systems where some of the channels of a specific DMA engine go 
through the IOMMU while others do not ? We indeed have no solution today for 
such a situation.

The problem is a bit broader than that, we'll also have an issue with DMA 
engines that have different channels served by different IOMMUs. I recall 
discussing this in the past with you, and the solution you proposed was to add 
a channel index to struct dma_attrs seems good to me. To support the case 
where some channels don't go through an IOMMU we would only need support for 
null entries in the IOMMUs list associated with a device (for instance in the 
DT case null entries in the iommus property).

Now I see that struct dma_attrs has been replaced by unsigned long in

commit 00085f1efa387a8ce100e3734920f7639c80caa3
Author: Krzysztof Kozlowski <k.kozlow...@samsung.com>
Date:   Wed Aug 3 13:46:00 2016 -0700

dma-mapping: use unsigned long for dma_attrs

We still have enough bits to reserve some of them for a channel number, but 
I'm not very happy with that patch as I can see how a future proposal to 
handle the channel number through the DMA attributes will get rejected on the 
grounds of bits starvation then :-(

> I don't have any idea for how this could be handled in a generic way, so my
> best answer here is to hope we never get there, and if we do, handle it
> using some local hack in the driver.

-- 
Regards,

Laurent Pinchart

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


Re: [PATCHv9 4/6] arm: dma-mapping: add {map, unmap}_resource for iommu ops

2016-09-05 Thread Laurent Pinchart
Hello Niklas and Russell,

On Tuesday 23 Aug 2016 17:31:36 Niklas Söderlund wrote:
> Hi Russell,
> 
> If you have the time can you please have a look at this patch? This
> series have been out for some time now and Vinod is willing to take it
> through the dmaengine tree but a ACK is needed on this patch from you
> first.

I've reviewed and acked all the patches touching the DMA mapping API (1/6 to 
4/6). Russell, if you can find a bit of time to review this one it would be 
very appreciated.

> On 2016-08-10 13:22:17 +0200, Niklas Söderlund wrote:
> > Add methods to map/unmap device resources addresses for dma_map_ops that
> > are IOMMU aware. This is needed to map a device MMIO register from a
> > physical address.
> > 
> > Signed-off-by: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>
> > Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
> > ---
> > 
> >  arch/arm/mm/dma-mapping.c | 63 ++
> >  1 file changed, 63 insertions(+)
> > 
> > diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> > index c6834c0..746eb29 100644
> > --- a/arch/arm/mm/dma-mapping.c
> > +++ b/arch/arm/mm/dma-mapping.c
> > @@ -2014,6 +2014,63 @@ static void arm_iommu_unmap_page(struct device
> > *dev, dma_addr_t handle,> 
> > __free_iova(mapping, iova, len);
> >  
> >  }
> > 
> > +/**
> > + * arm_iommu_map_resource - map a device resource for DMA
> > + * @dev: valid struct device pointer
> > + * @phys_addr: physical address of resource
> > + * @size: size of resource to map
> > + * @dir: DMA transfer direction
> > + */
> > +static dma_addr_t arm_iommu_map_resource(struct device *dev,
> > +   phys_addr_t phys_addr, size_t size,
> > +   enum dma_data_direction dir, unsigned long attrs)
> > +{
> > +   struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
> > +   dma_addr_t dma_addr;
> > +   int ret, prot;
> > +   phys_addr_t addr = phys_addr & PAGE_MASK;
> > +   unsigned int offset = phys_addr & ~PAGE_MASK;
> > +   size_t len = PAGE_ALIGN(size + offset);
> > +
> > +   dma_addr = __alloc_iova(mapping, len);
> > +   if (dma_addr == DMA_ERROR_CODE)
> > +   return dma_addr;
> > +
> > +   prot = __dma_direction_to_prot(dir) | IOMMU_MMIO;
> > +
> > +   ret = iommu_map(mapping->domain, dma_addr, addr, len, prot);
> > +   if (ret < 0)
> > +   goto fail;
> > +
> > +   return dma_addr + offset;
> > +fail:
> > +   __free_iova(mapping, dma_addr, len);
> > +   return DMA_ERROR_CODE;
> > +}
> > +
> > +/**
> > + * arm_iommu_unmap_resource - unmap a device DMA resource
> > + * @dev: valid struct device pointer
> > + * @dma_handle: DMA address to resource
> > + * @size: size of resource to map
> > + * @dir: DMA transfer direction
> > + */
> > +static void arm_iommu_unmap_resource(struct device *dev, dma_addr_t
> > dma_handle, +   size_t size, enum dma_data_direction dir,
> > +   unsigned long attrs)
> > +{
> > +   struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
> > +   dma_addr_t iova = dma_handle & PAGE_MASK;
> > +   unsigned int offset = dma_handle & ~PAGE_MASK;
> > +   size_t len = PAGE_ALIGN(size + offset);
> > +
> > +   if (!iova)
> > +   return;
> > +
> > +   iommu_unmap(mapping->domain, iova, len);
> > +   __free_iova(mapping, iova, len);
> > +}
> > +
> > 
> >  static void arm_iommu_sync_single_for_cpu(struct device *dev,
> >  
> > dma_addr_t handle, size_t size, enum dma_data_direction dir)
> >  
> >  {
> > 
> > @@ -2057,6 +2114,9 @@ struct dma_map_ops iommu_ops = {
> > 
> > .unmap_sg   = arm_iommu_unmap_sg,
> > .sync_sg_for_cpu= arm_iommu_sync_sg_for_cpu,
> > .sync_sg_for_device = arm_iommu_sync_sg_for_device,
> > 
> > +
> > +   .map_resource   = arm_iommu_map_resource,
> > +   .unmap_resource = arm_iommu_unmap_resource,
> > 
> >  };
> >  
> >  struct dma_map_ops iommu_coherent_ops = {
> > 
> > @@ -2070,6 +2130,9 @@ struct dma_map_ops iommu_coherent_ops = {
> > 
> > .map_sg = arm_coherent_iommu_map_sg,
> > .unmap_sg   = arm_coherent_iommu_unmap_sg,
> > 
> > +
> > +   .map_resource   = arm_iommu_map_resource,
> > +   .unmap_resource = arm_iommu_unmap_resource,
> > 
> >  };
> >  
> >  /**

-- 
Regards,

Laurent Pinchart

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


Re: [PATCHv9 6/6] dmaengine: rcar-dmac: add iommu support for slave transfers

2016-09-05 Thread Laurent Pinchart
rn rcar_dmac_chan_prep_sg(rchan, sgl, sg_len, rchan->map.addr,
> dir, flags, false);
>  }
> 
> @@ -1061,7 +1127,6 @@ rcar_dmac_prep_dma_cyclic(struct dma_chan *chan,
> dma_addr_t buf_addr, struct rcar_dmac_chan *rchan =
> to_rcar_dmac_chan(chan);
>   struct dma_async_tx_descriptor *desc;
>   struct scatterlist *sgl;
> - dma_addr_t dev_addr;
>   unsigned int sg_len;
>   unsigned int i;
> 
> @@ -1073,6 +1138,9 @@ rcar_dmac_prep_dma_cyclic(struct dma_chan *chan,
> dma_addr_t buf_addr, return NULL;
>   }
> 
> + if (rcar_dmac_map_slave_addr(chan, dir))
> + return NULL;
> +
>   sg_len = buf_len / period_len;
>   if (sg_len > RCAR_DMAC_MAX_SG_LEN) {
>   dev_err(chan->device->dev,
> @@ -1100,9 +1168,7 @@ rcar_dmac_prep_dma_cyclic(struct dma_chan *chan,
> dma_addr_t buf_addr, sg_dma_len([i]) = period_len;
>   }
> 
> - dev_addr = dir == DMA_DEV_TO_MEM
> -  ? rchan->src.slave_addr : rchan->dst.slave_addr;
> - desc = rcar_dmac_chan_prep_sg(rchan, sgl, sg_len, dev_addr,
> + desc = rcar_dmac_chan_prep_sg(rchan, sgl, sg_len, rchan->map.addr,
> dir, flags, true);
> 
>   kfree(sgl);

-- 
Regards,

Laurent Pinchart

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


Re: [PATCHv9 3/6] dma-mapping: add dma_{map,unmap}_resource

2016-09-05 Thread Laurent Pinchart
Hi Niklas,

Thank you for the patch.

On Wednesday 10 Aug 2016 13:22:16 Niklas Söderlund wrote:
> Map/Unmap a device MMIO resource from a physical address. If no dma_map_ops
> method is available the operation is a no-op.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>

Acked-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> ---
>  Documentation/DMA-API.txt   | 22 +-
>  include/linux/dma-mapping.h | 36 
>  2 files changed, 53 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
> index 1d26eeb6..6b20128 100644
> --- a/Documentation/DMA-API.txt
> +++ b/Documentation/DMA-API.txt
> @@ -277,14 +277,26 @@ and  parameters are provided to do partial page
> mapping, it is recommended that you never use these unless you really know
> what the cache width is.
> 
> +dma_addr_t
> +dma_map_resource(struct device *dev, phys_addr_t phys_addr, size_t size,
> +  enum dma_data_direction dir, unsigned long attrs)
> +
> +void
> +dma_unmap_resource(struct device *dev, dma_addr_t addr, size_t size,
> +enum dma_data_direction dir, unsigned long attrs)
> +
> +API for mapping and unmapping for MMIO resources. All the notes and
> +warnings for the other mapping APIs apply here. The API should only be
> +used to map device MMIO resources, mapping of RAM is not permitted.
> +
>  int
>  dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
> 
> -In some circumstances dma_map_single() and dma_map_page() will fail to
> create -a mapping. A driver can check for these errors by testing the
> returned -DMA address with dma_mapping_error(). A non-zero return value
> means the mapping -could not be created and the driver should take
> appropriate action (e.g. -reduce current DMA mapping usage or delay and try
> again later).
> +In some circumstances dma_map_single(), dma_map_page() and
> dma_map_resource() +will fail to create a mapping. A driver can check for
> these errors by testing +the returned DMA address with dma_mapping_error().
> A non-zero return value +means the mapping could not be created and the
> driver should take appropriate +action (e.g. reduce current DMA mapping
> usage or delay and try again later).
> 
>   int
>   dma_map_sg(struct device *dev, struct scatterlist *sg,
> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index e3bd27f..9a07882 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -264,6 +264,42 @@ static inline void dma_unmap_page(struct device *dev,
> dma_addr_t addr, debug_dma_unmap_page(dev, addr, size, dir, false);
>  }
> 
> +static inline dma_addr_t dma_map_resource(struct device *dev,
> +   phys_addr_t phys_addr,
> +   size_t size,
> +   enum dma_data_direction dir,
> +   unsigned long attrs)
> +{
> + struct dma_map_ops *ops = get_dma_ops(dev);
> + unsigned long pfn = __phys_to_pfn(phys_addr);
> + dma_addr_t addr;
> +
> + BUG_ON(!valid_dma_direction(dir));
> +
> + /* Don't allow RAM to be mapped */
> + BUG_ON(pfn_valid(pfn));
> +
> + addr = phys_addr;
> + if (ops->map_resource)
> + addr = ops->map_resource(dev, phys_addr, size, dir, attrs);
> +
> + debug_dma_map_resource(dev, phys_addr, size, dir, addr);
> +
> + return addr;
> +}
> +
> +static inline void dma_unmap_resource(struct device *dev, dma_addr_t addr,
> +   size_t size, enum dma_data_direction 
dir,
> +   unsigned long attrs)
> +{
> + struct dma_map_ops *ops = get_dma_ops(dev);
> +
> + BUG_ON(!valid_dma_direction(dir));
> + if (ops->unmap_resource)
> + ops->unmap_resource(dev, addr, size, dir, attrs);
> + debug_dma_unmap_resource(dev, addr, size, dir);
> +}
> +
>  static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t
> addr, size_t size,
>  enum dma_data_direction dir)

-- 
Regards,

Laurent Pinchart

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


Re: [PATCHv9 2/6] dma-debug: add support for resource mappings

2016-09-05 Thread Laurent Pinchart
Hi Niklas,

Thank you for the patch.

On Wednesday 10 Aug 2016 13:22:15 Niklas Söderlund wrote:
> A MMIO mapped resource can not be represented by a struct page so a new
> debug type is needed to handle this. This patch add such type and
> functionality to add/remove entries and how to translate them to a
> physical address.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>

Acked-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> ---
>  include/linux/dma-debug.h | 19 +
>  lib/dma-debug.c   | 52 +--
>  2 files changed, 69 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
> index fe8cb61..c7d844f 100644
> --- a/include/linux/dma-debug.h
> +++ b/include/linux/dma-debug.h
> @@ -56,6 +56,13 @@ extern void debug_dma_alloc_coherent(struct device *dev,
> size_t size, extern void debug_dma_free_coherent(struct device *dev, size_t
> size, void *virt, dma_addr_t addr);
> 
> +extern void debug_dma_map_resource(struct device *dev, phys_addr_t addr,
> +size_t size, int direction,
> +dma_addr_t dma_addr);
> +
> +extern void debug_dma_unmap_resource(struct device *dev, dma_addr_t
> dma_addr, +size_t size, int direction);
> +
>  extern void debug_dma_sync_single_for_cpu(struct device *dev,
> dma_addr_t dma_handle, size_t size,
> int direction);
> @@ -141,6 +148,18 @@ static inline void debug_dma_free_coherent(struct
> device *dev, size_t size, {
>  }
> 
> +static inline void debug_dma_map_resource(struct device *dev, phys_addr_t
> addr, + size_t size, int direction,
> +   dma_addr_t dma_addr)
> +{
> +}
> +
> +static inline void debug_dma_unmap_resource(struct device *dev,
> + dma_addr_t dma_addr, size_t size,
> + int direction)
> +{
> +}
> +
>  static inline void debug_dma_sync_single_for_cpu(struct device *dev,
>dma_addr_t dma_handle,
>size_t size, int direction)
> diff --git a/lib/dma-debug.c b/lib/dma-debug.c
> index fcfa193..2ba086b 100644
> --- a/lib/dma-debug.c
> +++ b/lib/dma-debug.c
> @@ -43,6 +43,7 @@ enum {
>   dma_debug_page,
>   dma_debug_sg,
>   dma_debug_coherent,
> + dma_debug_resource,
>  };
> 
>  enum map_err_types {
> @@ -150,8 +151,9 @@ static const char *const maperr2str[] = {
>   [MAP_ERR_CHECKED] = "dma map error checked",
>  };
> 
> -static const char *type2name[4] = { "single", "page",
> - "scather-gather", "coherent" };
> +static const char *type2name[5] = { "single", "page",
> + "scather-gather", "coherent",
> + "resource" };
> 
>  static const char *dir2name[4] = { "DMA_BIDIRECTIONAL", "DMA_TO_DEVICE",
>  "DMA_FROM_DEVICE", "DMA_NONE" };
> @@ -399,6 +401,9 @@ static void hash_bucket_del(struct dma_debug_entry
> *entry)
> 
>  static unsigned long long phys_addr(struct dma_debug_entry *entry)
>  {
> + if (entry->type == dma_debug_resource)
> + return __pfn_to_phys(entry->pfn) + entry->offset;
> +
>   return page_to_phys(pfn_to_page(entry->pfn)) + entry->offset;
>  }
> 
> @@ -1495,6 +1500,49 @@ void debug_dma_free_coherent(struct device *dev,
> size_t size, }
>  EXPORT_SYMBOL(debug_dma_free_coherent);
> 
> +void debug_dma_map_resource(struct device *dev, phys_addr_t addr, size_t
> size, +   int direction, dma_addr_t dma_addr)
> +{
> + struct dma_debug_entry *entry;
> +
> + if (unlikely(dma_debug_disabled()))
> + return;
> +
> + entry = dma_entry_alloc();
> + if (!entry)
> + return;
> +
> + entry->type = dma_debug_resource;
> + entry->dev  = dev;
> + entry->pfn  = __phys_to_pfn(addr);
> + entry->offset   = offset_in_page(addr);
> + entry->size = size;
> + entry->dev_addr = dma_addr;
> + entry->direction= direction;
> + entry->map_err_type = MAP_ERR_NOT_CHECKED;
> +
> + add_dma

Re: [PATCH 5/8] drivers: platform: Configure dma operations at probe time

2016-08-16 Thread Laurent Pinchart
Hi Sricharan,

Thank you for the patch.

On Tuesday 09 Aug 2016 04:19:07 Sricharan R wrote:
> Configuring DMA ops at probe time will allow deferring device probe when
> the IOMMU isn't available yet.
> 
> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
> ---
>  drivers/base/dd.c   | 11 +++
>  drivers/base/dma-mapping.c  | 11 +++
>  include/linux/dma-mapping.h |  3 +++
>  3 files changed, 25 insertions(+)
> 
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index 16688f5..b9978af 100644
> --- a/drivers/base/dd.c
> +++ b/drivers/base/dd.c
> @@ -19,6 +19,7 @@
> 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -353,6 +354,10 @@ static int really_probe(struct device *dev, struct
> device_driver *drv) if (ret)
>   goto pinctrl_bind_failed;
> 
> + ret = dma_configure_ops(dev);

Your patch doesn't remove the of_dma_configure_ops() from 
of_platform_device_create_pdata(). Unless I'm mistaken, you will then end up 
configuring the DMA ops twice, which at least on ARM will be a no-op the 
second time:

(arch_setup_dma_ops)

/*
 * Don't override the dma_ops if they have already been set. Ideally
 * this should be the only location where dma_ops are set, remove this
 * check when all other callers of set_dma_ops will have disappeared.
 */
if (dev->archdata.dma_ops)
return;

For the same reason I'm wondering whether you shouldn't also remove the 
of_dma_configure_ops() call from of_amba_device_create() (I don't remember why 
I left it there in my original patch series).

> + if (ret)
> + goto dma_failed;
> +
>   if (driver_sysfs_add(dev)) {
>   printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
>   __func__, dev_name(dev));
> @@ -394,7 +399,10 @@ static int really_probe(struct device *dev, struct
> device_driver *drv) drv->bus->name, __func__, dev_name(dev), drv->name);
>   goto done;
> 
> +
>  probe_failed:
> + dma_deconfigure(dev);
> +dma_failed:
>   if (dev->bus)
>   blocking_notifier_call_chain(>bus->p->bus_notifier,
>BUS_NOTIFY_DRIVER_NOT_BOUND, 
dev);
> @@ -780,6 +788,9 @@ static void __device_release_driver(struct device *dev)
>   dev->bus->remove(dev);
>   else if (drv->remove)
>   drv->remove(dev);
> +
> + dma_deconfigure(dev);
> +
>   devres_release_all(dev);
>   dev->driver = NULL;
>   dev_set_drvdata(dev, NULL);
> diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
> index d799662..ccc1c6e 100644
> --- a/drivers/base/dma-mapping.c
> +++ b/drivers/base/dma-mapping.c
> @@ -10,6 +10,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
> 
> @@ -166,6 +167,16 @@ void dmam_free_noncoherent(struct device *dev, size_t
> size, void *vaddr, }
>  EXPORT_SYMBOL(dmam_free_noncoherent);
> 
> +int dma_configure_ops(struct device *dev)
> +{
> + return of_dma_configure_ops(dev, dev->of_node);
> +}
> +
> +void dma_deconfigure(struct device *dev)
> +{
> + of_dma_deconfigure(dev);
> +}
> +
>  #ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
> 
>  static void dmam_coherent_decl_release(struct device *dev, void *res)
> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index 71c1b21..a49aac9 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -613,6 +613,9 @@ dma_mark_declared_memory_occupied(struct device *dev,
>  }
>  #endif /* CONFIG_HAVE_GENERIC_DMA_COHERENT */
> 
> +int dma_configure_ops(struct device *dev);
> +void dma_deconfigure(struct device *dev);
> +
>  /*
>   * Managed DMA API
>   */

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH 3/3] iommu/ipmmu-vmsa: Hook up r8a7796 DT matching code

2016-08-09 Thread Laurent Pinchart
On Tuesday 09 Aug 2016 16:17:57 Laurent Pinchart wrote:
> On Wednesday 08 Jun 2016 18:12:31 Magnus Damm wrote:
> > On Wed, Jun 8, 2016 at 5:48 PM, Laurent Pinchart wrote:
> >> On Wednesday 08 Jun 2016 09:04:17 Geert Uytterhoeven wrote:
> >>> On Wed, Jun 8, 2016 at 2:18 AM, Laurent Pinchart wrote:
> >>>>> --- 0031/drivers/iommu/ipmmu-vmsa.c
> >>>>> +++ work/drivers/iommu/ipmmu-vmsa.c   2016-06-06 11:19:40.210607110
> 
> [snip]
> 
> >>>>> @@ -1268,6 +1271,8 @@ IOMMU_OF_DECLARE(ipmmu_vmsa_iommu_of, "r
> >>>>>ipmmu_vmsa_iommu_of_setup);
> >>>>>  IOMMU_OF_DECLARE(ipmmu_r8a7795_iommu_of, "renesas,ipmmu-r8a7795",
> >>>>>ipmmu_vmsa_iommu_of_setup);
> >>>>> +IOMMU_OF_DECLARE(ipmmu_r8a7796_iommu_of, "renesas,ipmmu-r8a7796",
> >>>>> +  ipmmu_vmsa_iommu_of_setup);
> >>>> 
> >>>> How about a Gen3 generic compatible string in addition to the
> >>>> SoC-specific ones ?
> >>> 
> >>> Do we want to specify the number of utlbs here?
> >>> Does it differ between r8a7795, r8a7796, and future members?
> >> 
> >> It differs between IPMMU instances on a given SoC, so if we want to
> >> specify it it should be a DT property.
> > 
> > Can you please point out which documentation that says it varies with
> > IPMMU instance?
> > 
> > Based on IMUCTRn register description "H3-ES1" has 0-31 range while
> > "Others" have 0-47.
> 
> The maximum number of uTLBs is indeed the same according to that part of the
> documentation, but not all uTLBs are available in all IPMMU instances. We
> even have holes in the uTLB ranges, maybe a mask would be more appropriate.

And the other option is of course to ignore that and accept any uTLB number, 
in which case we will rely on the IOMMU bus master node providing correct 
information.

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH 3/3] iommu/ipmmu-vmsa: Hook up r8a7796 DT matching code

2016-08-09 Thread Laurent Pinchart
Hi Magnus,

On Wednesday 08 Jun 2016 18:12:31 Magnus Damm wrote:
> On Wed, Jun 8, 2016 at 5:48 PM, Laurent Pinchart wrote:
> > On Wednesday 08 Jun 2016 09:04:17 Geert Uytterhoeven wrote:
> >> On Wed, Jun 8, 2016 at 2:18 AM, Laurent Pinchart wrote:
> >>>> --- 0031/drivers/iommu/ipmmu-vmsa.c
> >>>> +++ work/drivers/iommu/ipmmu-vmsa.c   2016-06-06 11:19:40.210607110

[snip]

> >>>> @@ -1268,6 +1271,8 @@ IOMMU_OF_DECLARE(ipmmu_vmsa_iommu_of, "r
> >>>>ipmmu_vmsa_iommu_of_setup);
> >>>>  IOMMU_OF_DECLARE(ipmmu_r8a7795_iommu_of, "renesas,ipmmu-r8a7795",
> >>>>ipmmu_vmsa_iommu_of_setup);
> >>>> +IOMMU_OF_DECLARE(ipmmu_r8a7796_iommu_of, "renesas,ipmmu-r8a7796",
> >>>> +  ipmmu_vmsa_iommu_of_setup);
> >>> 
> >>> How about a Gen3 generic compatible string in addition to the
> >>> SoC-specific ones ?
> >> 
> >> Do we want to specify the number of utlbs here?
> >> Does it differ between r8a7795, r8a7796, and future members?
> > 
> > It differs between IPMMU instances on a given SoC, so if we want to
> > specify it it should be a DT property.
> 
> Can you please point out which documentation that says it varies with
> IPMMU instance?
> 
> Based on IMUCTRn register description "H3-ES1" has 0-31 range while
> "Others" have 0-47.

The maximum number of uTLBs is indeed the same according to that part of the 
documentation, but not all uTLBs are available in all IPMMU instances. We even 
have holes in the uTLB ranges, maybe a mask would be more appropriate.

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH 3/3] iommu/ipmmu-vmsa: Hook up r8a7796 DT matching code

2016-06-08 Thread Laurent Pinchart
Hi Geert,

On Wednesday 08 Jun 2016 09:04:17 Geert Uytterhoeven wrote:
> On Wed, Jun 8, 2016 at 2:18 AM, Laurent Pinchart wrote:
> >> --- 0031/drivers/iommu/ipmmu-vmsa.c
> >> +++ work/drivers/iommu/ipmmu-vmsa.c   2016-06-06 11:19:40.210607110 +0900
> >> @@ -1074,7 +1074,7 @@ static const struct ipmmu_features ipmmu
> >>   .twobit_imttbcr_sl0 = false,
 >>  };
> >> 
> >> -static const struct ipmmu_features ipmmu_features_r8a7795 = {
> >> +static const struct ipmmu_features ipmmu_features_rcar_gen3 = {
> >>   .use_ns_alias_offset = false,
> >>   .has_cache_leaf_nodes = true,
> >>   .has_eight_ctx = true,
> >> @@ -1088,7 +1088,10 @@ static const struct of_device_id ipmmu_o
> >>   .data = _features_default,
> >>   }, {
> >>   .compatible = "renesas,ipmmu-r8a7795",
> >> - .data = _features_r8a7795,
> >> + .data = _features_rcar_gen3,
> >> + }, {
> >> + .compatible = "renesas,ipmmu-r8a7796",
> >> + .data = _features_rcar_gen3,
> >>   }, {
> >>   /* Terminator */
> >>   },
> >> @@ -1268,6 +1271,8 @@ IOMMU_OF_DECLARE(ipmmu_vmsa_iommu_of, "r
> >>ipmmu_vmsa_iommu_of_setup);
> >>  IOMMU_OF_DECLARE(ipmmu_r8a7795_iommu_of, "renesas,ipmmu-r8a7795",
> >>ipmmu_vmsa_iommu_of_setup);
> >> +IOMMU_OF_DECLARE(ipmmu_r8a7796_iommu_of, "renesas,ipmmu-r8a7796",
> >> +  ipmmu_vmsa_iommu_of_setup);
> > 
> > How about a Gen3 generic compatible string in addition to the SoC-specific
> > ones ?
> 
> Do we want to specify the number of utlbs here?
> Does it differ between r8a7795, r8a7796, and future members?

It differs between IPMMU instances on a given SoC, so if we want to specify it 
it should be a DT property.

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v2 06/11] iommu/ipmmu-vmsa: Teach xlate() to skip disabled iommus

2016-06-07 Thread Laurent Pinchart
Hi Magnus,

Thank you for the patch.

I agree with the comment that Geert made on v1, and I haven't seen you 
replying to it or addressing it.

Quoting Geert,

"I think this should be handled in drivers/iommu/of_iommu.c:of_iommu_init()
instead, cfr. commit 3e5dd6f6e690048d ("clk: Ignore disabled DT clock
providers")."

On Monday 06 Jun 2016 12:58:22 Magnus Damm wrote:
> From: Magnus Damm <damm+rene...@opensource.se>
> 
> The ->xlate() call gets invoked even though the iommu
> device has status = "disabled" in DT, so make sure we
> skip over disabled devices.
> 
> In my mind it would make sense to have this at some
> shared level, but I guess some users may want to
> configure the iommu regardless of DT state.
> 
> Signed-off-by: Magnus Damm <damm+rene...@opensource.se>
> ---
> 
>  Changes since V1:
>  - Reworked slightly to fit on top of updated patch order
> 
>  drivers/iommu/ipmmu-vmsa.c |8 +++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> --- 0017/drivers/iommu/ipmmu-vmsa.c
> +++ work/drivers/iommu/ipmmu-vmsa.c   2016-06-06 10:58:18.530607110 +0900
> @@ -1001,7 +1001,13 @@ static struct iommu_group *ipmmu_device_
>  static int ipmmu_of_xlate_dma(struct device *dev,
> struct of_phandle_args *spec)
>  {
> - /* dummy callback to satisfy of_iommu_configure() */
> + /* If the IPMMU device is disabled in DT then return error
> +  * to make sure the of_iommu code does not install ops
> +  * even though the iommu device is disabled
> +      */
> + if (!of_device_is_available(spec->np))
> + return -ENODEV;
> +
>   return 0;
>  }

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH 3/3] iommu/ipmmu-vmsa: Hook up r8a7796 DT matching code

2016-06-07 Thread Laurent Pinchart
Hi Magnus,

Thank you for the patch.

On Tuesday 07 Jun 2016 12:39:45 Magnus Damm wrote:
> From: Magnus Damm <damm+rene...@opensource.se>
> 
> Support the r8a7796 IPMMU by sharing feature flags between
> r8a7795 and r8a7796. Also update IOMMU_OF_DECLARE to hook
> up the updated compat string.
> 
> Signed-off-by: Magnus Damm <damm+rene...@opensource.se>
> ---
> 
>  drivers/iommu/ipmmu-vmsa.c |9 +++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> --- 0031/drivers/iommu/ipmmu-vmsa.c
> +++ work/drivers/iommu/ipmmu-vmsa.c   2016-06-06 11:19:40.210607110 +0900
> @@ -1074,7 +1074,7 @@ static const struct ipmmu_features ipmmu
>   .twobit_imttbcr_sl0 = false,
>  };
> 
> -static const struct ipmmu_features ipmmu_features_r8a7795 = {
> +static const struct ipmmu_features ipmmu_features_rcar_gen3 = {
>   .use_ns_alias_offset = false,
>   .has_cache_leaf_nodes = true,
>   .has_eight_ctx = true,
> @@ -1088,7 +1088,10 @@ static const struct of_device_id ipmmu_o
>   .data = _features_default,
>   }, {
>   .compatible = "renesas,ipmmu-r8a7795",
> - .data = _features_r8a7795,
> + .data = _features_rcar_gen3,
> + }, {
> + .compatible = "renesas,ipmmu-r8a7796",
> + .data = _features_rcar_gen3,
>   }, {
>   /* Terminator */
>   },
> @@ -1268,6 +1271,8 @@ IOMMU_OF_DECLARE(ipmmu_vmsa_iommu_of, "r
>ipmmu_vmsa_iommu_of_setup);
>  IOMMU_OF_DECLARE(ipmmu_r8a7795_iommu_of, "renesas,ipmmu-r8a7795",
>ipmmu_vmsa_iommu_of_setup);
> +IOMMU_OF_DECLARE(ipmmu_r8a7796_iommu_of, "renesas,ipmmu-r8a7796",
> +  ipmmu_vmsa_iommu_of_setup);

How about a Gen3 generic compatible string in addition to the SoC-specific 
ones ?

>  #endif
> 
>  MODULE_DESCRIPTION("IOMMU API for Renesas VMSA-compatible IPMMU");

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH 1/3] iommu/ipmmu-vmsa: Add r8a7796 DT binding

2016-06-07 Thread Laurent Pinchart
Hi Magnus,

Thank you for the patch.

On Tuesday 07 Jun 2016 12:39:27 Magnus Damm wrote:
> From: Magnus Damm <damm+rene...@opensource.se>
> 
> Update the IPMMU DT binding documentation to include the r8a7796 compat
> string for R-Car M3-W.
> 
> Signed-off-by: Magnus Damm <damm+rene...@opensource.se>

Acked-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> ---
> 
>  Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt |1 +
>  1 file changed, 1 insertion(+)
> 
> --- 0001/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
> +++
> work/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt   
2016-06
> -06 11:27:37.560607110 +0900 @@ -16,6 +16,7 @@ Required Properties:
>  - "renesas,ipmmu-r8a7793" for the R8A7793 (R-Car M2-N) IPMMU.
>  - "renesas,ipmmu-r8a7794" for the R8A7794 (R-Car E2) IPMMU.
>  - "renesas,ipmmu-r8a7795" for the R8A7795 (R-Car H3) IPMMU.
> +- "renesas,ipmmu-r8a7796" for the R8A7796 (R-Car M3-W) IPMMU.
>  - "renesas,ipmmu-vmsa" for generic R-Car Gen2 VMSA-compatible IPMMU.
> 
>- reg: Base address and size of the IPMMU registers.

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH 2/3] iommu/ipmmu-vmsa: Increase maximum micro-TLBS to 48

2016-06-07 Thread Laurent Pinchart
Hi Magnus,

Thank you for the patch.

On Tuesday 07 Jun 2016 12:39:36 Magnus Damm wrote:
> From: Magnus Damm <damm+rene...@opensource.se>
> 
> Bump up the maximum numbers of micro-TLBS to 48.
> 
> Each IPMMU device instance get micro-TLB assignment via
> the "iommus" property in DT. Older SoCs tend to use a
> maximum number of 32 micro-TLBd per IPMMU instance however
> newer SoCs such as r8a7796 make use of up to 48 micro-TLBs.
> 
> At this point no SoC specific handling is done to validate
> the maximum number of micro-TLBs, and because of that the
> DT information is assumed to be within correct range for
> each particular SoC.
> 
> If needed in the future SoC specific feature flags can be
> added to handle the maximum number of micro-TLBs without
> requiring DT changes, however at this point this does not
> seem necessary.
> 
> Signed-off-by: Magnus Damm <damm+rene...@opensource.se>
> ---
> 
>  drivers/iommu/ipmmu-vmsa.c |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> --- 0029/drivers/iommu/ipmmu-vmsa.c
> +++ work/drivers/iommu/ipmmu-vmsa.c   2016-06-06 11:17:33.230607110 +0900
> @@ -1115,7 +1115,7 @@ static int ipmmu_probe(struct platform_d
>   }
> 
>   mmu->dev = >dev;
> - mmu->num_utlbs = 32;
> + mmu->num_utlbs = 48;

This value is only used to validate that all utlb numbers in the bus master DT 
nodes are within the range acceptable by the device. If we bump it up 
unconditionally we could as well remove it completely. A possibly better 
alternative would be to specify the number of utlbs, or even the mask of 
implemented utlbs, in the DT node of the IPMMU.

Why 48 by the way ? The IPMMU instance with the largest utlb number in the R-
Car Gen3 datasheet uses a 0-38 utlb range.

>   spin_lock_init(>lock);
>   bitmap_zero(mmu->ctx, IPMMU_CTX_MAX);
>   mmu->features = match->data;

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH V2 1/5] iommu/msm: Add DT adaptation

2016-04-09 Thread Laurent Pinchart
  clock-names =
> + "smmu_pclk",
> + "iommu_clk";
> + clocks =
> + < SMMU_AHB_CLK>,
> + < MDP_AXI_CLK>;
> + reg = <0x0750 0x10>;
> + interrupts =
> + ,
> + ;
> + ncb = <2>;
> + };
> +
> + mdp: qcom,mdp@510 {
> + compatible = "qcom,mdp";
> + ...
> + iommus = <_port0 0 2>;
> + };

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v5 6/9] dmaengine: rcar-dmac: group slave configuration

2016-03-20 Thread Laurent Pinchart
Hi Niklas,

Thank you for the patch.

On Tuesday 08 March 2016 03:42:51 Niklas Söderlund wrote:
> Group slave address and transfer size in own structs for source and
> destination. This is in preparation for hooking up the dma-mapping API
> to the slave addresses.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> ---
>  drivers/dma/sh/rcar-dmac.c | 38 ++
>  1 file changed, 22 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
> index 01cf82f..b3911fe 100644
> --- a/drivers/dma/sh/rcar-dmac.c
> +++ b/drivers/dma/sh/rcar-dmac.c
> @@ -118,14 +118,22 @@ struct rcar_dmac_desc_page {
>   sizeof(struct rcar_dmac_xfer_chunk))
> 
>  /*
> + * struct rcar_dmac_chan_slave - Slave configuration
> + * @slave_addr: slave memory address
> + * @xfer_size: size (in bytes) of hardware transfers
> + */
> +struct rcar_dmac_chan_slave {
> + phys_addr_t slave_addr;
> + unsigned int xfer_size;
> +};
> +
> +/*
>   * struct rcar_dmac_chan - R-Car Gen2 DMA Controller Channel
>   * @chan: base DMA channel object
>   * @iomem: channel I/O memory base
>   * @index: index of this channel in the controller
> - * @src_xfer_size: size (in bytes) of hardware transfers on the source side
> - * @dst_xfer_size: size (in bytes) of hardware transfers on the
> destination side - * @src_slave_addr: slave source memory address
> - * @dst_slave_addr: slave destination memory address
> + * @src: slave memory address and size on the source side
> + * @dst: slave memory address and size on the destination side
>   * @mid_rid: hardware MID/RID for the DMA client using this channel
>   * @lock: protects the channel CHCR register and the desc members
>   * @desc.free: list of free descriptors
> @@ -142,10 +150,8 @@ struct rcar_dmac_chan {
>   void __iomem *iomem;
>   unsigned int index;
> 
> - unsigned int src_xfer_size;
> - unsigned int dst_xfer_size;
> - phys_addr_t src_slave_addr;
> - phys_addr_t dst_slave_addr;
> + struct rcar_dmac_chan_slave src;
> + struct rcar_dmac_chan_slave dst;
>   int mid_rid;
> 
>   spinlock_t lock;
> @@ -793,13 +799,13 @@ static void rcar_dmac_chan_configure_desc(struct
> rcar_dmac_chan *chan, case DMA_DEV_TO_MEM:
>   chcr = RCAR_DMACHCR_DM_INC | RCAR_DMACHCR_SM_FIXED
> 
>| RCAR_DMACHCR_RS_DMARS;
> 
> - xfer_size = chan->src_xfer_size;
> + xfer_size = chan->src.xfer_size;
>   break;
> 
>   case DMA_MEM_TO_DEV:
>   chcr = RCAR_DMACHCR_DM_FIXED | RCAR_DMACHCR_SM_INC
> 
>| RCAR_DMACHCR_RS_DMARS;
> 
> - xfer_size = chan->dst_xfer_size;
> + xfer_size = chan->dst.xfer_size;
>   break;
> 
>   case DMA_MEM_TO_MEM:
> @@ -1038,7 +1044,7 @@ rcar_dmac_prep_slave_sg(struct dma_chan *chan, struct
> scatterlist *sgl, }
> 
>   dev_addr = dir == DMA_DEV_TO_MEM
> -  ? rchan->src_slave_addr : rchan->dst_slave_addr;
> +  ? rchan->src.slave_addr : rchan->dst.slave_addr;
>   return rcar_dmac_chan_prep_sg(rchan, sgl, sg_len, dev_addr,
> dir, flags, false);
>  }
> @@ -1093,7 +1099,7 @@ rcar_dmac_prep_dma_cyclic(struct dma_chan *chan,
> dma_addr_t buf_addr, }
> 
>   dev_addr = dir == DMA_DEV_TO_MEM
> -  ? rchan->src_slave_addr : rchan->dst_slave_addr;
> +  ? rchan->src.slave_addr : rchan->dst.slave_addr;
>   desc = rcar_dmac_chan_prep_sg(rchan, sgl, sg_len, dev_addr,
> dir, flags, true);
> 
> @@ -1110,10 +1116,10 @@ static int rcar_dmac_device_config(struct dma_chan
> *chan, * We could lock this, but you shouldn't be configuring the
>* channel, while using it...
>*/
> - rchan->src_slave_addr = cfg->src_addr;
> - rchan->dst_slave_addr = cfg->dst_addr;
> -     rchan->src_xfer_size = cfg->src_addr_width;
> - rchan->dst_xfer_size = cfg->dst_addr_width;
> + rchan->src.slave_addr = cfg->src_addr;
> + rchan->dst.slave_addr = cfg->dst_addr;
> + rchan->src.xfer_size = cfg->src_addr_width;
> + rchan->dst.xfer_size = cfg->dst_addr_width;
> 
>   return 0;
>  }

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH 00/04] iommu/ipmmu-vmsa: IPMMU CONFIG_IOMMU_DMA update

2016-03-19 Thread Laurent Pinchart
Hi Magnus,

Thank you for the patches.

On Wednesday 16 March 2016 02:04:31 Magnus Damm wrote:
> iommu/ipmmu-vmsa: IPMMU CONFIG_IOMMU_DMA update
> 
> [PATCH 01/04] iommu/ipmmu-vmsa: 32-bit ARM may have CONFIG_IOMMU_DMA=y
> [PATCH 02/04] iommu/ipmmu-vmsa: Break out utlb parsing code
> [PATCH 03/04] iommu/ipmmu-vmsa: Break out domain allocation code
> [PATCH 04/04] iommu/ipmmu-vmsa: Add new IOMMU_DOMAIN_DMA ops
> 
> This series updates the IPMMU driver with CONFIG_IOMMU_DMA=y support
> which is present in mainline for 64-bit ARM while experimental support
> has been posted for 32-bit ARM thanks to Marek Szyprowski:
> 
> [RFC 0/3] Unify IOMMU-based DMA-mapping code for ARM and ARM64
> 
> Most of the patches in this series based on code earlier included in
> the series below but has been reworked to also fit on 32-bit ARM:
> 
> [PATCH/RFC 00/10] iommu/ipmmu-vmsa: Experimental r8a7795 support
> 
> Signed-off-by: Magnus Damm <damm+rene...@opensource.se>

Great ! Thanks a lot for the work, I'm really happy to see this being 
addressed.

For patches 1/4 to 3/4,

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

For patch 4/4, please see my comments in the reply to the patch.

> ---
> 
>  Built on top of next-20160315
>  Depends on [PATCH v2 00/04] iommu/ipmmu-vmsa: IPMMU multi-arch update V2
> 
>  drivers/iommu/ipmmu-vmsa.c |  238 ++++++--
>  1 file changed, 174 insertions(+), 64 deletions(-)

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v5 3/9] dma-mapping: add dma_{map,unmap}_resource

2016-03-19 Thread Laurent Pinchart
Hello,

On Tuesday 15 March 2016 01:22:54 Christoph Hellwig wrote:
> On Fri, Mar 11, 2016 at 01:58:46PM +0100, Niklas S?derlund wrote:
> > Without an IOMMU this is easy since the phys_addr_t and dma_addr_t are
> > the same and no special care is needed. However if you have a IOMMU you
> > need to map the DMA slave phys_addr_t to a dma_addr_t using something
> > like this. Is it not very similar to dma_map_single() where one maps
> > processor virtual memory (instead if MMIO) so that it can be used with
> > DMA slaves?
> 
> It's similar, but I don't think this actually works as a general case
> as there are quite a few places that expect to be able to have a
> struct page for a physical address.  We'd at least need a very careful
> audit for that case.

The good news is that, given that no code uses this new API at the moment, 
there isn't much to audit. The patch series implements the resource mapping 
for arch/arm only, and makes use of it in the rcar-dmac driver only. Would you 
like anything audited else than the arch/arm dma mapping implementation, the 
rcar-dmac driver and the code that then deals with the dma addresses (I'm 
thinking about the IOMMU subsystem and the ipmmu-vmsa driver in particular) ?

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v2 03/04] iommu/ipmmu-vmsa: Break out 32-bit ARM mapping code

2016-03-19 Thread Laurent Pinchart
gt; -  * Create the ARM mapping, used by the ARM DMA mapping core to allocate
> -  * VAs. This will allocate a corresponding IOMMU domain.
> -  *
> -  * TODO:
> -  * - Create one mapping per context (TLB).
> -  * - Make the mapping size configurable ? We currently use a 2GB mapping
> -  *   at a 1GB offset to ensure that NULL VAs will fault.
> -  */
> - if (!mmu->mapping) {
> - struct dma_iommu_mapping *mapping;
> -
> - mapping = arm_iommu_create_mapping(_bus_type,
> -SZ_1G, SZ_2G);
> - if (IS_ERR(mapping)) {
> - dev_err(mmu->dev, "failed to create ARM IOMMU 
> mapping\n");
> - ret = PTR_ERR(mapping);
> - goto error;
> - }
> -
> - mmu->mapping = mapping;
> - }
> -
> - /* Attach the ARM VA mapping to the device. */
> - ret = arm_iommu_attach_device(dev, mmu->mapping);
> - if (ret < 0) {
> - dev_err(dev, "Failed to attach device to VA mapping\n");
> + ret = ipmmu_map_attach(dev, mmu);
> + if (ret < 0)
>   goto error;
> - }
> 
>   return 0;
> 
>  error:
> - arm_iommu_release_mapping(mmu->mapping);
> -
>   kfree(dev->archdata.iommu);
>   kfree(utlbs);
> 
> @@ -745,7 +775,7 @@ static void ipmmu_remove_device(struct d
>  {
>   struct ipmmu_vmsa_archdata *archdata = dev->archdata.iommu;
> 
> - arm_iommu_detach_device(dev);
> + ipmmu_detach(dev);
>   iommu_group_remove_device(dev);
> 
>   kfree(archdata->utlbs);
> @@ -856,7 +886,7 @@ static int ipmmu_remove(struct platform_
>   list_del(>list);
>   spin_unlock(_devices_lock);
> 
> - arm_iommu_release_mapping(mmu->mapping);
> + ipmmu_release_mapping(mmu);
> 
>   ipmmu_device_reset(mmu);

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v5 1/9] iommu: Add MMIO mapping type

2016-03-19 Thread Laurent Pinchart
Hi Niklas,

Thank you for the patch.

On Tuesday 08 March 2016 03:42:46 Niklas Söderlund wrote:
> From: Robin Murphy <robin.mur...@arm.com>
> 
> On some platforms, MMIO regions might need slightly different treatment
> compared to mapping regular memory; add the notion of MMIO mappings to
> the IOMMU API's memory type flags, so that callers can let the IOMMU
> drivers know to do the right thing.
> 
> Signed-off-by: Robin Murphy <robin.mur...@arm.com>
> Signed-off-by: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> ---
>  drivers/iommu/io-pgtable-arm.c | 9 +++--
>  include/linux/iommu.h  | 1 +
>  2 files changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> index 381ca5a..9c19989 100644
> --- a/drivers/iommu/io-pgtable-arm.c
> +++ b/drivers/iommu/io-pgtable-arm.c
> @@ -355,7 +355,10 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct
> arm_lpae_io_pgtable *data, if (!(prot & IOMMU_WRITE) && (prot &
> IOMMU_READ))
>   pte |= ARM_LPAE_PTE_AP_RDONLY;
> 
> - if (prot & IOMMU_CACHE)
> + if (prot & IOMMU_MMIO)
> + pte |= (ARM_LPAE_MAIR_ATTR_IDX_DEV
> + << ARM_LPAE_PTE_ATTRINDX_SHIFT);
> + else if (prot & IOMMU_CACHE)
>   pte |= (ARM_LPAE_MAIR_ATTR_IDX_CACHE
>   << ARM_LPAE_PTE_ATTRINDX_SHIFT);
>   } else {
> @@ -364,7 +367,9 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct
> arm_lpae_io_pgtable *data, pte |= ARM_LPAE_PTE_HAP_READ;
>   if (prot & IOMMU_WRITE)
>   pte |= ARM_LPAE_PTE_HAP_WRITE;
> - if (prot & IOMMU_CACHE)
> + if (prot & IOMMU_MMIO)
> + pte |= ARM_LPAE_PTE_MEMATTR_DEV;
> + else if (prot & IOMMU_CACHE)
>   pte |= ARM_LPAE_PTE_MEMATTR_OIWB;
>   else
>   pte |= ARM_LPAE_PTE_MEMATTR_NC;
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index a5c539f..34b6432 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -30,6 +30,7 @@
>  #define IOMMU_WRITE  (1 << 1)
>  #define IOMMU_CACHE  (1 << 2) /* DMA cache coherency */
>  #define IOMMU_NOEXEC (1 << 3)
> +#define IOMMU_MMIO   (1 << 4) /* e.g. things like MSI doorbells */
> 
>  struct iommu_ops;
>  struct iommu_group;

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v2 02/04] iommu/ipmmu-vmsa: Rework interrupt code and use bitmap for context

2016-03-19 Thread Laurent Pinchart
 continue;
> + if (ipmmu_domain_irq(mmu->domains[i]) == IRQ_HANDLED)
> + status = IRQ_HANDLED;
> + }
> 
> - return ipmmu_domain_irq(domain);
> + return status;
>  }
> 
>  /* 
> @@ -774,6 +796,7 @@ static int ipmmu_probe(struct platform_d
> 
>   mmu->dev = >dev;
>   mmu->num_utlbs = 32;
> + bitmap_zero(mmu->ctx, IPMMU_CTX_MAX);
> 
>   /* Map I/O memory and request IRQ. */
>   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH 04/04] iommu/ipmmu-vmsa: Add new IOMMU_DOMAIN_DMA ops

2016-03-18 Thread Laurent Pinchart
Hi Magnus,

Thank you for the patch.

On Wednesday 16 March 2016 02:05:10 Magnus Damm wrote:
> From: Magnus Damm <damm+rene...@opensource.se>
> 
> Introduce a new set of iommu_ops suitable for 64-bit ARM
> as well as 32-bit ARM when CONFIG_IOMMU_DMA=y. The ->of_xlate()
> callback is needed by the code exported by of_iommu.h and
> it is wrapped in #ifdefs to also compile of x86_64.
> 
> Signed-off-by: Magnus Damm <damm+rene...@opensource.se>

Nice work, thanks a lot. With the two comments below addressed,

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> ---
> 
>  drivers/iommu/ipmmu-vmsa.c |   94 -
>  1 file changed, 92 insertions(+), 2 deletions(-)
> 
> --- 0011/drivers/iommu/ipmmu-vmsa.c
> +++ work/drivers/iommu/ipmmu-vmsa.c   2016-03-16 01:35:06.990513000 +0900
> @@ -10,6 +10,7 @@
> 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -804,7 +805,7 @@ static void ipmmu_remove_device(struct d
>   dev->archdata.iommu = NULL;
>  }
> 
> -static const struct iommu_ops ipmmu_ops = {
> +static const struct iommu_ops __maybe_unused ipmmu_ops = {
>   .domain_alloc = ipmmu_domain_alloc,
>   .domain_free = ipmmu_domain_free,
>   .attach_dev = ipmmu_attach_device,
> @@ -818,6 +819,92 @@ static const struct iommu_ops ipmmu_ops
>   .pgsize_bitmap = SZ_1G | SZ_2M | SZ_4K,
>  };
> 
> +static struct iommu_domain *ipmmu_domain_alloc_dma(unsigned type)
> +{
> + struct iommu_domain *io_domain;
> +
> + if (type != IOMMU_DOMAIN_DMA)
> + return NULL;
> +
> + io_domain = __ipmmu_domain_alloc(type);
> + if (io_domain)
> + iommu_get_dma_cookie(io_domain);
> +
> + return io_domain;
> +}
> +
> +static void ipmmu_domain_free_dma(struct iommu_domain *io_domain)
> +{
> + iommu_put_dma_cookie(io_domain);
> + ipmmu_domain_free(io_domain);
> +}
> +
> +static int ipmmu_add_device_dma(struct device *dev)
> +{
> + struct iommu_group *group;
> +
> + /* only accept devices with iommus property */

Nitpicking, the driver capitalizes the first letter of the sentence in 
comments and includes a period at the end. Could you please follow the same 
style for consistency ?

> + if (of_count_phandle_with_args(dev->of_node, "iommus",
> +"#iommu-cells") < 0)
> + return -ENODEV;

Given that the iommu_group_get_for_dev() call will call the .device_group() 
operation that ends up calling ipmmu_init_platform_device(), do we need this 
check here ?

> + group = iommu_group_get_for_dev(dev);
> + if (IS_ERR(group))
> + return PTR_ERR(group);
> +
> + return 0;
> +}
> +
> +static void ipmmu_remove_device_dma(struct device *dev)
> +{
> + iommu_group_remove_device(dev);
> +}
> +
> +static struct iommu_group *ipmmu_device_group_dma(struct device *dev)
> +{
> + struct iommu_group *group;
> + int ret;
> +
> + group = generic_device_group(dev);
> + if (IS_ERR(group))
> + return group;
> +
> + ret = ipmmu_init_platform_device(dev, group);
> + if (ret) {
> + iommu_group_put(group);
> + group = ERR_PTR(ret);
> + }
> +
> + return group;
> +}
> +
> +#ifdef CONFIG_OF_IOMMU
> +static int ipmmu_of_xlate_dma(struct device *dev,
> +   struct of_phandle_args *spec)
> +{
> + /* dummy callback to satisfy of_iommu_configure() */
> + return 0;
> +}
> +#endif
> +
> +static const struct iommu_ops __maybe_unused ipmmu_ops_dma = {
> + .domain_alloc = ipmmu_domain_alloc_dma,
> + .domain_free = ipmmu_domain_free_dma,
> + .attach_dev = ipmmu_attach_device,
> + .detach_dev = ipmmu_detach_device,
> + .map = ipmmu_map,
> + .unmap = ipmmu_unmap,
> + .map_sg = default_iommu_map_sg,
> + .iova_to_phys = ipmmu_iova_to_phys,
> + .add_device = ipmmu_add_device_dma,
> + .remove_device = ipmmu_remove_device_dma,
> + .device_group = ipmmu_device_group_dma,
> + .pgsize_bitmap = SZ_1G | SZ_2M | SZ_4K,
> +#ifdef CONFIG_OF_IOMMU
> + .of_xlate = ipmmu_of_xlate_dma,
> +#endif
> +};
> +
>  /*
> ---
> -- * Probe/remove and init
>   */
> @@ -929,14 +1016,17 @@ static struct platform_driver ipmmu_driv
> 
>  static int __init ipmmu_init(void)
>  {
> + const struct iommu_ops *ops;
>   int ret;
> 
>   ret = platform_driver_register(_driver);
>   if (ret < 0)
>   return ret;
> 
> + ops = IS_ENABLED(CONFIG_IOMMU_DMA) ? _ops_dma : _ops;
> +
>   if (!iommu_present(_bus_type))
> - bus_set_iommu(_bus_type, _ops);
> + bus_set_iommu(_bus_type, ops);
> 
>   return 0;
>  }

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v5 5/9] dmaengine: rcar-dmac: slave address are physical

2016-03-18 Thread Laurent Pinchart
Hi Niklas,

Thank you for the patch.

On Tuesday 08 March 2016 03:42:50 Niklas Söderlund wrote:
> Slave addresses coming from a client is physical not dma. Store the
> address using the correct data type. This is in preparation for hooking
> up the dma-mapping API to the slave addresses.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>
> ---
>  drivers/dma/sh/rcar-dmac.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
> index 7820d07..01cf82f 100644
> --- a/drivers/dma/sh/rcar-dmac.c
> +++ b/drivers/dma/sh/rcar-dmac.c
> @@ -144,8 +144,8 @@ struct rcar_dmac_chan {
> 
>   unsigned int src_xfer_size;
>   unsigned int dst_xfer_size;
> - dma_addr_t src_slave_addr;
> - dma_addr_t dst_slave_addr;
> + phys_addr_t src_slave_addr;
> + phys_addr_t dst_slave_addr;

This moves the cast from phys_addr_t to dma_addr_t from the driver's DMA 
engine operations to other places. I'm not sure there's much value in doing 
so. I'd squash this patch with 7/9, the result will be easier to review.

>   int mid_rid;
> 
>   spinlock_t lock;

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH] iommu: ipmmu-vmsa: Use ARCH_RENESAS

2016-02-22 Thread Laurent Pinchart
Hi Simon,

Thank you for the patch.

On Monday 22 February 2016 10:41:35 Simon Horman wrote:
> Make use of ARCH_RENESAS in place of ARCH_SHMOBILE.
> 
> This is part of an ongoing process to migrate from ARCH_SHMOBILE to
> ARCH_RENESAS the motivation for which being that RENESAS seems to be a more
> appropriate name than SHMOBILE for the majority of Renesas ARM based SoCs.
> 
> Signed-off-by: Simon Horman <horms+rene...@verge.net.au>

Acked-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> ---
>  drivers/iommu/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
>  Based on the next branch of Joerg's iommu tree on kernel.org
> 
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index a1e75cba18e0..d4b38e4d27fe 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -266,7 +266,7 @@ config EXYNOS_IOMMU_DEBUG
>  config IPMMU_VMSA
>   bool "Renesas VMSA-compatible IPMMU"
>   depends on ARM_LPAE
> - depends on ARCH_SHMOBILE || COMPILE_TEST
> + depends on ARCH_RENESAS || COMPILE_TEST
>   select IOMMU_API
>   select IOMMU_IO_PGTABLE_LPAE
>   select ARM_DMA_USE_IOMMU

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v2] iommu/io-pgtable: Rationalise quirk handling

2016-02-12 Thread Laurent Pinchart
Hi Robin,

Thank you for the patch.

On Friday 12 February 2016 17:09:46 Robin Murphy wrote:
> As the number of io-pgtable implementations grows beyond 1, it's time
> to rationalise the quirks mechanism before things have a chance to
> start getting really ugly and out-of-hand.
> 
> To that end:
> - Indicate exactly which quirks each format can/does support.
> - Fail creating a table if a caller wants unsupported quirks.
> - Properly document where each quirk applies and why.
> 
> Signed-off-by: Robin Murphy <robin.mur...@arm.com>
> ---
> 
> Just to allay any confusion, I intend this as a followup to the
> short-descriptor[1] and Mediatek IOMMU[2] patches, rather than a
> crucial addition, so it can either get picked up along with those
> or wait 'til later.
> 
> v2:
> - Use unsigned long for the bitmap.
> - Do format-specific checks inline.
> - Enough of a difference that I don't feel comfortable putting
>   Laurent's reviewed-by from v1 on it...

Here it is again.

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> [1]:http://thread.gmane.org/gmane.linux.kernel.iommu/12007
> [2]:http://thread.gmane.org/gmane.linux.kernel.iommu/11974
> 
>  drivers/iommu/io-pgtable-arm-v7s.c |  5 +
>  drivers/iommu/io-pgtable-arm.c | 13 +++--
>  drivers/iommu/io-pgtable.h | 22 ++
>  3 files changed, 34 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iommu/io-pgtable-arm-v7s.c
> b/drivers/iommu/io-pgtable-arm-v7s.c index d39a021..9fcceb1 100644
> --- a/drivers/iommu/io-pgtable-arm-v7s.c
> +++ b/drivers/iommu/io-pgtable-arm-v7s.c
> @@ -623,6 +623,11 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct
> io_pgtable_cfg *cfg, if (cfg->ias > ARM_V7S_ADDR_BITS || cfg->oas >
> ARM_V7S_ADDR_BITS) return NULL;
> 
> + if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
> + IO_PGTABLE_QUIRK_NO_PERMS |
> + IO_PGTABLE_QUIRK_TLBI_ON_MAP))
> + return NULL;
> +
>   data = kmalloc(sizeof(*data), GFP_KERNEL);
>   if (!data)
>   return NULL;
> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> index 4095af2..debdf04 100644
> --- a/drivers/iommu/io-pgtable-arm.c
> +++ b/drivers/iommu/io-pgtable-arm.c
> @@ -658,8 +658,12 @@ static struct io_pgtable *
>  arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
>  {
>   u64 reg;
> - struct arm_lpae_io_pgtable *data = arm_lpae_alloc_pgtable(cfg);
> + struct arm_lpae_io_pgtable *data;
> 
> + if (cfg->quirks & ~IO_PGTABLE_QUIRK_ARM_NS)
> + return NULL;
> +
> + data = arm_lpae_alloc_pgtable(cfg);
>   if (!data)
>   return NULL;
> 
> @@ -742,8 +746,13 @@ static struct io_pgtable *
>  arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
>  {
>   u64 reg, sl;
> - struct arm_lpae_io_pgtable *data = arm_lpae_alloc_pgtable(cfg);
> + struct arm_lpae_io_pgtable *data;
> 
> + /* The NS quirk doesn't apply at stage 2 */
> + if (cfg->quirks)
> + return NULL;
> +
> + data = arm_lpae_alloc_pgtable(cfg);
>   if (!data)
>   return NULL;
> 
> diff --git a/drivers/iommu/io-pgtable.h b/drivers/iommu/io-pgtable.h
> index 4faee7d..d4f5027 100644
> --- a/drivers/iommu/io-pgtable.h
> +++ b/drivers/iommu/io-pgtable.h
> @@ -47,10 +47,24 @@ struct iommu_gather_ops {
>   * page table walker.
>   */
>  struct io_pgtable_cfg {
> - #define IO_PGTABLE_QUIRK_ARM_NS BIT(0) /* Set NS bit in PTEs */
> - #define IO_PGTABLE_QUIRK_NO_PERMS   BIT(1) /* No AP/XN bits */
> - #define IO_PGTABLE_QUIRK_TLBI_ON_MAPBIT(2) /* TLB Inv. on map */
> - int quirks;
> + /*
> +  * IO_PGTABLE_QUIRK_ARM_NS: (ARM formats) Set NS and NSTABLE bits in
> +  *  stage 1 PTEs, for hardware which insists on validating them
> +  *  even in non-secure state where they should normally be ignored.
> +  *
> +  * IO_PGTABLE_QUIRK_NO_PERMS: Ignore the IOMMU_READ, IOMMU_WRITE and
> +  *  IOMMU_NOEXEC flags and map everything with full access, for
> +  *  hardware which does not implement the permissions of a given
> +  *  format, and/or requires some format-specific default value.
> +  *
> +  * IO_PGTABLE_QUIRK_TLBI_ON_MAP: If the format forbids caching invalid
> +  *  (unmapped) entries but the hardware might do so anyway, perform
> +  *  TLB maintenance when mapping as well as when unmapping.
> +  */
> + #define IO_PGTABLE_QUI

Re: [PATCH 4/3] iommu/io-pgtable: Rationalise quirk handling

2016-02-11 Thread Laurent Pinchart
Hi Robin,

Thank you for the patch.

On Thursday 11 February 2016 16:13:45 Robin Murphy wrote:
> As the number of io-pgtable implementations grows beyond 1, it's time
> to rationalise the quirks mechanism before things have a chance to
> start getting really ugly and out-of-hand.
> 
> To that end:
> - Indicate exactly which quirks each format can/does support.
> - Fail creating a table if a caller wants unsupported quirks.
> - Properly document where each quirk applies and why.
> 
> Signed-off-by: Robin Murphy <robin.mur...@arm.com>

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> ---
>  drivers/iommu/io-pgtable-arm-v7s.c |  3 +++
>  drivers/iommu/io-pgtable-arm.c |  2 ++
>  drivers/iommu/io-pgtable.c |  3 +++
>  drivers/iommu/io-pgtable.h | 24 
>  4 files changed, 28 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/iommu/io-pgtable-arm-v7s.c
> b/drivers/iommu/io-pgtable-arm-v7s.c index d39a021..9bc607a 100644
> --- a/drivers/iommu/io-pgtable-arm-v7s.c
> +++ b/drivers/iommu/io-pgtable-arm-v7s.c
> @@ -690,6 +690,9 @@ out_free_data:
>  struct io_pgtable_init_fns io_pgtable_arm_v7s_init_fns = {
>   .alloc  = arm_v7s_alloc_pgtable,
>   .free   = arm_v7s_free_pgtable,
> + .supported_quirks = IO_PGTABLE_QUIRK_ARM_NS |
> + IO_PGTABLE_QUIRK_NO_PERMS |
> + IO_PGTABLE_QUIRK_TLBI_ON_MAP,
>  };
> 
>  #ifdef CONFIG_IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> index 4095af2..32f94f1 100644
> --- a/drivers/iommu/io-pgtable-arm.c
> +++ b/drivers/iommu/io-pgtable-arm.c
> @@ -863,6 +863,7 @@ arm_32_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg,
> void *cookie) struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s1_init_fns
> = { .alloc= arm_64_lpae_alloc_pgtable_s1,
>   .free   = arm_lpae_free_pgtable,
> + .supported_quirks = IO_PGTABLE_QUIRK_ARM_NS,
>  };
> 
>  struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s2_init_fns = {
> @@ -873,6 +874,7 @@ struct io_pgtable_init_fns
> io_pgtable_arm_64_lpae_s2_init_fns = { struct io_pgtable_init_fns
> io_pgtable_arm_32_lpae_s1_init_fns = { .alloc =
> arm_32_lpae_alloc_pgtable_s1,
>   .free   = arm_lpae_free_pgtable,
> + .supported_quirks = IO_PGTABLE_QUIRK_ARM_NS,
>  };
> 
>  struct io_pgtable_init_fns io_pgtable_arm_32_lpae_s2_init_fns = {
> diff --git a/drivers/iommu/io-pgtable.c b/drivers/iommu/io-pgtable.c
> index 876f6a7..0f57a45 100644
> --- a/drivers/iommu/io-pgtable.c
> +++ b/drivers/iommu/io-pgtable.c
> @@ -52,6 +52,9 @@ struct io_pgtable_ops *alloc_io_pgtable_ops(enum
> io_pgtable_fmt fmt, if (!fns)
>   return NULL;
> 
> + if (cfg->quirks & ~fns->supported_quirks)
> + return NULL;
> +
>   iop = fns->alloc(cfg, cookie);
>   if (!iop)
>   return NULL;
> diff --git a/drivers/iommu/io-pgtable.h b/drivers/iommu/io-pgtable.h
> index 4faee7d..6e7f11e 100644
> --- a/drivers/iommu/io-pgtable.h
> +++ b/drivers/iommu/io-pgtable.h
> @@ -47,10 +47,24 @@ struct iommu_gather_ops {
>   * page table walker.
>   */
>  struct io_pgtable_cfg {
> - #define IO_PGTABLE_QUIRK_ARM_NS BIT(0) /* Set NS bit in PTEs */
> - #define IO_PGTABLE_QUIRK_NO_PERMS   BIT(1) /* No AP/XN bits */
> - #define IO_PGTABLE_QUIRK_TLBI_ON_MAPBIT(2) /* TLB Inv. on map */
> - int quirks;
> + /*
> +  * IO_PGTABLE_QUIRK_ARM_NS: (ARM formats) Set NS and NSTABLE bits in
> +  *  stage 1 PTEs, for hardware which insists on validating them
> +  *  even in non-secure state where they should normally be ignored.
> +  *
> +  * IO_PGTABLE_QUIRK_NO_PERMS: Ignore the IOMMU_READ, IOMMU_WRITE and
> +  *  IOMMU_NOEXEC flags and map everything with full access, for
> +  *  hardware which does not implement the permissions of a given
> +  *  format, and/or requires some format-specific default value.
> +  *
> +  * IO_PGTABLE_QUIRK_TLBI_ON_MAP: If the format forbids caching invalid
> +  *  (unmapped) entries but the hardware might do so anyway, perform
> +  *  TLB maintenance when mapping as well as when unmapping.
> +  */
> + #define IO_PGTABLE_QUIRK_ARM_NS BIT(0)
> + #define IO_PGTABLE_QUIRK_NO_PERMS   BIT(1)
> + #define IO_PGTABLE_QUIRK_TLBI_ON_MAPBIT(2)
> + unsigned intquirks;
>   unsigned long   pgsize_bitmap;
>   unsigned intias;
>   unsigned intoas;
> @@ -173,10 +1

Re: [PATCH v3 7/8] ARM: dts: r8a7790: add iommus to dmac0 and dmac1

2016-02-10 Thread Laurent Pinchart
Hi Niklas,

Thank you for the patch.

On Wednesday 10 February 2016 01:57:57 Niklas Söderlund wrote:

No commit message ? I'd at least mention that as a side effect of this patch 
channel 0 and 15 are disabled, reducing the effective number of channels to 14 
per DMAC.

> Signed-off-by: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>

Acked-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

Same comment and ack for patch 8/8.

Note that we should still try to find a way to selectively enable the IOMMU in 
a per-device fashion, as system integrators might want it to be disabled for 
some devices. There's no urgency though.

> ---
>  arch/arm/boot/dts/r8a7790.dtsi | 30 ++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
> index 7dfd393..048bbf8 100644
> --- a/arch/arm/boot/dts/r8a7790.dtsi
> +++ b/arch/arm/boot/dts/r8a7790.dtsi
> @@ -294,6 +294,21 @@
>   power-domains = <_clocks>;
>   #dma-cells = <1>;
>   dma-channels = <15>;
> + iommus = <_ds 0>,
> +  <_ds 1>,
> +  <_ds 2>,
> +  <_ds 3>,
> +  <_ds 4>,
> +  <_ds 5>,
> +  <_ds 6>,
> +  <_ds 7>,
> +  <_ds 8>,
> +  <_ds 9>,
> +  <_ds 10>,
> +  <_ds 11>,
> +  <_ds 12>,
> +  <_ds 13>,
> +  <_ds 14>;
>   };
> 
>   dmac1: dma-controller@e672 {
> @@ -325,6 +340,21 @@
>   power-domains = <_clocks>;
>   #dma-cells = <1>;
>   dma-channels = <15>;
> + iommus = <_ds 15>,
> +  <_ds 16>,
> +  <_ds 17>,
> +  <_ds 18>,
> +  <_ds 19>,
> +  <_ds 20>,
> +  <_ds 21>,
> +  <_ds 22>,
> +      <_ds 23>,
> +  <_ds 24>,
> +  <_ds 25>,
> +  <_ds 26>,
> +  <_ds 27>,
> +  <_ds 28>,
> +  <_ds 29>;
>   };
> 
>   audma0: dma-controller@ec70 {

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v3 6/8] dmaengine: rcar-dmac: add iommu support for slave transfers

2016-02-10 Thread Laurent Pinchart
Hi Niklas,

Thank you for the patch.

On Wednesday 10 February 2016 01:57:56 Niklas Söderlund wrote:
> Enable slave transfers to devices behind IPMMU:s by mapping the slave
> addresses using the dma-mapping API.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>
> ---
>  drivers/dma/sh/rcar-dmac.c | 57 +++
>  1 file changed, 52 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
> index 743873c..268407c 100644
> --- a/drivers/dma/sh/rcar-dmac.c
> +++ b/drivers/dma/sh/rcar-dmac.c
> @@ -1106,21 +1106,68 @@ rcar_dmac_prep_dma_cyclic(struct dma_chan *chan,
> dma_addr_t buf_addr, return desc;
>  }
> 
> +static int rcar_dmac_set_slave_addr(struct dma_chan *chan,
> +  struct rcar_dmac_chan_slave *slave,
> +  phys_addr_t addr, size_t size)
> +{
> + struct dma_attrs attrs;
> + enum dma_data_direction dir;
> +
> + init_dma_attrs();
> + dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, );
> + dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, );
> +
> + /*
> +  * We can't know the direction at this time, see documentation for
> +  * 'direction' in struct dma_slave_config.
> +  */
> + dir = DMA_BIDIRECTIONAL;
> +
> + if (slave->xfer_size) {
> + dma_unmap_resource(chan->device->dev, slave->slave_addr,
> + slave->xfer_size, dir, );

Nitpicking, you can align slave with chan on the previous line.

> + slave->slave_addr = 0;
> + slave->xfer_size = 0;
> + }
> +
> + if (size) {
> + slave->slave_addr = dma_map_resource(chan->device->dev, addr,
> + size, dir, );
> +
> + if (dma_mapping_error(chan->device->dev, slave->slave_addr)) {
> + struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan);
> +
> + dev_err(chan->device->dev,
> + "chan%u: failed to map %zx@%pap",
> + rchan->index, size, );

Indentation looks weird to me.

> + return -EIO;
> + }
> +
> + slave->xfer_size = size;
> + }
> +
> + return 0;
> +}
> +
>  static int rcar_dmac_device_config(struct dma_chan *chan,
>  struct dma_slave_config *cfg)
>  {
>   struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan);
> + int ret;
> 
>   /*
>* We could lock this, but you shouldn't be configuring the
>* channel, while using it...
>*/
> - rchan->src.slave_addr = cfg->src_addr;
> - rchan->dst.slave_addr = cfg->dst_addr;
> - rchan->src.xfer_size = cfg->src_addr_width;
> - rchan->dst.xfer_size = cfg->dst_addr_width;
> 
> - return 0;
> + ret = rcar_dmac_set_slave_addr(chan, >src, cfg->src_addr,
> +     cfg->src_addr_width);
> + if (ret)
> + return ret;
> +
> + ret = rcar_dmac_set_slave_addr(chan, >dst, cfg->dst_addr,
> +     cfg->dst_addr_width);

You could align cfg with chan on the previous line (twice).

With this fixed and the attributes removed as explained by Robin,

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> + return ret;
>  }
> 
>  static int rcar_dmac_chan_terminate_all(struct dma_chan *chan)

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v3 1/8] iommu: Add MMIO mapping type

2016-02-10 Thread Laurent Pinchart
Hi Niklas,

Thank you for the patch.

On Wednesday 10 February 2016 01:57:51 Niklas Söderlund wrote:
> From: Robin Murphy <robin.mur...@arm.com>
> 
> On some platforms, MMIO regions might need slightly different treatment
> compared to mapping regular memory; add the notion of MMIO mappings to
> the IOMMU API's memory type flags, so that callers can let the IOMMU
> drivers know to do the right thing.
> 
> Signed-off-by: Robin Murphy <robin.mur...@arm.com>
> Acked-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

Answering the question from the cover letter, yes, it's totally fine to pick 
the ack, that's actually expected.

> ---
>  drivers/iommu/io-pgtable-arm.c | 4 +++-
>  include/linux/iommu.h  | 1 +

You might be asked to split this patch in two.

>  2 files changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> index 381ca5a..3ff4f87 100644
> --- a/drivers/iommu/io-pgtable-arm.c
> +++ b/drivers/iommu/io-pgtable-arm.c
> @@ -364,7 +364,9 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct
> arm_lpae_io_pgtable *data, pte |= ARM_LPAE_PTE_HAP_READ;
>   if (prot & IOMMU_WRITE)
>   pte |= ARM_LPAE_PTE_HAP_WRITE;
> - if (prot & IOMMU_CACHE)
> + if (prot & IOMMU_MMIO)
> + pte |= ARM_LPAE_PTE_MEMATTR_DEV;
> + else if (prot & IOMMU_CACHE)
>   pte |= ARM_LPAE_PTE_MEMATTR_OIWB;
>   else
>   pte |= ARM_LPAE_PTE_MEMATTR_NC;
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index a5c539f..34b6432 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -30,6 +30,7 @@
>  #define IOMMU_WRITE  (1 << 1)
>  #define IOMMU_CACHE  (1 << 2) /* DMA cache coherency */
>  #define IOMMU_NOEXEC (1 << 3)
> +#define IOMMU_MMIO   (1 << 4) /* e.g. things like MSI doorbells */
> 
>  struct iommu_ops;
>  struct iommu_group;

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v3 2/8] dma-mapping: add {map, unmap}_resource to dma_map_ops

2016-02-10 Thread Laurent Pinchart
Hi Niklas,

Thank you for the patch.

On Wednesday 10 February 2016 01:57:52 Niklas Söderlund wrote:
> Add methods to handle mapping of device resources from a physical
> address. This is needed for example to map be able to map MMIO FIFO
> registers to a IOMMU.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>

Apart from the typo in the commit message that Sergei already pointed out,

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> ---
>  include/linux/dma-mapping.h | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index 75857cd..e3aba4e 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -49,6 +49,12 @@ struct dma_map_ops {
>struct scatterlist *sg, int nents,
>enum dma_data_direction dir,
>struct dma_attrs *attrs);
> + dma_addr_t (*map_resource)(struct device *dev, phys_addr_t phys_addr,
> +size_t size, enum dma_data_direction dir,
> +struct dma_attrs *attrs);
> + void (*unmap_resource)(struct device *dev, dma_addr_t dma_handle,
> +size_t size, enum dma_data_direction dir,
> +struct dma_attrs *attrs);
>   void (*sync_single_for_cpu)(struct device *dev,
>   dma_addr_t dma_handle, size_t size,
>   enum dma_data_direction dir);

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v3 4/8] arm: dma-mapping: add {map, unmap}_resource for iommu ops

2016-02-10 Thread Laurent Pinchart
Hi Niklas,

Thank you for the patch.

On Wednesday 10 February 2016 01:57:54 Niklas Söderlund wrote:
> Add methods to map/unmap device resources addresses for dma_map_ops that
> are IOMMU aware. This is needed to map a device MMIO register from a
> physical address.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> ---
>  arch/arm/mm/dma-mapping.c | 63 
>  1 file changed, 63 insertions(+)
> 
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index 0eca381..ae2b175 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -1814,6 +1814,63 @@ static void arm_iommu_unmap_page(struct device *dev,
> dma_addr_t handle, __free_iova(mapping, iova, len);
>  }
> 
> +/**
> + * arm_iommu_map_resource - map a device resource for DMA
> + * @dev: valid struct device pointer
> + * @phys_addr: physical address of resource
> + * @size: size of resource to map
> + * @dir: DMA transfer direction
> + */
> +static dma_addr_t arm_iommu_map_resource(struct device *dev,
> + phys_addr_t phys_addr, size_t size,
> + enum dma_data_direction dir, struct dma_attrs *attrs)
> +{
> + struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
> + dma_addr_t dma_addr;
> + int ret, prot;
> + phys_addr_t addr = phys_addr & PAGE_MASK;
> + int offset = phys_addr & ~PAGE_MASK;
> + int len = PAGE_ALIGN(size + offset);
> +
> + dma_addr = __alloc_iova(mapping, size);
> + if (dma_addr == DMA_ERROR_CODE)
> + return dma_addr;
> +
> + prot = __dma_direction_to_prot(dir) | IOMMU_MMIO;
> +
> + ret = iommu_map(mapping->domain, dma_addr, addr, len, prot);
> + if (ret < 0)
> + goto fail;
> +
> + return dma_addr + offset;
> +fail:
> + __free_iova(mapping, dma_addr, size);
> + return DMA_ERROR_CODE;
> +}
> +
> +/**
> + * arm_iommu_unmap_resource - unmap a device DMA resource
> + * @dev: valid struct device pointer
> + * @dma_handle: DMA address to resource
> + * @size: size of resource to map
> + * @dir: DMA transfer direction
> + */
> +static void arm_iommu_unmap_resource(struct device *dev, dma_addr_t
> dma_handle, + size_t size, enum dma_data_direction dir,
> + struct dma_attrs *attrs)
> +{
> + struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
> + dma_addr_t iova = dma_handle & PAGE_MASK;
> + int offset = dma_handle & ~PAGE_MASK;
> + int len = PAGE_ALIGN(size + offset);
> +
> + if (!iova)
> + return;
> +
> + iommu_unmap(mapping->domain, iova, len);
> + __free_iova(mapping, iova, len);
> +}
> +
>  static void arm_iommu_sync_single_for_cpu(struct device *dev,
>   dma_addr_t handle, size_t size, enum dma_data_direction dir)
>  {
> @@ -1858,6 +1915,9 @@ struct dma_map_ops iommu_ops = {
>   .sync_sg_for_cpu= arm_iommu_sync_sg_for_cpu,
>   .sync_sg_for_device = arm_iommu_sync_sg_for_device,
> 
> + .map_resource   = arm_iommu_map_resource,
> + .unmap_resource = arm_iommu_unmap_resource,
> +
>   .set_dma_mask   = arm_dma_set_mask,
>  };
> 
> @@ -1873,6 +1933,9 @@ struct dma_map_ops iommu_coherent_ops = {
>   .map_sg = arm_coherent_iommu_map_sg,
>   .unmap_sg   = arm_coherent_iommu_unmap_sg,
> 
> + .map_resource   = arm_iommu_map_resource,
> + .unmap_resource = arm_iommu_unmap_resource,
> +
>   .set_dma_mask   = arm_dma_set_mask,
>  };

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v3 5/8] dmaengine: rcar-dmac: group slave configuration

2016-02-10 Thread Laurent Pinchart
Hi Niklas,

Thank you for the patch.

On Wednesday 10 February 2016 01:57:55 Niklas Söderlund wrote:
> Group slave address and transfer size in own structs for source and
> destination. This is in preparation for hooking up the dma-mapping API
> to the slave addresses.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> ---
>  drivers/dma/sh/rcar-dmac.c | 37 +
>  1 file changed, 21 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
> index 7820d07..743873c 100644
> --- a/drivers/dma/sh/rcar-dmac.c
> +++ b/drivers/dma/sh/rcar-dmac.c
> @@ -118,14 +118,21 @@ struct rcar_dmac_desc_page {
>   sizeof(struct rcar_dmac_xfer_chunk))
> 
>  /*
> + * @slave_addr: slave memory address
> + * @xfer_size: size (in bytes) of hardware transfers
> + */
> +struct rcar_dmac_chan_slave {
> + dma_addr_t slave_addr;
> + unsigned int xfer_size;
> +};
> +
> +/*
>   * struct rcar_dmac_chan - R-Car Gen2 DMA Controller Channel
>   * @chan: base DMA channel object
>   * @iomem: channel I/O memory base
>   * @index: index of this channel in the controller
> - * @src_xfer_size: size (in bytes) of hardware transfers on the source side
> - * @dst_xfer_size: size (in bytes) of hardware transfers on the
> destination side - * @src_slave_addr: slave source memory address
> - * @dst_slave_addr: slave destination memory address
> + * @src: slave memory address and size on the source side
> + * @dst: slave memory address and size on the destination side
>   * @mid_rid: hardware MID/RID for the DMA client using this channel
>   * @lock: protects the channel CHCR register and the desc members
>   * @desc.free: list of free descriptors
> @@ -142,10 +149,8 @@ struct rcar_dmac_chan {
>   void __iomem *iomem;
>   unsigned int index;
> 
> - unsigned int src_xfer_size;
> - unsigned int dst_xfer_size;
> - dma_addr_t src_slave_addr;
> - dma_addr_t dst_slave_addr;
> + struct rcar_dmac_chan_slave src;
> + struct rcar_dmac_chan_slave dst;
>   int mid_rid;
> 
>   spinlock_t lock;
> @@ -793,13 +798,13 @@ static void rcar_dmac_chan_configure_desc(struct
> rcar_dmac_chan *chan, case DMA_DEV_TO_MEM:
>   chcr = RCAR_DMACHCR_DM_INC | RCAR_DMACHCR_SM_FIXED
> 
>| RCAR_DMACHCR_RS_DMARS;
> 
> - xfer_size = chan->src_xfer_size;
> + xfer_size = chan->src.xfer_size;
>   break;
> 
>   case DMA_MEM_TO_DEV:
>   chcr = RCAR_DMACHCR_DM_FIXED | RCAR_DMACHCR_SM_INC
> 
>| RCAR_DMACHCR_RS_DMARS;
> 
> - xfer_size = chan->dst_xfer_size;
> + xfer_size = chan->dst.xfer_size;
>   break;
> 
>   case DMA_MEM_TO_MEM:
> @@ -1038,7 +1043,7 @@ rcar_dmac_prep_slave_sg(struct dma_chan *chan, struct
> scatterlist *sgl, }
> 
>   dev_addr = dir == DMA_DEV_TO_MEM
> -  ? rchan->src_slave_addr : rchan->dst_slave_addr;
> +  ? rchan->src.slave_addr : rchan->dst.slave_addr;
>   return rcar_dmac_chan_prep_sg(rchan, sgl, sg_len, dev_addr,
> dir, flags, false);
>  }
> @@ -1093,7 +1098,7 @@ rcar_dmac_prep_dma_cyclic(struct dma_chan *chan,
> dma_addr_t buf_addr, }
> 
>   dev_addr = dir == DMA_DEV_TO_MEM
> -  ? rchan->src_slave_addr : rchan->dst_slave_addr;
> +  ? rchan->src.slave_addr : rchan->dst.slave_addr;
>   desc = rcar_dmac_chan_prep_sg(rchan, sgl, sg_len, dev_addr,
> dir, flags, true);
> 
> @@ -1110,10 +1115,10 @@ static int rcar_dmac_device_config(struct dma_chan
> *chan, * We could lock this, but you shouldn't be configuring the
>* channel, while using it...
>*/
> - rchan->src_slave_addr = cfg->src_addr;
> - rchan->dst_slave_addr = cfg->dst_addr;
> - rchan->src_xfer_size = cfg->src_addr_width;
> - rchan->dst_xfer_size = cfg->dst_addr_width;
> + rchan->src.slave_addr = cfg->src_addr;
> + rchan->dst.slave_addr = cfg->dst_addr;
> + rchan->src.xfer_size = cfg->src_addr_width;
> + rchan->dst.xfer_size = cfg->dst_addr_width;
> 
>   return 0;
>  }

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH v2 3/3] iommu/io-pgtable: Avoid redundant TLB syncs

2016-01-15 Thread Laurent Pinchart
Hi Robin,

Thank you for the patch.

On Tuesday 12 January 2016 18:27:55 Will Deacon wrote:
> On Thu, Dec 17, 2015 at 08:50:59PM +, Robin Murphy wrote:
> > In certain unmapping situations it is quite possible to end up issuing
> > back-to-back TLB synchronisations, which at best is a waste of time and
> > effort, and at worst causes some hardware to get rather confused. Whilst
> > the pagetable implementations, or the IOMMU drivers, or both, could keep
> > track of things to avoid this happening, it seems to make the most sense
> > to prevent code duplication and add some simple state tracking in the
> > common interface between the two.
> > 
> > Signed-off-by: Robin Murphy <robin.mur...@arm.com>
> > ---
> > 
> >  drivers/iommu/io-pgtable.h | 9 -
> >  1 file changed, 8 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/iommu/io-pgtable.h b/drivers/iommu/io-pgtable.h
> > index 95c5565..d06219b 100644
> > --- a/drivers/iommu/io-pgtable.h
> > +++ b/drivers/iommu/io-pgtable.h
> > @@ -132,12 +132,14 @@ void free_io_pgtable_ops(struct io_pgtable_ops
> > *ops);
> > 
> >   * @fmt:The page table format.
> >   * @cookie: An opaque token provided by the IOMMU driver and passed back
> >   to
> >   *  any callback routines.
> > 
> > + * @sync_flag: Private flag for optimising out redundant syncs.
> 
> It makes sense to factor this out like you're proposing, but maybe we
> can think of a better name? How about "tlb_sync_pending", to follow
> "tlb_flush_pending" in the core code?

With tlb_sync_pending,

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH 01/06] iommu/ipmmu-vmsa: Remove platform data handling

2015-12-28 Thread Laurent Pinchart
Hi Magnus,

Thank you for the patch.

On Tuesday 15 December 2015 21:02:21 Magnus Damm wrote:
> From: Magnus Damm <damm+rene...@opensource.se>
> 
> The IPMMU driver is using DT these days, and platform data is no longer
> used by the driver. Remove unused code.
> 
> Signed-off-by: Magnus Damm <damm+rene...@opensource.se>

Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

> ---
> 
>  drivers/iommu/ipmmu-vmsa.c |5 -
>  1 file changed, 5 deletions(-)
> 
> --- 0001/drivers/iommu/ipmmu-vmsa.c
> +++ work/drivers/iommu/ipmmu-vmsa.c   2015-12-15 11:35:00.490513000 +0900
> @@ -766,11 +766,6 @@ static int ipmmu_probe(struct platform_d
>   int irq;
>   int ret;
> 
> - if (!IS_ENABLED(CONFIG_OF) && !pdev->dev.platform_data) {
> - dev_err(>dev, "missing platform data\n");
> - return -EINVAL;
> - }
> -
>   mmu = devm_kzalloc(>dev, sizeof(*mmu), GFP_KERNEL);
>   if (!mmu) {
>   dev_err(>dev, "cannot allocate device data\n");

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH 04/06] iommu/ipmmu-vmsa: Rework interrupt code and use bitmap for context

2015-12-28 Thread Laurent Pinchart
Hi Magnus,

Thank you for the patch.

On Tuesday 15 December 2015 21:02:49 Magnus Damm wrote:
> From: Magnus Damm <damm+rene...@opensource.se>
> 
> Introduce a bitmap for context handing and convert the
> interrupt routine to go handle all registered contexts.
> 
> At this point the number of contexts are still limited.

That's all nice, but without seeing support for multiple contexts it's hard to 
tell if the implementation is correct for multiple context purpose.

> The purpose of this patch is to remove the use of the
> ARM specific mapping variable from ipmmu_irq().

Why do you want to do that ?

> Signed-off-by: Magnus Damm <damm+rene...@opensource.se>
> ---
> 
>  drivers/iommu/ipmmu-vmsa.c |   37 ++---
>  1 file changed, 26 insertions(+), 11 deletions(-)
> 
> --- 0007/drivers/iommu/ipmmu-vmsa.c
> +++ work/drivers/iommu/ipmmu-vmsa.c   2015-12-15 13:14:35.540513000 +0900
> @@ -8,6 +8,7 @@
>   * the Free Software Foundation; version 2 of the License.
>   */
> 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -26,12 +27,16 @@
> 
>  #include "io-pgtable.h"
> 
> +#define IPMMU_CTX_MAX 1
> +
>  struct ipmmu_vmsa_device {
>   struct device *dev;
>   void __iomem *base;
>   struct list_head list;
> 
>   unsigned int num_utlbs;
> + DECLARE_BITMAP(ctx, IPMMU_CTX_MAX);

We have up to 4 context on Gen2 and 8 on Gen3, a bitmap might be slightly 
overkill.

> + struct ipmmu_vmsa_domain *domains[IPMMU_CTX_MAX];
> 
>   struct dma_iommu_mapping *mapping;
>  };
> @@ -319,6 +324,7 @@ static struct iommu_gather_ops ipmmu_gat
>  static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain)
>  {
>   phys_addr_t ttbr;
> + int ret;
> 
>   /*
>* Allocate the page table operations.
> @@ -348,10 +354,16 @@ static int ipmmu_domain_init_context(str
>   return -EINVAL;
> 
>   /*
> -  * TODO: When adding support for multiple contexts, find an unused
> -  * context.
> +  * Find an unused context.

We need to support multiple devices per context or we will very soon run out 
of contexts. How to pick a proper context is a topic that needs to be 
researched, I believe IOMMU groups might come into play.

>*/
> - domain->context_id = 0;
> + ret = bitmap_find_free_region(domain->mmu->ctx, IPMMU_CTX_MAX, 0);
> + if (ret < 0) {
> + free_io_pgtable_ops(domain->iop);
> + return ret;
> + }
> +
> + domain->context_id = ret;
> + domain->mmu->domains[ret] = domain;

This requires locking to protect against races with the interrupt handler.

> 
>   /* TTBR0 */
>   ttbr = domain->cfg.arm_lpae_s1_cfg.ttbr[0];
> @@ -395,6 +407,8 @@ static int ipmmu_domain_init_context(str
> 
>  static void ipmmu_domain_destroy_context(struct ipmmu_vmsa_domain *domain)
>  {
> + bitmap_release_region(domain->mmu->ctx, domain->context_id, 0);
> +
>   /*
>* Disable the context. Flush the TLB as required when modifying the
>* context registers.
> @@ -460,16 +474,16 @@ static irqreturn_t ipmmu_domain_irq(stru
>  static irqreturn_t ipmmu_irq(int irq, void *dev)
>  {
>   struct ipmmu_vmsa_device *mmu = dev;
> - struct iommu_domain *io_domain;
> - struct ipmmu_vmsa_domain *domain;
> -
> - if (!mmu->mapping)
> - return IRQ_NONE;
> + irqreturn_t status = IRQ_NONE;
> + unsigned int k;

i is a perfectly fine loop counter :-)

> - io_domain = mmu->mapping->domain;
> - domain = to_vmsa_domain(io_domain);
> + /* Check interrupts for all active contexts */
> + for (k = find_first_bit(mmu->ctx, IPMMU_CTX_MAX);
> +  k < IPMMU_CTX_MAX && status == IRQ_NONE;
> +  k = find_next_bit(mmu->ctx, IPMMU_CTX_MAX, k))

You can just loop over mmu->domains and skip NULL entries.

> + status = ipmmu_domain_irq(mmu->domains[k]);

Only the status of the last domain is taken into account.

> - return ipmmu_domain_irq(domain);
> + return status;
>  }
> 
>  /* 
> @@ -788,6 +802,7 @@ static int ipmmu_probe(struct platform_d
> 
>   mmu->dev = >dev;
>   mmu->num_utlbs = 32;
> + bitmap_zero(mmu->ctx, IPMMU_CTX_MAX);
> 
>   /* Map I/O memory and request IRQ. */
>   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH 05/06] iommu/ipmmu-vmsa: Break out 32-bit ARM mapping code

2015-12-28 Thread Laurent Pinchart
ttach_device(dev, mmu->mapping);
> - if (ret < 0) {
> - dev_err(dev, "Failed to attach device to VA mapping\n");
> + ret = ipmmu_map_attach(dev, mmu);
> + if (ret < 0)
>   goto error;
> - }
> 
>   return 0;
> 
>  error:
> - arm_iommu_release_mapping(mmu->mapping);
> -
>   kfree(dev_data);
>   kfree(utlbs);
> 
> @@ -751,7 +781,7 @@ static void ipmmu_remove_device(struct d
>  {
>   struct ipmmu_vmsa_dev_data *dev_data = get_dev_data(dev);
> 
> - arm_iommu_detach_device(dev);
> + ipmmu_detach(dev);
>   iommu_group_remove_device(dev);
> 
>   kfree(dev_data->utlbs);
> @@ -862,7 +892,7 @@ static int ipmmu_remove(struct platform_
>   list_del(>list);
>   spin_unlock(_devices_lock);
> 
> - arm_iommu_release_mapping(mmu->mapping);
> + ipmmu_release_mapping(mmu);
> 
>   ipmmu_device_reset(mmu);

-- 
Regards,

Laurent Pinchart

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


Re: [PATCH 02/06] iommu/ipmmu-vmsa: Convert to dev_data

2015-12-28 Thread Laurent Pinchart
_utlbs;
> - dev->archdata.iommu = archdata;
> + dev_data->mmu = mmu;
> + dev_data->utlbs = utlbs;
> + dev_data->num_utlbs = num_utlbs;
> + set_dev_data(dev, dev_data);
> 
>   /*
>* Create the ARM mapping, used by the ARM DMA mapping core to allocate
> @@ -708,10 +722,10 @@ static int ipmmu_add_device(struct devic
>  error:
>   arm_iommu_release_mapping(mmu->mapping);
> 
> - kfree(dev->archdata.iommu);
> + kfree(dev_data);
>   kfree(utlbs);
> 
> - dev->archdata.iommu = NULL;
> + set_dev_data(dev, NULL);
> 
>   if (!IS_ERR_OR_NULL(group))
>   iommu_group_remove_device(dev);
> @@ -721,15 +735,15 @@ error:
> 
>  static void ipmmu_remove_device(struct device *dev)
>  {
> - struct ipmmu_vmsa_archdata *archdata = dev->archdata.iommu;
> + struct ipmmu_vmsa_dev_data *dev_data = get_dev_data(dev);
> 
>   arm_iommu_detach_device(dev);
>   iommu_group_remove_device(dev);
> 
> - kfree(archdata->utlbs);
> - kfree(archdata);
> + kfree(dev_data->utlbs);
> + kfree(dev_data);
> 
> - dev->archdata.iommu = NULL;
> + set_dev_data(dev, NULL);
>  }
> 
>  static const struct iommu_ops ipmmu_ops = {

-- 
Regards,

Laurent Pinchart

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


  1   2   3   4   >