All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
@ 2023-11-03 16:44 ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is a more complete solution that the first attempt here:
https://lore.kernel.org/r/1698825902-10685-1-git-send-email-quic_zhenhuah@quicinc.com

I haven't been able to test this on any HW that touches these paths, so if
some people with HW can help get it in shape it can become non-RFC.


The iommu subsystem uses dev->iommu to store bits of information about the
attached iommu driver. This has been co-opted by the ACPI/OF code to also
be a place to pass around the iommu_fwspec before a driver is probed.

Since both are using the same pointers without any locking it triggers
races if there is concurrent driver loading:

     CPU0                                     CPU1
of_iommu_configure()                iommu_device_register()
 ..                                   bus_iommu_probe()
  iommu_fwspec_of_xlate()              __iommu_probe_device()
                                        iommu_init_device()
   dev_iommu_get()
                                          .. ops->probe fails, no fwspec ..
                                          dev_iommu_free()
   dev->iommu->fwspec    *crash*

My first attempt get correct locking here was to use the device_lock to
protect the entire *_iommu_configure() and iommu_probe() paths. This
allowed safe use of dev->iommu within those paths. Unfortuately enough
drivers abuse the of_iommu_configure() flow without proper locking and
this approach failed.

This approach removes touches of dev->iommu from the *_iommu_configure()
code. The few remaining required touches are moved into iommu.c and
protected with the existing iommu_probe_device_lock.

To do this we change *_iommu_configure() to hold the iommu_fwspec on the
stack while it is being built. Once it is fully formed the core code will
install it into the dev->iommu when it calls probe.

This also removes all the touches of iommu_ops from
the *_iommu_configure() paths and makes that mechanism private to the
iommu core.

A few more lockdep assertions are added to discourage future mis-use.

This is on github: https://github.com/jgunthorpe/linux/commits/iommu_fwspec

Jason Gunthorpe (17):
  iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
  of: Do not return struct iommu_ops from of_iommu_configure()
  of: Use -ENODEV consistently in of_iommu_configure()
  acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
  iommu: Make iommu_fwspec->ids a distinct allocation
  iommu: Add iommu_fwspec_alloc/dealloc()
  iommu: Add iommu_probe_device_fwspec()
  of: Do not use dev->iommu within of_iommu_configure()
  iommu: Add iommu_fwspec_append_ids()
  acpi: Do not use dev->iommu within acpi_iommu_configure()
  iommu: Hold iommu_probe_device_lock while calling ops->of_xlate
  iommu: Make iommu_ops_from_fwnode() static
  iommu: Remove dev_iommu_fwspec_set()
  iommu: Remove pointless iommu_fwspec_free()
  iommu: Add ops->of_xlate_fwspec()
  iommu: Mark dev_iommu_get() with lockdep
  iommu: Mark dev_iommu_priv_set() with a lockdep

 arch/arc/mm/dma.c                           |   2 +-
 arch/arm/mm/dma-mapping-nommu.c             |   2 +-
 arch/arm/mm/dma-mapping.c                   |  10 +-
 arch/arm64/mm/dma-mapping.c                 |   4 +-
 arch/mips/mm/dma-noncoherent.c              |   2 +-
 arch/riscv/mm/dma-noncoherent.c             |   2 +-
 drivers/acpi/arm64/iort.c                   |  39 ++--
 drivers/acpi/scan.c                         | 104 +++++----
 drivers/acpi/viot.c                         |  44 ++--
 drivers/hv/hv_common.c                      |   2 +-
 drivers/iommu/amd/iommu.c                   |   2 -
 drivers/iommu/apple-dart.c                  |   1 -
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |   9 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.c       |  23 +-
 drivers/iommu/intel/iommu.c                 |   2 -
 drivers/iommu/iommu.c                       | 227 +++++++++++++++-----
 drivers/iommu/of_iommu.c                    | 129 +++++------
 drivers/iommu/omap-iommu.c                  |   1 -
 drivers/iommu/tegra-smmu.c                  |   1 -
 drivers/iommu/virtio-iommu.c                |   8 +-
 drivers/of/device.c                         |  24 ++-
 include/acpi/acpi_bus.h                     |   8 +-
 include/linux/acpi_iort.h                   |   3 +-
 include/linux/acpi_viot.h                   |   5 +-
 include/linux/dma-map-ops.h                 |   4 +-
 include/linux/iommu.h                       |  46 ++--
 include/linux/of_iommu.h                    |  13 +-
 27 files changed, 417 insertions(+), 300 deletions(-)


base-commit: ab41f1aafb43c2555b358147b14b4d7b8105b452
-- 
2.42.0


^ permalink raw reply	[flat|nested] 242+ messages in thread

* [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
@ 2023-11-03 16:44 ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is a more complete solution that the first attempt here:
https://lore.kernel.org/r/1698825902-10685-1-git-send-email-quic_zhenhuah@quicinc.com

I haven't been able to test this on any HW that touches these paths, so if
some people with HW can help get it in shape it can become non-RFC.


The iommu subsystem uses dev->iommu to store bits of information about the
attached iommu driver. This has been co-opted by the ACPI/OF code to also
be a place to pass around the iommu_fwspec before a driver is probed.

Since both are using the same pointers without any locking it triggers
races if there is concurrent driver loading:

     CPU0                                     CPU1
of_iommu_configure()                iommu_device_register()
 ..                                   bus_iommu_probe()
  iommu_fwspec_of_xlate()              __iommu_probe_device()
                                        iommu_init_device()
   dev_iommu_get()
                                          .. ops->probe fails, no fwspec ..
                                          dev_iommu_free()
   dev->iommu->fwspec    *crash*

My first attempt get correct locking here was to use the device_lock to
protect the entire *_iommu_configure() and iommu_probe() paths. This
allowed safe use of dev->iommu within those paths. Unfortuately enough
drivers abuse the of_iommu_configure() flow without proper locking and
this approach failed.

This approach removes touches of dev->iommu from the *_iommu_configure()
code. The few remaining required touches are moved into iommu.c and
protected with the existing iommu_probe_device_lock.

To do this we change *_iommu_configure() to hold the iommu_fwspec on the
stack while it is being built. Once it is fully formed the core code will
install it into the dev->iommu when it calls probe.

This also removes all the touches of iommu_ops from
the *_iommu_configure() paths and makes that mechanism private to the
iommu core.

A few more lockdep assertions are added to discourage future mis-use.

This is on github: https://github.com/jgunthorpe/linux/commits/iommu_fwspec

Jason Gunthorpe (17):
  iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
  of: Do not return struct iommu_ops from of_iommu_configure()
  of: Use -ENODEV consistently in of_iommu_configure()
  acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
  iommu: Make iommu_fwspec->ids a distinct allocation
  iommu: Add iommu_fwspec_alloc/dealloc()
  iommu: Add iommu_probe_device_fwspec()
  of: Do not use dev->iommu within of_iommu_configure()
  iommu: Add iommu_fwspec_append_ids()
  acpi: Do not use dev->iommu within acpi_iommu_configure()
  iommu: Hold iommu_probe_device_lock while calling ops->of_xlate
  iommu: Make iommu_ops_from_fwnode() static
  iommu: Remove dev_iommu_fwspec_set()
  iommu: Remove pointless iommu_fwspec_free()
  iommu: Add ops->of_xlate_fwspec()
  iommu: Mark dev_iommu_get() with lockdep
  iommu: Mark dev_iommu_priv_set() with a lockdep

 arch/arc/mm/dma.c                           |   2 +-
 arch/arm/mm/dma-mapping-nommu.c             |   2 +-
 arch/arm/mm/dma-mapping.c                   |  10 +-
 arch/arm64/mm/dma-mapping.c                 |   4 +-
 arch/mips/mm/dma-noncoherent.c              |   2 +-
 arch/riscv/mm/dma-noncoherent.c             |   2 +-
 drivers/acpi/arm64/iort.c                   |  39 ++--
 drivers/acpi/scan.c                         | 104 +++++----
 drivers/acpi/viot.c                         |  44 ++--
 drivers/hv/hv_common.c                      |   2 +-
 drivers/iommu/amd/iommu.c                   |   2 -
 drivers/iommu/apple-dart.c                  |   1 -
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |   9 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.c       |  23 +-
 drivers/iommu/intel/iommu.c                 |   2 -
 drivers/iommu/iommu.c                       | 227 +++++++++++++++-----
 drivers/iommu/of_iommu.c                    | 129 +++++------
 drivers/iommu/omap-iommu.c                  |   1 -
 drivers/iommu/tegra-smmu.c                  |   1 -
 drivers/iommu/virtio-iommu.c                |   8 +-
 drivers/of/device.c                         |  24 ++-
 include/acpi/acpi_bus.h                     |   8 +-
 include/linux/acpi_iort.h                   |   3 +-
 include/linux/acpi_viot.h                   |   5 +-
 include/linux/dma-map-ops.h                 |   4 +-
 include/linux/iommu.h                       |  46 ++--
 include/linux/of_iommu.h                    |  13 +-
 27 files changed, 417 insertions(+), 300 deletions(-)


base-commit: ab41f1aafb43c2555b358147b14b4d7b8105b452
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
@ 2023-11-03 16:44 ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is a more complete solution that the first attempt here:
https://lore.kernel.org/r/1698825902-10685-1-git-send-email-quic_zhenhuah@quicinc.com

I haven't been able to test this on any HW that touches these paths, so if
some people with HW can help get it in shape it can become non-RFC.


The iommu subsystem uses dev->iommu to store bits of information about the
attached iommu driver. This has been co-opted by the ACPI/OF code to also
be a place to pass around the iommu_fwspec before a driver is probed.

Since both are using the same pointers without any locking it triggers
races if there is concurrent driver loading:

     CPU0                                     CPU1
of_iommu_configure()                iommu_device_register()
 ..                                   bus_iommu_probe()
  iommu_fwspec_of_xlate()              __iommu_probe_device()
                                        iommu_init_device()
   dev_iommu_get()
                                          .. ops->probe fails, no fwspec ..
                                          dev_iommu_free()
   dev->iommu->fwspec    *crash*

My first attempt get correct locking here was to use the device_lock to
protect the entire *_iommu_configure() and iommu_probe() paths. This
allowed safe use of dev->iommu within those paths. Unfortuately enough
drivers abuse the of_iommu_configure() flow without proper locking and
this approach failed.

This approach removes touches of dev->iommu from the *_iommu_configure()
code. The few remaining required touches are moved into iommu.c and
protected with the existing iommu_probe_device_lock.

To do this we change *_iommu_configure() to hold the iommu_fwspec on the
stack while it is being built. Once it is fully formed the core code will
install it into the dev->iommu when it calls probe.

This also removes all the touches of iommu_ops from
the *_iommu_configure() paths and makes that mechanism private to the
iommu core.

A few more lockdep assertions are added to discourage future mis-use.

This is on github: https://github.com/jgunthorpe/linux/commits/iommu_fwspec

Jason Gunthorpe (17):
  iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
  of: Do not return struct iommu_ops from of_iommu_configure()
  of: Use -ENODEV consistently in of_iommu_configure()
  acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
  iommu: Make iommu_fwspec->ids a distinct allocation
  iommu: Add iommu_fwspec_alloc/dealloc()
  iommu: Add iommu_probe_device_fwspec()
  of: Do not use dev->iommu within of_iommu_configure()
  iommu: Add iommu_fwspec_append_ids()
  acpi: Do not use dev->iommu within acpi_iommu_configure()
  iommu: Hold iommu_probe_device_lock while calling ops->of_xlate
  iommu: Make iommu_ops_from_fwnode() static
  iommu: Remove dev_iommu_fwspec_set()
  iommu: Remove pointless iommu_fwspec_free()
  iommu: Add ops->of_xlate_fwspec()
  iommu: Mark dev_iommu_get() with lockdep
  iommu: Mark dev_iommu_priv_set() with a lockdep

 arch/arc/mm/dma.c                           |   2 +-
 arch/arm/mm/dma-mapping-nommu.c             |   2 +-
 arch/arm/mm/dma-mapping.c                   |  10 +-
 arch/arm64/mm/dma-mapping.c                 |   4 +-
 arch/mips/mm/dma-noncoherent.c              |   2 +-
 arch/riscv/mm/dma-noncoherent.c             |   2 +-
 drivers/acpi/arm64/iort.c                   |  39 ++--
 drivers/acpi/scan.c                         | 104 +++++----
 drivers/acpi/viot.c                         |  44 ++--
 drivers/hv/hv_common.c                      |   2 +-
 drivers/iommu/amd/iommu.c                   |   2 -
 drivers/iommu/apple-dart.c                  |   1 -
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |   9 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.c       |  23 +-
 drivers/iommu/intel/iommu.c                 |   2 -
 drivers/iommu/iommu.c                       | 227 +++++++++++++++-----
 drivers/iommu/of_iommu.c                    | 129 +++++------
 drivers/iommu/omap-iommu.c                  |   1 -
 drivers/iommu/tegra-smmu.c                  |   1 -
 drivers/iommu/virtio-iommu.c                |   8 +-
 drivers/of/device.c                         |  24 ++-
 include/acpi/acpi_bus.h                     |   8 +-
 include/linux/acpi_iort.h                   |   3 +-
 include/linux/acpi_viot.h                   |   5 +-
 include/linux/dma-map-ops.h                 |   4 +-
 include/linux/iommu.h                       |  46 ++--
 include/linux/of_iommu.h                    |  13 +-
 27 files changed, 417 insertions(+), 300 deletions(-)


base-commit: ab41f1aafb43c2555b358147b14b4d7b8105b452
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
@ 2023-11-03 16:44 ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is a more complete solution that the first attempt here:
https://lore.kernel.org/r/1698825902-10685-1-git-send-email-quic_zhenhuah@quicinc.com

I haven't been able to test this on any HW that touches these paths, so if
some people with HW can help get it in shape it can become non-RFC.


The iommu subsystem uses dev->iommu to store bits of information about the
attached iommu driver. This has been co-opted by the ACPI/OF code to also
be a place to pass around the iommu_fwspec before a driver is probed.

Since both are using the same pointers without any locking it triggers
races if there is concurrent driver loading:

     CPU0                                     CPU1
of_iommu_configure()                iommu_device_register()
 ..                                   bus_iommu_probe()
  iommu_fwspec_of_xlate()              __iommu_probe_device()
                                        iommu_init_device()
   dev_iommu_get()
                                          .. ops->probe fails, no fwspec ..
                                          dev_iommu_free()
   dev->iommu->fwspec    *crash*

My first attempt get correct locking here was to use the device_lock to
protect the entire *_iommu_configure() and iommu_probe() paths. This
allowed safe use of dev->iommu within those paths. Unfortuately enough
drivers abuse the of_iommu_configure() flow without proper locking and
this approach failed.

This approach removes touches of dev->iommu from the *_iommu_configure()
code. The few remaining required touches are moved into iommu.c and
protected with the existing iommu_probe_device_lock.

To do this we change *_iommu_configure() to hold the iommu_fwspec on the
stack while it is being built. Once it is fully formed the core code will
install it into the dev->iommu when it calls probe.

This also removes all the touches of iommu_ops from
the *_iommu_configure() paths and makes that mechanism private to the
iommu core.

A few more lockdep assertions are added to discourage future mis-use.

This is on github: https://github.com/jgunthorpe/linux/commits/iommu_fwspec

Jason Gunthorpe (17):
  iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
  of: Do not return struct iommu_ops from of_iommu_configure()
  of: Use -ENODEV consistently in of_iommu_configure()
  acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
  iommu: Make iommu_fwspec->ids a distinct allocation
  iommu: Add iommu_fwspec_alloc/dealloc()
  iommu: Add iommu_probe_device_fwspec()
  of: Do not use dev->iommu within of_iommu_configure()
  iommu: Add iommu_fwspec_append_ids()
  acpi: Do not use dev->iommu within acpi_iommu_configure()
  iommu: Hold iommu_probe_device_lock while calling ops->of_xlate
  iommu: Make iommu_ops_from_fwnode() static
  iommu: Remove dev_iommu_fwspec_set()
  iommu: Remove pointless iommu_fwspec_free()
  iommu: Add ops->of_xlate_fwspec()
  iommu: Mark dev_iommu_get() with lockdep
  iommu: Mark dev_iommu_priv_set() with a lockdep

 arch/arc/mm/dma.c                           |   2 +-
 arch/arm/mm/dma-mapping-nommu.c             |   2 +-
 arch/arm/mm/dma-mapping.c                   |  10 +-
 arch/arm64/mm/dma-mapping.c                 |   4 +-
 arch/mips/mm/dma-noncoherent.c              |   2 +-
 arch/riscv/mm/dma-noncoherent.c             |   2 +-
 drivers/acpi/arm64/iort.c                   |  39 ++--
 drivers/acpi/scan.c                         | 104 +++++----
 drivers/acpi/viot.c                         |  44 ++--
 drivers/hv/hv_common.c                      |   2 +-
 drivers/iommu/amd/iommu.c                   |   2 -
 drivers/iommu/apple-dart.c                  |   1 -
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |   9 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.c       |  23 +-
 drivers/iommu/intel/iommu.c                 |   2 -
 drivers/iommu/iommu.c                       | 227 +++++++++++++++-----
 drivers/iommu/of_iommu.c                    | 129 +++++------
 drivers/iommu/omap-iommu.c                  |   1 -
 drivers/iommu/tegra-smmu.c                  |   1 -
 drivers/iommu/virtio-iommu.c                |   8 +-
 drivers/of/device.c                         |  24 ++-
 include/acpi/acpi_bus.h                     |   8 +-
 include/linux/acpi_iort.h                   |   3 +-
 include/linux/acpi_viot.h                   |   5 +-
 include/linux/dma-map-ops.h                 |   4 +-
 include/linux/iommu.h                       |  46 ++--
 include/linux/of_iommu.h                    |  13 +-
 27 files changed, 417 insertions(+), 300 deletions(-)


base-commit: ab41f1aafb43c2555b358147b14b4d7b8105b452
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
@ 2023-11-03 16:44 ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is a more complete solution that the first attempt here:
https://lore.kernel.org/r/1698825902-10685-1-git-send-email-quic_zhenhuah@quicinc.com

I haven't been able to test this on any HW that touches these paths, so if
some people with HW can help get it in shape it can become non-RFC.


The iommu subsystem uses dev->iommu to store bits of information about the
attached iommu driver. This has been co-opted by the ACPI/OF code to also
be a place to pass around the iommu_fwspec before a driver is probed.

Since both are using the same pointers without any locking it triggers
races if there is concurrent driver loading:

     CPU0                                     CPU1
of_iommu_configure()                iommu_device_register()
 ..                                   bus_iommu_probe()
  iommu_fwspec_of_xlate()              __iommu_probe_device()
                                        iommu_init_device()
   dev_iommu_get()
                                          .. ops->probe fails, no fwspec ..
                                          dev_iommu_free()
   dev->iommu->fwspec    *crash*

My first attempt get correct locking here was to use the device_lock to
protect the entire *_iommu_configure() and iommu_probe() paths. This
allowed safe use of dev->iommu within those paths. Unfortuately enough
drivers abuse the of_iommu_configure() flow without proper locking and
this approach failed.

This approach removes touches of dev->iommu from the *_iommu_configure()
code. The few remaining required touches are moved into iommu.c and
protected with the existing iommu_probe_device_lock.

To do this we change *_iommu_configure() to hold the iommu_fwspec on the
stack while it is being built. Once it is fully formed the core code will
install it into the dev->iommu when it calls probe.

This also removes all the touches of iommu_ops from
the *_iommu_configure() paths and makes that mechanism private to the
iommu core.

A few more lockdep assertions are added to discourage future mis-use.

This is on github: https://github.com/jgunthorpe/linux/commits/iommu_fwspec

Jason Gunthorpe (17):
  iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
  of: Do not return struct iommu_ops from of_iommu_configure()
  of: Use -ENODEV consistently in of_iommu_configure()
  acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
  iommu: Make iommu_fwspec->ids a distinct allocation
  iommu: Add iommu_fwspec_alloc/dealloc()
  iommu: Add iommu_probe_device_fwspec()
  of: Do not use dev->iommu within of_iommu_configure()
  iommu: Add iommu_fwspec_append_ids()
  acpi: Do not use dev->iommu within acpi_iommu_configure()
  iommu: Hold iommu_probe_device_lock while calling ops->of_xlate
  iommu: Make iommu_ops_from_fwnode() static
  iommu: Remove dev_iommu_fwspec_set()
  iommu: Remove pointless iommu_fwspec_free()
  iommu: Add ops->of_xlate_fwspec()
  iommu: Mark dev_iommu_get() with lockdep
  iommu: Mark dev_iommu_priv_set() with a lockdep

 arch/arc/mm/dma.c                           |   2 +-
 arch/arm/mm/dma-mapping-nommu.c             |   2 +-
 arch/arm/mm/dma-mapping.c                   |  10 +-
 arch/arm64/mm/dma-mapping.c                 |   4 +-
 arch/mips/mm/dma-noncoherent.c              |   2 +-
 arch/riscv/mm/dma-noncoherent.c             |   2 +-
 drivers/acpi/arm64/iort.c                   |  39 ++--
 drivers/acpi/scan.c                         | 104 +++++----
 drivers/acpi/viot.c                         |  44 ++--
 drivers/hv/hv_common.c                      |   2 +-
 drivers/iommu/amd/iommu.c                   |   2 -
 drivers/iommu/apple-dart.c                  |   1 -
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |   9 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.c       |  23 +-
 drivers/iommu/intel/iommu.c                 |   2 -
 drivers/iommu/iommu.c                       | 227 +++++++++++++++-----
 drivers/iommu/of_iommu.c                    | 129 +++++------
 drivers/iommu/omap-iommu.c                  |   1 -
 drivers/iommu/tegra-smmu.c                  |   1 -
 drivers/iommu/virtio-iommu.c                |   8 +-
 drivers/of/device.c                         |  24 ++-
 include/acpi/acpi_bus.h                     |   8 +-
 include/linux/acpi_iort.h                   |   3 +-
 include/linux/acpi_viot.h                   |   5 +-
 include/linux/dma-map-ops.h                 |   4 +-
 include/linux/iommu.h                       |  46 ++--
 include/linux/of_iommu.h                    |  13 +-
 27 files changed, 417 insertions(+), 300 deletions(-)


base-commit: ab41f1aafb43c2555b358147b14b4d7b8105b452
-- 
2.42.0


^ permalink raw reply	[flat|nested] 242+ messages in thread

* [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:44   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is not being used to pass ops, it is just a way to tell if an
iommu driver was probed. These days this can be detected directly via
device_iommu_mapped(). Call device_iommu_mapped() in the two places that
need to check it and remove the iommu parameter everywhere.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 arch/arc/mm/dma.c               |  2 +-
 arch/arm/mm/dma-mapping-nommu.c |  2 +-
 arch/arm/mm/dma-mapping.c       | 10 +++++-----
 arch/arm64/mm/dma-mapping.c     |  4 ++--
 arch/mips/mm/dma-noncoherent.c  |  2 +-
 arch/riscv/mm/dma-noncoherent.c |  2 +-
 drivers/acpi/scan.c             |  3 +--
 drivers/hv/hv_common.c          |  2 +-
 drivers/of/device.c             |  2 +-
 include/linux/dma-map-ops.h     |  4 ++--
 10 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index 2a7fbbb83b7056..197707bc765889 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -91,7 +91,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
  * Plug in direct dma map ops.
  */
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	/*
 	 * IOC hardware snoops all DMA traffic keeping the caches consistent
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
index cfd9c933d2f09c..b94850b579952a 100644
--- a/arch/arm/mm/dma-mapping-nommu.c
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -34,7 +34,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 }
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	if (IS_ENABLED(CONFIG_CPU_V7M)) {
 		/*
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 5409225b4abc06..6c359a3af8d9c7 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1713,7 +1713,7 @@ void arm_iommu_detach_device(struct device *dev)
 EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
 
 static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
-				    const struct iommu_ops *iommu, bool coherent)
+				    bool coherent)
 {
 	struct dma_iommu_mapping *mapping;
 
@@ -1748,7 +1748,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
 #else
 
 static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
-				    const struct iommu_ops *iommu, bool coherent)
+				    bool coherent)
 {
 }
 
@@ -1757,7 +1757,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }
 #endif	/* CONFIG_ARM_DMA_USE_IOMMU */
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	/*
 	 * Due to legacy code that sets the ->dma_coherent flag from a bus
@@ -1776,8 +1776,8 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 	if (dev->dma_ops)
 		return;
 
-	if (iommu)
-		arm_setup_iommu_dma_ops(dev, dma_base, size, iommu, coherent);
+	if (device_iommu_mapped(dev))
+		arm_setup_iommu_dma_ops(dev, dma_base, size, coherent);
 
 	xen_setup_dma_ops(dev);
 	dev->archdata.dma_ops_setup = true;
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 3cb101e8cb29ba..61886e43e3a10f 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -47,7 +47,7 @@ void arch_teardown_dma_ops(struct device *dev)
 #endif
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	int cls = cache_line_size_of_cpu();
 
@@ -58,7 +58,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 		   ARCH_DMA_MINALIGN, cls);
 
 	dev->dma_coherent = coherent;
-	if (iommu)
+	if (device_iommu_mapped(dev))
 		iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1);
 
 	xen_setup_dma_ops(dev);
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index 3c4fc97b9f394b..0f3cec663a12cd 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -138,7 +138,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 
 #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		const struct iommu_ops *iommu, bool coherent)
+		bool coherent)
 {
 	dev->dma_coherent = coherent;
 }
diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
index b76e7e192eb183..f91fa741c41211 100644
--- a/arch/riscv/mm/dma-noncoherent.c
+++ b/arch/riscv/mm/dma-noncoherent.c
@@ -135,7 +135,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
 }
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	WARN_TAINT(!coherent && riscv_cbom_block_size > ARCH_DMA_MINALIGN,
 		   TAINT_CPU_OUT_OF_SPEC,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 691d4b7686ee7e..a6891ad0ceee2c 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1636,8 +1636,7 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 	if (PTR_ERR(iommu) == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
-	arch_setup_dma_ops(dev, 0, U64_MAX,
-				iommu, attr == DEV_DMA_COHERENT);
+	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
 
 	return 0;
 }
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index ccad7bca3fd3da..fd938b6dfa7ed4 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -489,7 +489,7 @@ void hv_setup_dma_ops(struct device *dev, bool coherent)
 	 * Hyper-V does not offer a vIOMMU in the guest
 	 * VM, so pass 0/NULL for the IOMMU settings
 	 */
-	arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
+	arch_setup_dma_ops(dev, 0, 0, coherent);
 }
 EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
 
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 1ca42ad9dd159d..65c71be71a8d45 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -193,7 +193,7 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 	dev_dbg(dev, "device is%sbehind an iommu\n",
 		iommu ? " " : " not ");
 
-	arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
+	arch_setup_dma_ops(dev, dma_start, size, coherent);
 
 	if (!iommu)
 		of_dma_set_restricted_buffer(dev, np);
diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
index f2fc203fb8a1a2..2cb98a12c50348 100644
--- a/include/linux/dma-map-ops.h
+++ b/include/linux/dma-map-ops.h
@@ -426,10 +426,10 @@ bool arch_dma_unmap_sg_direct(struct device *dev, struct scatterlist *sg,
 
 #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		const struct iommu_ops *iommu, bool coherent);
+		bool coherent);
 #else
 static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
-		u64 size, const struct iommu_ops *iommu, bool coherent)
+		u64 size, bool coherent)
 {
 }
 #endif /* CONFIG_ARCH_HAS_SETUP_DMA_OPS */
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is not being used to pass ops, it is just a way to tell if an
iommu driver was probed. These days this can be detected directly via
device_iommu_mapped(). Call device_iommu_mapped() in the two places that
need to check it and remove the iommu parameter everywhere.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 arch/arc/mm/dma.c               |  2 +-
 arch/arm/mm/dma-mapping-nommu.c |  2 +-
 arch/arm/mm/dma-mapping.c       | 10 +++++-----
 arch/arm64/mm/dma-mapping.c     |  4 ++--
 arch/mips/mm/dma-noncoherent.c  |  2 +-
 arch/riscv/mm/dma-noncoherent.c |  2 +-
 drivers/acpi/scan.c             |  3 +--
 drivers/hv/hv_common.c          |  2 +-
 drivers/of/device.c             |  2 +-
 include/linux/dma-map-ops.h     |  4 ++--
 10 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index 2a7fbbb83b7056..197707bc765889 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -91,7 +91,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
  * Plug in direct dma map ops.
  */
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	/*
 	 * IOC hardware snoops all DMA traffic keeping the caches consistent
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
index cfd9c933d2f09c..b94850b579952a 100644
--- a/arch/arm/mm/dma-mapping-nommu.c
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -34,7 +34,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 }
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	if (IS_ENABLED(CONFIG_CPU_V7M)) {
 		/*
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 5409225b4abc06..6c359a3af8d9c7 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1713,7 +1713,7 @@ void arm_iommu_detach_device(struct device *dev)
 EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
 
 static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
-				    const struct iommu_ops *iommu, bool coherent)
+				    bool coherent)
 {
 	struct dma_iommu_mapping *mapping;
 
@@ -1748,7 +1748,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
 #else
 
 static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
-				    const struct iommu_ops *iommu, bool coherent)
+				    bool coherent)
 {
 }
 
@@ -1757,7 +1757,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }
 #endif	/* CONFIG_ARM_DMA_USE_IOMMU */
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	/*
 	 * Due to legacy code that sets the ->dma_coherent flag from a bus
@@ -1776,8 +1776,8 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 	if (dev->dma_ops)
 		return;
 
-	if (iommu)
-		arm_setup_iommu_dma_ops(dev, dma_base, size, iommu, coherent);
+	if (device_iommu_mapped(dev))
+		arm_setup_iommu_dma_ops(dev, dma_base, size, coherent);
 
 	xen_setup_dma_ops(dev);
 	dev->archdata.dma_ops_setup = true;
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 3cb101e8cb29ba..61886e43e3a10f 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -47,7 +47,7 @@ void arch_teardown_dma_ops(struct device *dev)
 #endif
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	int cls = cache_line_size_of_cpu();
 
@@ -58,7 +58,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 		   ARCH_DMA_MINALIGN, cls);
 
 	dev->dma_coherent = coherent;
-	if (iommu)
+	if (device_iommu_mapped(dev))
 		iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1);
 
 	xen_setup_dma_ops(dev);
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index 3c4fc97b9f394b..0f3cec663a12cd 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -138,7 +138,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 
 #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		const struct iommu_ops *iommu, bool coherent)
+		bool coherent)
 {
 	dev->dma_coherent = coherent;
 }
diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
index b76e7e192eb183..f91fa741c41211 100644
--- a/arch/riscv/mm/dma-noncoherent.c
+++ b/arch/riscv/mm/dma-noncoherent.c
@@ -135,7 +135,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
 }
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	WARN_TAINT(!coherent && riscv_cbom_block_size > ARCH_DMA_MINALIGN,
 		   TAINT_CPU_OUT_OF_SPEC,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 691d4b7686ee7e..a6891ad0ceee2c 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1636,8 +1636,7 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 	if (PTR_ERR(iommu) == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
-	arch_setup_dma_ops(dev, 0, U64_MAX,
-				iommu, attr == DEV_DMA_COHERENT);
+	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
 
 	return 0;
 }
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index ccad7bca3fd3da..fd938b6dfa7ed4 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -489,7 +489,7 @@ void hv_setup_dma_ops(struct device *dev, bool coherent)
 	 * Hyper-V does not offer a vIOMMU in the guest
 	 * VM, so pass 0/NULL for the IOMMU settings
 	 */
-	arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
+	arch_setup_dma_ops(dev, 0, 0, coherent);
 }
 EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
 
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 1ca42ad9dd159d..65c71be71a8d45 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -193,7 +193,7 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 	dev_dbg(dev, "device is%sbehind an iommu\n",
 		iommu ? " " : " not ");
 
-	arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
+	arch_setup_dma_ops(dev, dma_start, size, coherent);
 
 	if (!iommu)
 		of_dma_set_restricted_buffer(dev, np);
diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
index f2fc203fb8a1a2..2cb98a12c50348 100644
--- a/include/linux/dma-map-ops.h
+++ b/include/linux/dma-map-ops.h
@@ -426,10 +426,10 @@ bool arch_dma_unmap_sg_direct(struct device *dev, struct scatterlist *sg,
 
 #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		const struct iommu_ops *iommu, bool coherent);
+		bool coherent);
 #else
 static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
-		u64 size, const struct iommu_ops *iommu, bool coherent)
+		u64 size, bool coherent)
 {
 }
 #endif /* CONFIG_ARCH_HAS_SETUP_DMA_OPS */
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is not being used to pass ops, it is just a way to tell if an
iommu driver was probed. These days this can be detected directly via
device_iommu_mapped(). Call device_iommu_mapped() in the two places that
need to check it and remove the iommu parameter everywhere.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 arch/arc/mm/dma.c               |  2 +-
 arch/arm/mm/dma-mapping-nommu.c |  2 +-
 arch/arm/mm/dma-mapping.c       | 10 +++++-----
 arch/arm64/mm/dma-mapping.c     |  4 ++--
 arch/mips/mm/dma-noncoherent.c  |  2 +-
 arch/riscv/mm/dma-noncoherent.c |  2 +-
 drivers/acpi/scan.c             |  3 +--
 drivers/hv/hv_common.c          |  2 +-
 drivers/of/device.c             |  2 +-
 include/linux/dma-map-ops.h     |  4 ++--
 10 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index 2a7fbbb83b7056..197707bc765889 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -91,7 +91,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
  * Plug in direct dma map ops.
  */
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	/*
 	 * IOC hardware snoops all DMA traffic keeping the caches consistent
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
index cfd9c933d2f09c..b94850b579952a 100644
--- a/arch/arm/mm/dma-mapping-nommu.c
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -34,7 +34,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 }
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	if (IS_ENABLED(CONFIG_CPU_V7M)) {
 		/*
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 5409225b4abc06..6c359a3af8d9c7 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1713,7 +1713,7 @@ void arm_iommu_detach_device(struct device *dev)
 EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
 
 static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
-				    const struct iommu_ops *iommu, bool coherent)
+				    bool coherent)
 {
 	struct dma_iommu_mapping *mapping;
 
@@ -1748,7 +1748,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
 #else
 
 static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
-				    const struct iommu_ops *iommu, bool coherent)
+				    bool coherent)
 {
 }
 
@@ -1757,7 +1757,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }
 #endif	/* CONFIG_ARM_DMA_USE_IOMMU */
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	/*
 	 * Due to legacy code that sets the ->dma_coherent flag from a bus
@@ -1776,8 +1776,8 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 	if (dev->dma_ops)
 		return;
 
-	if (iommu)
-		arm_setup_iommu_dma_ops(dev, dma_base, size, iommu, coherent);
+	if (device_iommu_mapped(dev))
+		arm_setup_iommu_dma_ops(dev, dma_base, size, coherent);
 
 	xen_setup_dma_ops(dev);
 	dev->archdata.dma_ops_setup = true;
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 3cb101e8cb29ba..61886e43e3a10f 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -47,7 +47,7 @@ void arch_teardown_dma_ops(struct device *dev)
 #endif
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	int cls = cache_line_size_of_cpu();
 
@@ -58,7 +58,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 		   ARCH_DMA_MINALIGN, cls);
 
 	dev->dma_coherent = coherent;
-	if (iommu)
+	if (device_iommu_mapped(dev))
 		iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1);
 
 	xen_setup_dma_ops(dev);
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index 3c4fc97b9f394b..0f3cec663a12cd 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -138,7 +138,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 
 #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		const struct iommu_ops *iommu, bool coherent)
+		bool coherent)
 {
 	dev->dma_coherent = coherent;
 }
diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
index b76e7e192eb183..f91fa741c41211 100644
--- a/arch/riscv/mm/dma-noncoherent.c
+++ b/arch/riscv/mm/dma-noncoherent.c
@@ -135,7 +135,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
 }
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	WARN_TAINT(!coherent && riscv_cbom_block_size > ARCH_DMA_MINALIGN,
 		   TAINT_CPU_OUT_OF_SPEC,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 691d4b7686ee7e..a6891ad0ceee2c 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1636,8 +1636,7 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 	if (PTR_ERR(iommu) == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
-	arch_setup_dma_ops(dev, 0, U64_MAX,
-				iommu, attr == DEV_DMA_COHERENT);
+	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
 
 	return 0;
 }
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index ccad7bca3fd3da..fd938b6dfa7ed4 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -489,7 +489,7 @@ void hv_setup_dma_ops(struct device *dev, bool coherent)
 	 * Hyper-V does not offer a vIOMMU in the guest
 	 * VM, so pass 0/NULL for the IOMMU settings
 	 */
-	arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
+	arch_setup_dma_ops(dev, 0, 0, coherent);
 }
 EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
 
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 1ca42ad9dd159d..65c71be71a8d45 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -193,7 +193,7 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 	dev_dbg(dev, "device is%sbehind an iommu\n",
 		iommu ? " " : " not ");
 
-	arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
+	arch_setup_dma_ops(dev, dma_start, size, coherent);
 
 	if (!iommu)
 		of_dma_set_restricted_buffer(dev, np);
diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
index f2fc203fb8a1a2..2cb98a12c50348 100644
--- a/include/linux/dma-map-ops.h
+++ b/include/linux/dma-map-ops.h
@@ -426,10 +426,10 @@ bool arch_dma_unmap_sg_direct(struct device *dev, struct scatterlist *sg,
 
 #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		const struct iommu_ops *iommu, bool coherent);
+		bool coherent);
 #else
 static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
-		u64 size, const struct iommu_ops *iommu, bool coherent)
+		u64 size, bool coherent)
 {
 }
 #endif /* CONFIG_ARCH_HAS_SETUP_DMA_OPS */
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is not being used to pass ops, it is just a way to tell if an
iommu driver was probed. These days this can be detected directly via
device_iommu_mapped(). Call device_iommu_mapped() in the two places that
need to check it and remove the iommu parameter everywhere.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 arch/arc/mm/dma.c               |  2 +-
 arch/arm/mm/dma-mapping-nommu.c |  2 +-
 arch/arm/mm/dma-mapping.c       | 10 +++++-----
 arch/arm64/mm/dma-mapping.c     |  4 ++--
 arch/mips/mm/dma-noncoherent.c  |  2 +-
 arch/riscv/mm/dma-noncoherent.c |  2 +-
 drivers/acpi/scan.c             |  3 +--
 drivers/hv/hv_common.c          |  2 +-
 drivers/of/device.c             |  2 +-
 include/linux/dma-map-ops.h     |  4 ++--
 10 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index 2a7fbbb83b7056..197707bc765889 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -91,7 +91,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
  * Plug in direct dma map ops.
  */
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	/*
 	 * IOC hardware snoops all DMA traffic keeping the caches consistent
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
index cfd9c933d2f09c..b94850b579952a 100644
--- a/arch/arm/mm/dma-mapping-nommu.c
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -34,7 +34,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 }
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	if (IS_ENABLED(CONFIG_CPU_V7M)) {
 		/*
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 5409225b4abc06..6c359a3af8d9c7 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1713,7 +1713,7 @@ void arm_iommu_detach_device(struct device *dev)
 EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
 
 static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
-				    const struct iommu_ops *iommu, bool coherent)
+				    bool coherent)
 {
 	struct dma_iommu_mapping *mapping;
 
@@ -1748,7 +1748,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
 #else
 
 static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
-				    const struct iommu_ops *iommu, bool coherent)
+				    bool coherent)
 {
 }
 
@@ -1757,7 +1757,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }
 #endif	/* CONFIG_ARM_DMA_USE_IOMMU */
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	/*
 	 * Due to legacy code that sets the ->dma_coherent flag from a bus
@@ -1776,8 +1776,8 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 	if (dev->dma_ops)
 		return;
 
-	if (iommu)
-		arm_setup_iommu_dma_ops(dev, dma_base, size, iommu, coherent);
+	if (device_iommu_mapped(dev))
+		arm_setup_iommu_dma_ops(dev, dma_base, size, coherent);
 
 	xen_setup_dma_ops(dev);
 	dev->archdata.dma_ops_setup = true;
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 3cb101e8cb29ba..61886e43e3a10f 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -47,7 +47,7 @@ void arch_teardown_dma_ops(struct device *dev)
 #endif
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	int cls = cache_line_size_of_cpu();
 
@@ -58,7 +58,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 		   ARCH_DMA_MINALIGN, cls);
 
 	dev->dma_coherent = coherent;
-	if (iommu)
+	if (device_iommu_mapped(dev))
 		iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1);
 
 	xen_setup_dma_ops(dev);
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index 3c4fc97b9f394b..0f3cec663a12cd 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -138,7 +138,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 
 #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		const struct iommu_ops *iommu, bool coherent)
+		bool coherent)
 {
 	dev->dma_coherent = coherent;
 }
diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
index b76e7e192eb183..f91fa741c41211 100644
--- a/arch/riscv/mm/dma-noncoherent.c
+++ b/arch/riscv/mm/dma-noncoherent.c
@@ -135,7 +135,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
 }
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	WARN_TAINT(!coherent && riscv_cbom_block_size > ARCH_DMA_MINALIGN,
 		   TAINT_CPU_OUT_OF_SPEC,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 691d4b7686ee7e..a6891ad0ceee2c 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1636,8 +1636,7 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 	if (PTR_ERR(iommu) == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
-	arch_setup_dma_ops(dev, 0, U64_MAX,
-				iommu, attr == DEV_DMA_COHERENT);
+	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
 
 	return 0;
 }
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index ccad7bca3fd3da..fd938b6dfa7ed4 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -489,7 +489,7 @@ void hv_setup_dma_ops(struct device *dev, bool coherent)
 	 * Hyper-V does not offer a vIOMMU in the guest
 	 * VM, so pass 0/NULL for the IOMMU settings
 	 */
-	arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
+	arch_setup_dma_ops(dev, 0, 0, coherent);
 }
 EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
 
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 1ca42ad9dd159d..65c71be71a8d45 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -193,7 +193,7 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 	dev_dbg(dev, "device is%sbehind an iommu\n",
 		iommu ? " " : " not ");
 
-	arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
+	arch_setup_dma_ops(dev, dma_start, size, coherent);
 
 	if (!iommu)
 		of_dma_set_restricted_buffer(dev, np);
diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
index f2fc203fb8a1a2..2cb98a12c50348 100644
--- a/include/linux/dma-map-ops.h
+++ b/include/linux/dma-map-ops.h
@@ -426,10 +426,10 @@ bool arch_dma_unmap_sg_direct(struct device *dev, struct scatterlist *sg,
 
 #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		const struct iommu_ops *iommu, bool coherent);
+		bool coherent);
 #else
 static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
-		u64 size, const struct iommu_ops *iommu, bool coherent)
+		u64 size, bool coherent)
 {
 }
 #endif /* CONFIG_ARCH_HAS_SETUP_DMA_OPS */
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is not being used to pass ops, it is just a way to tell if an
iommu driver was probed. These days this can be detected directly via
device_iommu_mapped(). Call device_iommu_mapped() in the two places that
need to check it and remove the iommu parameter everywhere.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 arch/arc/mm/dma.c               |  2 +-
 arch/arm/mm/dma-mapping-nommu.c |  2 +-
 arch/arm/mm/dma-mapping.c       | 10 +++++-----
 arch/arm64/mm/dma-mapping.c     |  4 ++--
 arch/mips/mm/dma-noncoherent.c  |  2 +-
 arch/riscv/mm/dma-noncoherent.c |  2 +-
 drivers/acpi/scan.c             |  3 +--
 drivers/hv/hv_common.c          |  2 +-
 drivers/of/device.c             |  2 +-
 include/linux/dma-map-ops.h     |  4 ++--
 10 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index 2a7fbbb83b7056..197707bc765889 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -91,7 +91,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
  * Plug in direct dma map ops.
  */
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	/*
 	 * IOC hardware snoops all DMA traffic keeping the caches consistent
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
index cfd9c933d2f09c..b94850b579952a 100644
--- a/arch/arm/mm/dma-mapping-nommu.c
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -34,7 +34,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 }
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	if (IS_ENABLED(CONFIG_CPU_V7M)) {
 		/*
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 5409225b4abc06..6c359a3af8d9c7 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1713,7 +1713,7 @@ void arm_iommu_detach_device(struct device *dev)
 EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
 
 static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
-				    const struct iommu_ops *iommu, bool coherent)
+				    bool coherent)
 {
 	struct dma_iommu_mapping *mapping;
 
@@ -1748,7 +1748,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
 #else
 
 static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
-				    const struct iommu_ops *iommu, bool coherent)
+				    bool coherent)
 {
 }
 
@@ -1757,7 +1757,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }
 #endif	/* CONFIG_ARM_DMA_USE_IOMMU */
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	/*
 	 * Due to legacy code that sets the ->dma_coherent flag from a bus
@@ -1776,8 +1776,8 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 	if (dev->dma_ops)
 		return;
 
-	if (iommu)
-		arm_setup_iommu_dma_ops(dev, dma_base, size, iommu, coherent);
+	if (device_iommu_mapped(dev))
+		arm_setup_iommu_dma_ops(dev, dma_base, size, coherent);
 
 	xen_setup_dma_ops(dev);
 	dev->archdata.dma_ops_setup = true;
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 3cb101e8cb29ba..61886e43e3a10f 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -47,7 +47,7 @@ void arch_teardown_dma_ops(struct device *dev)
 #endif
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	int cls = cache_line_size_of_cpu();
 
@@ -58,7 +58,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 		   ARCH_DMA_MINALIGN, cls);
 
 	dev->dma_coherent = coherent;
-	if (iommu)
+	if (device_iommu_mapped(dev))
 		iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1);
 
 	xen_setup_dma_ops(dev);
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index 3c4fc97b9f394b..0f3cec663a12cd 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -138,7 +138,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 
 #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		const struct iommu_ops *iommu, bool coherent)
+		bool coherent)
 {
 	dev->dma_coherent = coherent;
 }
diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
index b76e7e192eb183..f91fa741c41211 100644
--- a/arch/riscv/mm/dma-noncoherent.c
+++ b/arch/riscv/mm/dma-noncoherent.c
@@ -135,7 +135,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
 }
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		const struct iommu_ops *iommu, bool coherent)
+			bool coherent)
 {
 	WARN_TAINT(!coherent && riscv_cbom_block_size > ARCH_DMA_MINALIGN,
 		   TAINT_CPU_OUT_OF_SPEC,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 691d4b7686ee7e..a6891ad0ceee2c 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1636,8 +1636,7 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 	if (PTR_ERR(iommu) == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
-	arch_setup_dma_ops(dev, 0, U64_MAX,
-				iommu, attr == DEV_DMA_COHERENT);
+	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
 
 	return 0;
 }
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index ccad7bca3fd3da..fd938b6dfa7ed4 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -489,7 +489,7 @@ void hv_setup_dma_ops(struct device *dev, bool coherent)
 	 * Hyper-V does not offer a vIOMMU in the guest
 	 * VM, so pass 0/NULL for the IOMMU settings
 	 */
-	arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
+	arch_setup_dma_ops(dev, 0, 0, coherent);
 }
 EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
 
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 1ca42ad9dd159d..65c71be71a8d45 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -193,7 +193,7 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 	dev_dbg(dev, "device is%sbehind an iommu\n",
 		iommu ? " " : " not ");
 
-	arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
+	arch_setup_dma_ops(dev, dma_start, size, coherent);
 
 	if (!iommu)
 		of_dma_set_restricted_buffer(dev, np);
diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
index f2fc203fb8a1a2..2cb98a12c50348 100644
--- a/include/linux/dma-map-ops.h
+++ b/include/linux/dma-map-ops.h
@@ -426,10 +426,10 @@ bool arch_dma_unmap_sg_direct(struct device *dev, struct scatterlist *sg,
 
 #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		const struct iommu_ops *iommu, bool coherent);
+		bool coherent);
 #else
 static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
-		u64 size, const struct iommu_ops *iommu, bool coherent)
+		u64 size, bool coherent)
 {
 }
 #endif /* CONFIG_ARCH_HAS_SETUP_DMA_OPS */
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:44   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Nothing needs this pointer. Return a normal error code with the usual
IOMMU semantic that ENODEV means 'there is no IOMMU driver'.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
 drivers/of/device.c      | 22 +++++++++++++++-------
 include/linux/of_iommu.h | 13 ++++++-------
 3 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 157b286e36bf3a..e2fa29c16dd758 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
 		      of_iommu_configure_dev(master_np, dev);
 }
 
-const struct iommu_ops *of_iommu_configure(struct device *dev,
-					   struct device_node *master_np,
-					   const u32 *id)
+/*
+ * Returns:
+ *  0 on success, an iommu was configured
+ *  -ENODEV if the device does not have any IOMMU
+ *  -EPROBEDEFER if probing should be tried again
+ *  -errno fatal errors
+ */
+int of_iommu_configure(struct device *dev, struct device_node *master_np,
+		       const u32 *id)
 {
 	const struct iommu_ops *ops = NULL;
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	int err = NO_IOMMU;
 
 	if (!master_np)
-		return NULL;
+		return -ENODEV;
 
 	if (fwspec) {
 		if (fwspec->ops)
-			return fwspec->ops;
+			return 0;
 
 		/* In the deferred case, start again from scratch */
 		iommu_fwspec_free(dev);
@@ -163,14 +169,15 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
 		err = iommu_probe_device(dev);
 
 	/* Ignore all other errors apart from EPROBE_DEFER */
-	if (err == -EPROBE_DEFER) {
-		ops = ERR_PTR(err);
-	} else if (err < 0) {
+	if (err < 0) {
+		if (err == -EPROBE_DEFER)
+			return err;
 		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		ops = NULL;
+		return -ENODEV;
 	}
-
-	return ops;
+	if (!ops)
+		return -ENODEV;
+	return 0;
 }
 
 static enum iommu_resv_type __maybe_unused
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 65c71be71a8d45..873d933e8e6d1d 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -93,12 +93,12 @@ of_dma_set_restricted_buffer(struct device *dev, struct device_node *np)
 int of_dma_configure_id(struct device *dev, struct device_node *np,
 			bool force_dma, const u32 *id)
 {
-	const struct iommu_ops *iommu;
 	const struct bus_dma_region *map = NULL;
 	struct device_node *bus_np;
 	u64 dma_start = 0;
 	u64 mask, end, size = 0;
 	bool coherent;
+	int iommu_ret;
 	int ret;
 
 	if (np == dev->of_node)
@@ -181,21 +181,29 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 	dev_dbg(dev, "device is%sdma coherent\n",
 		coherent ? " " : " not ");
 
-	iommu = of_iommu_configure(dev, np, id);
-	if (PTR_ERR(iommu) == -EPROBE_DEFER) {
+	iommu_ret = of_iommu_configure(dev, np, id);
+	if (iommu_ret == -EPROBE_DEFER) {
 		/* Don't touch range map if it wasn't set from a valid dma-ranges */
 		if (!ret)
 			dev->dma_range_map = NULL;
 		kfree(map);
 		return -EPROBE_DEFER;
-	}
+	} else if (iommu_ret == -ENODEV) {
+		dev_dbg(dev, "device is not behind an iommu\n");
+	} else if (iommu_ret) {
+		dev_err(dev, "iommu configuration for device failed with %pe\n",
+			ERR_PTR(iommu_ret));
 
-	dev_dbg(dev, "device is%sbehind an iommu\n",
-		iommu ? " " : " not ");
+		/*
+		 * Historically this routine doesn't fail driver probing
+		 * due to errors in of_iommu_configure()
+		 */
+	} else
+		dev_dbg(dev, "device is behind an iommu\n");
 
 	arch_setup_dma_ops(dev, dma_start, size, coherent);
 
-	if (!iommu)
+	if (iommu_ret)
 		of_dma_set_restricted_buffer(dev, np);
 
 	return 0;
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index 9a5e6b410dd2fb..e61cbbe12dac6f 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -8,20 +8,19 @@ struct iommu_ops;
 
 #ifdef CONFIG_OF_IOMMU
 
-extern const struct iommu_ops *of_iommu_configure(struct device *dev,
-					struct device_node *master_np,
-					const u32 *id);
+extern int of_iommu_configure(struct device *dev, struct device_node *master_np,
+			      const u32 *id);
 
 extern void of_iommu_get_resv_regions(struct device *dev,
 				      struct list_head *list);
 
 #else
 
-static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
-					 struct device_node *master_np,
-					 const u32 *id)
+static inline int of_iommu_configure(struct device *dev,
+				     struct device_node *master_np,
+				     const u32 *id)
 {
-	return NULL;
+	return -ENODEV;
 }
 
 static inline void of_iommu_get_resv_regions(struct device *dev,
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Nothing needs this pointer. Return a normal error code with the usual
IOMMU semantic that ENODEV means 'there is no IOMMU driver'.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
 drivers/of/device.c      | 22 +++++++++++++++-------
 include/linux/of_iommu.h | 13 ++++++-------
 3 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 157b286e36bf3a..e2fa29c16dd758 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
 		      of_iommu_configure_dev(master_np, dev);
 }
 
-const struct iommu_ops *of_iommu_configure(struct device *dev,
-					   struct device_node *master_np,
-					   const u32 *id)
+/*
+ * Returns:
+ *  0 on success, an iommu was configured
+ *  -ENODEV if the device does not have any IOMMU
+ *  -EPROBEDEFER if probing should be tried again
+ *  -errno fatal errors
+ */
+int of_iommu_configure(struct device *dev, struct device_node *master_np,
+		       const u32 *id)
 {
 	const struct iommu_ops *ops = NULL;
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	int err = NO_IOMMU;
 
 	if (!master_np)
-		return NULL;
+		return -ENODEV;
 
 	if (fwspec) {
 		if (fwspec->ops)
-			return fwspec->ops;
+			return 0;
 
 		/* In the deferred case, start again from scratch */
 		iommu_fwspec_free(dev);
@@ -163,14 +169,15 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
 		err = iommu_probe_device(dev);
 
 	/* Ignore all other errors apart from EPROBE_DEFER */
-	if (err == -EPROBE_DEFER) {
-		ops = ERR_PTR(err);
-	} else if (err < 0) {
+	if (err < 0) {
+		if (err == -EPROBE_DEFER)
+			return err;
 		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		ops = NULL;
+		return -ENODEV;
 	}
-
-	return ops;
+	if (!ops)
+		return -ENODEV;
+	return 0;
 }
 
 static enum iommu_resv_type __maybe_unused
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 65c71be71a8d45..873d933e8e6d1d 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -93,12 +93,12 @@ of_dma_set_restricted_buffer(struct device *dev, struct device_node *np)
 int of_dma_configure_id(struct device *dev, struct device_node *np,
 			bool force_dma, const u32 *id)
 {
-	const struct iommu_ops *iommu;
 	const struct bus_dma_region *map = NULL;
 	struct device_node *bus_np;
 	u64 dma_start = 0;
 	u64 mask, end, size = 0;
 	bool coherent;
+	int iommu_ret;
 	int ret;
 
 	if (np == dev->of_node)
@@ -181,21 +181,29 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 	dev_dbg(dev, "device is%sdma coherent\n",
 		coherent ? " " : " not ");
 
-	iommu = of_iommu_configure(dev, np, id);
-	if (PTR_ERR(iommu) == -EPROBE_DEFER) {
+	iommu_ret = of_iommu_configure(dev, np, id);
+	if (iommu_ret == -EPROBE_DEFER) {
 		/* Don't touch range map if it wasn't set from a valid dma-ranges */
 		if (!ret)
 			dev->dma_range_map = NULL;
 		kfree(map);
 		return -EPROBE_DEFER;
-	}
+	} else if (iommu_ret == -ENODEV) {
+		dev_dbg(dev, "device is not behind an iommu\n");
+	} else if (iommu_ret) {
+		dev_err(dev, "iommu configuration for device failed with %pe\n",
+			ERR_PTR(iommu_ret));
 
-	dev_dbg(dev, "device is%sbehind an iommu\n",
-		iommu ? " " : " not ");
+		/*
+		 * Historically this routine doesn't fail driver probing
+		 * due to errors in of_iommu_configure()
+		 */
+	} else
+		dev_dbg(dev, "device is behind an iommu\n");
 
 	arch_setup_dma_ops(dev, dma_start, size, coherent);
 
-	if (!iommu)
+	if (iommu_ret)
 		of_dma_set_restricted_buffer(dev, np);
 
 	return 0;
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index 9a5e6b410dd2fb..e61cbbe12dac6f 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -8,20 +8,19 @@ struct iommu_ops;
 
 #ifdef CONFIG_OF_IOMMU
 
-extern const struct iommu_ops *of_iommu_configure(struct device *dev,
-					struct device_node *master_np,
-					const u32 *id);
+extern int of_iommu_configure(struct device *dev, struct device_node *master_np,
+			      const u32 *id);
 
 extern void of_iommu_get_resv_regions(struct device *dev,
 				      struct list_head *list);
 
 #else
 
-static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
-					 struct device_node *master_np,
-					 const u32 *id)
+static inline int of_iommu_configure(struct device *dev,
+				     struct device_node *master_np,
+				     const u32 *id)
 {
-	return NULL;
+	return -ENODEV;
 }
 
 static inline void of_iommu_get_resv_regions(struct device *dev,
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Nothing needs this pointer. Return a normal error code with the usual
IOMMU semantic that ENODEV means 'there is no IOMMU driver'.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
 drivers/of/device.c      | 22 +++++++++++++++-------
 include/linux/of_iommu.h | 13 ++++++-------
 3 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 157b286e36bf3a..e2fa29c16dd758 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
 		      of_iommu_configure_dev(master_np, dev);
 }
 
-const struct iommu_ops *of_iommu_configure(struct device *dev,
-					   struct device_node *master_np,
-					   const u32 *id)
+/*
+ * Returns:
+ *  0 on success, an iommu was configured
+ *  -ENODEV if the device does not have any IOMMU
+ *  -EPROBEDEFER if probing should be tried again
+ *  -errno fatal errors
+ */
+int of_iommu_configure(struct device *dev, struct device_node *master_np,
+		       const u32 *id)
 {
 	const struct iommu_ops *ops = NULL;
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	int err = NO_IOMMU;
 
 	if (!master_np)
-		return NULL;
+		return -ENODEV;
 
 	if (fwspec) {
 		if (fwspec->ops)
-			return fwspec->ops;
+			return 0;
 
 		/* In the deferred case, start again from scratch */
 		iommu_fwspec_free(dev);
@@ -163,14 +169,15 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
 		err = iommu_probe_device(dev);
 
 	/* Ignore all other errors apart from EPROBE_DEFER */
-	if (err == -EPROBE_DEFER) {
-		ops = ERR_PTR(err);
-	} else if (err < 0) {
+	if (err < 0) {
+		if (err == -EPROBE_DEFER)
+			return err;
 		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		ops = NULL;
+		return -ENODEV;
 	}
-
-	return ops;
+	if (!ops)
+		return -ENODEV;
+	return 0;
 }
 
 static enum iommu_resv_type __maybe_unused
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 65c71be71a8d45..873d933e8e6d1d 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -93,12 +93,12 @@ of_dma_set_restricted_buffer(struct device *dev, struct device_node *np)
 int of_dma_configure_id(struct device *dev, struct device_node *np,
 			bool force_dma, const u32 *id)
 {
-	const struct iommu_ops *iommu;
 	const struct bus_dma_region *map = NULL;
 	struct device_node *bus_np;
 	u64 dma_start = 0;
 	u64 mask, end, size = 0;
 	bool coherent;
+	int iommu_ret;
 	int ret;
 
 	if (np == dev->of_node)
@@ -181,21 +181,29 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 	dev_dbg(dev, "device is%sdma coherent\n",
 		coherent ? " " : " not ");
 
-	iommu = of_iommu_configure(dev, np, id);
-	if (PTR_ERR(iommu) == -EPROBE_DEFER) {
+	iommu_ret = of_iommu_configure(dev, np, id);
+	if (iommu_ret == -EPROBE_DEFER) {
 		/* Don't touch range map if it wasn't set from a valid dma-ranges */
 		if (!ret)
 			dev->dma_range_map = NULL;
 		kfree(map);
 		return -EPROBE_DEFER;
-	}
+	} else if (iommu_ret == -ENODEV) {
+		dev_dbg(dev, "device is not behind an iommu\n");
+	} else if (iommu_ret) {
+		dev_err(dev, "iommu configuration for device failed with %pe\n",
+			ERR_PTR(iommu_ret));
 
-	dev_dbg(dev, "device is%sbehind an iommu\n",
-		iommu ? " " : " not ");
+		/*
+		 * Historically this routine doesn't fail driver probing
+		 * due to errors in of_iommu_configure()
+		 */
+	} else
+		dev_dbg(dev, "device is behind an iommu\n");
 
 	arch_setup_dma_ops(dev, dma_start, size, coherent);
 
-	if (!iommu)
+	if (iommu_ret)
 		of_dma_set_restricted_buffer(dev, np);
 
 	return 0;
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index 9a5e6b410dd2fb..e61cbbe12dac6f 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -8,20 +8,19 @@ struct iommu_ops;
 
 #ifdef CONFIG_OF_IOMMU
 
-extern const struct iommu_ops *of_iommu_configure(struct device *dev,
-					struct device_node *master_np,
-					const u32 *id);
+extern int of_iommu_configure(struct device *dev, struct device_node *master_np,
+			      const u32 *id);
 
 extern void of_iommu_get_resv_regions(struct device *dev,
 				      struct list_head *list);
 
 #else
 
-static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
-					 struct device_node *master_np,
-					 const u32 *id)
+static inline int of_iommu_configure(struct device *dev,
+				     struct device_node *master_np,
+				     const u32 *id)
 {
-	return NULL;
+	return -ENODEV;
 }
 
 static inline void of_iommu_get_resv_regions(struct device *dev,
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Nothing needs this pointer. Return a normal error code with the usual
IOMMU semantic that ENODEV means 'there is no IOMMU driver'.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
 drivers/of/device.c      | 22 +++++++++++++++-------
 include/linux/of_iommu.h | 13 ++++++-------
 3 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 157b286e36bf3a..e2fa29c16dd758 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
 		      of_iommu_configure_dev(master_np, dev);
 }
 
-const struct iommu_ops *of_iommu_configure(struct device *dev,
-					   struct device_node *master_np,
-					   const u32 *id)
+/*
+ * Returns:
+ *  0 on success, an iommu was configured
+ *  -ENODEV if the device does not have any IOMMU
+ *  -EPROBEDEFER if probing should be tried again
+ *  -errno fatal errors
+ */
+int of_iommu_configure(struct device *dev, struct device_node *master_np,
+		       const u32 *id)
 {
 	const struct iommu_ops *ops = NULL;
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	int err = NO_IOMMU;
 
 	if (!master_np)
-		return NULL;
+		return -ENODEV;
 
 	if (fwspec) {
 		if (fwspec->ops)
-			return fwspec->ops;
+			return 0;
 
 		/* In the deferred case, start again from scratch */
 		iommu_fwspec_free(dev);
@@ -163,14 +169,15 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
 		err = iommu_probe_device(dev);
 
 	/* Ignore all other errors apart from EPROBE_DEFER */
-	if (err == -EPROBE_DEFER) {
-		ops = ERR_PTR(err);
-	} else if (err < 0) {
+	if (err < 0) {
+		if (err == -EPROBE_DEFER)
+			return err;
 		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		ops = NULL;
+		return -ENODEV;
 	}
-
-	return ops;
+	if (!ops)
+		return -ENODEV;
+	return 0;
 }
 
 static enum iommu_resv_type __maybe_unused
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 65c71be71a8d45..873d933e8e6d1d 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -93,12 +93,12 @@ of_dma_set_restricted_buffer(struct device *dev, struct device_node *np)
 int of_dma_configure_id(struct device *dev, struct device_node *np,
 			bool force_dma, const u32 *id)
 {
-	const struct iommu_ops *iommu;
 	const struct bus_dma_region *map = NULL;
 	struct device_node *bus_np;
 	u64 dma_start = 0;
 	u64 mask, end, size = 0;
 	bool coherent;
+	int iommu_ret;
 	int ret;
 
 	if (np == dev->of_node)
@@ -181,21 +181,29 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 	dev_dbg(dev, "device is%sdma coherent\n",
 		coherent ? " " : " not ");
 
-	iommu = of_iommu_configure(dev, np, id);
-	if (PTR_ERR(iommu) == -EPROBE_DEFER) {
+	iommu_ret = of_iommu_configure(dev, np, id);
+	if (iommu_ret == -EPROBE_DEFER) {
 		/* Don't touch range map if it wasn't set from a valid dma-ranges */
 		if (!ret)
 			dev->dma_range_map = NULL;
 		kfree(map);
 		return -EPROBE_DEFER;
-	}
+	} else if (iommu_ret == -ENODEV) {
+		dev_dbg(dev, "device is not behind an iommu\n");
+	} else if (iommu_ret) {
+		dev_err(dev, "iommu configuration for device failed with %pe\n",
+			ERR_PTR(iommu_ret));
 
-	dev_dbg(dev, "device is%sbehind an iommu\n",
-		iommu ? " " : " not ");
+		/*
+		 * Historically this routine doesn't fail driver probing
+		 * due to errors in of_iommu_configure()
+		 */
+	} else
+		dev_dbg(dev, "device is behind an iommu\n");
 
 	arch_setup_dma_ops(dev, dma_start, size, coherent);
 
-	if (!iommu)
+	if (iommu_ret)
 		of_dma_set_restricted_buffer(dev, np);
 
 	return 0;
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index 9a5e6b410dd2fb..e61cbbe12dac6f 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -8,20 +8,19 @@ struct iommu_ops;
 
 #ifdef CONFIG_OF_IOMMU
 
-extern const struct iommu_ops *of_iommu_configure(struct device *dev,
-					struct device_node *master_np,
-					const u32 *id);
+extern int of_iommu_configure(struct device *dev, struct device_node *master_np,
+			      const u32 *id);
 
 extern void of_iommu_get_resv_regions(struct device *dev,
 				      struct list_head *list);
 
 #else
 
-static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
-					 struct device_node *master_np,
-					 const u32 *id)
+static inline int of_iommu_configure(struct device *dev,
+				     struct device_node *master_np,
+				     const u32 *id)
 {
-	return NULL;
+	return -ENODEV;
 }
 
 static inline void of_iommu_get_resv_regions(struct device *dev,
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Nothing needs this pointer. Return a normal error code with the usual
IOMMU semantic that ENODEV means 'there is no IOMMU driver'.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
 drivers/of/device.c      | 22 +++++++++++++++-------
 include/linux/of_iommu.h | 13 ++++++-------
 3 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 157b286e36bf3a..e2fa29c16dd758 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
 		      of_iommu_configure_dev(master_np, dev);
 }
 
-const struct iommu_ops *of_iommu_configure(struct device *dev,
-					   struct device_node *master_np,
-					   const u32 *id)
+/*
+ * Returns:
+ *  0 on success, an iommu was configured
+ *  -ENODEV if the device does not have any IOMMU
+ *  -EPROBEDEFER if probing should be tried again
+ *  -errno fatal errors
+ */
+int of_iommu_configure(struct device *dev, struct device_node *master_np,
+		       const u32 *id)
 {
 	const struct iommu_ops *ops = NULL;
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	int err = NO_IOMMU;
 
 	if (!master_np)
-		return NULL;
+		return -ENODEV;
 
 	if (fwspec) {
 		if (fwspec->ops)
-			return fwspec->ops;
+			return 0;
 
 		/* In the deferred case, start again from scratch */
 		iommu_fwspec_free(dev);
@@ -163,14 +169,15 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
 		err = iommu_probe_device(dev);
 
 	/* Ignore all other errors apart from EPROBE_DEFER */
-	if (err == -EPROBE_DEFER) {
-		ops = ERR_PTR(err);
-	} else if (err < 0) {
+	if (err < 0) {
+		if (err == -EPROBE_DEFER)
+			return err;
 		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		ops = NULL;
+		return -ENODEV;
 	}
-
-	return ops;
+	if (!ops)
+		return -ENODEV;
+	return 0;
 }
 
 static enum iommu_resv_type __maybe_unused
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 65c71be71a8d45..873d933e8e6d1d 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -93,12 +93,12 @@ of_dma_set_restricted_buffer(struct device *dev, struct device_node *np)
 int of_dma_configure_id(struct device *dev, struct device_node *np,
 			bool force_dma, const u32 *id)
 {
-	const struct iommu_ops *iommu;
 	const struct bus_dma_region *map = NULL;
 	struct device_node *bus_np;
 	u64 dma_start = 0;
 	u64 mask, end, size = 0;
 	bool coherent;
+	int iommu_ret;
 	int ret;
 
 	if (np == dev->of_node)
@@ -181,21 +181,29 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 	dev_dbg(dev, "device is%sdma coherent\n",
 		coherent ? " " : " not ");
 
-	iommu = of_iommu_configure(dev, np, id);
-	if (PTR_ERR(iommu) == -EPROBE_DEFER) {
+	iommu_ret = of_iommu_configure(dev, np, id);
+	if (iommu_ret == -EPROBE_DEFER) {
 		/* Don't touch range map if it wasn't set from a valid dma-ranges */
 		if (!ret)
 			dev->dma_range_map = NULL;
 		kfree(map);
 		return -EPROBE_DEFER;
-	}
+	} else if (iommu_ret == -ENODEV) {
+		dev_dbg(dev, "device is not behind an iommu\n");
+	} else if (iommu_ret) {
+		dev_err(dev, "iommu configuration for device failed with %pe\n",
+			ERR_PTR(iommu_ret));
 
-	dev_dbg(dev, "device is%sbehind an iommu\n",
-		iommu ? " " : " not ");
+		/*
+		 * Historically this routine doesn't fail driver probing
+		 * due to errors in of_iommu_configure()
+		 */
+	} else
+		dev_dbg(dev, "device is behind an iommu\n");
 
 	arch_setup_dma_ops(dev, dma_start, size, coherent);
 
-	if (!iommu)
+	if (iommu_ret)
 		of_dma_set_restricted_buffer(dev, np);
 
 	return 0;
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index 9a5e6b410dd2fb..e61cbbe12dac6f 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -8,20 +8,19 @@ struct iommu_ops;
 
 #ifdef CONFIG_OF_IOMMU
 
-extern const struct iommu_ops *of_iommu_configure(struct device *dev,
-					struct device_node *master_np,
-					const u32 *id);
+extern int of_iommu_configure(struct device *dev, struct device_node *master_np,
+			      const u32 *id);
 
 extern void of_iommu_get_resv_regions(struct device *dev,
 				      struct list_head *list);
 
 #else
 
-static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
-					 struct device_node *master_np,
-					 const u32 *id)
+static inline int of_iommu_configure(struct device *dev,
+				     struct device_node *master_np,
+				     const u32 *id)
 {
-	return NULL;
+	return -ENODEV;
 }
 
 static inline void of_iommu_get_resv_regions(struct device *dev,
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:44   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Instead of returning 1 and trying to handle positive error codes just
stick to the convention of returning -ENODEV. Remove references to ops
from of_iommu_configure(), a NULL ops will already generate an error code.

There is no reason to check dev->bus, if err=0 at this point then the
called configure functions thought there was an iommu and we should try to
probe it. Remove it.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/of_iommu.c | 42 +++++++++++++---------------------------
 1 file changed, 13 insertions(+), 29 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index e2fa29c16dd758..4f77495a2543ea 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -17,7 +17,7 @@
 #include <linux/slab.h>
 #include <linux/fsl/mc.h>
 
-#define NO_IOMMU	1
+#define NO_IOMMU	-ENODEV
 
 static int of_iommu_xlate(struct device *dev,
 			  struct of_phandle_args *iommu_spec)
@@ -117,9 +117,8 @@ static int of_iommu_configure_device(struct device_node *master_np,
 int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		       const u32 *id)
 {
-	const struct iommu_ops *ops = NULL;
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-	int err = NO_IOMMU;
+	int err;
 
 	if (!master_np)
 		return -ENODEV;
@@ -150,34 +149,19 @@ int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		err = of_iommu_configure_device(master_np, dev, id);
 	}
 
-	/*
-	 * Two success conditions can be represented by non-negative err here:
-	 * >0 : there is no IOMMU, or one was unavailable for non-fatal reasons
-	 *  0 : we found an IOMMU, and dev->fwspec is initialised appropriately
-	 * <0 : any actual error
-	 */
-	if (!err) {
-		/* The fwspec pointer changed, read it again */
-		fwspec = dev_iommu_fwspec_get(dev);
-		ops    = fwspec->ops;
-	}
-	/*
-	 * If we have reason to believe the IOMMU driver missed the initial
-	 * probe for dev, replay it to get things in order.
-	 */
-	if (!err && dev->bus)
-		err = iommu_probe_device(dev);
+	if (err == -ENODEV || err == -EPROBE_DEFER)
+		return err;
+	if (err)
+		goto err_log;
 
-	/* Ignore all other errors apart from EPROBE_DEFER */
-	if (err < 0) {
-		if (err == -EPROBE_DEFER)
-			return err;
-		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		return -ENODEV;
-	}
-	if (!ops)
-		return -ENODEV;
+	err = iommu_probe_device(dev);
+	if (err)
+		goto err_log;
 	return 0;
+
+err_log:
+	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+	return err;
 }
 
 static enum iommu_resv_type __maybe_unused
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Instead of returning 1 and trying to handle positive error codes just
stick to the convention of returning -ENODEV. Remove references to ops
from of_iommu_configure(), a NULL ops will already generate an error code.

There is no reason to check dev->bus, if err=0 at this point then the
called configure functions thought there was an iommu and we should try to
probe it. Remove it.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/of_iommu.c | 42 +++++++++++++---------------------------
 1 file changed, 13 insertions(+), 29 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index e2fa29c16dd758..4f77495a2543ea 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -17,7 +17,7 @@
 #include <linux/slab.h>
 #include <linux/fsl/mc.h>
 
-#define NO_IOMMU	1
+#define NO_IOMMU	-ENODEV
 
 static int of_iommu_xlate(struct device *dev,
 			  struct of_phandle_args *iommu_spec)
@@ -117,9 +117,8 @@ static int of_iommu_configure_device(struct device_node *master_np,
 int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		       const u32 *id)
 {
-	const struct iommu_ops *ops = NULL;
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-	int err = NO_IOMMU;
+	int err;
 
 	if (!master_np)
 		return -ENODEV;
@@ -150,34 +149,19 @@ int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		err = of_iommu_configure_device(master_np, dev, id);
 	}
 
-	/*
-	 * Two success conditions can be represented by non-negative err here:
-	 * >0 : there is no IOMMU, or one was unavailable for non-fatal reasons
-	 *  0 : we found an IOMMU, and dev->fwspec is initialised appropriately
-	 * <0 : any actual error
-	 */
-	if (!err) {
-		/* The fwspec pointer changed, read it again */
-		fwspec = dev_iommu_fwspec_get(dev);
-		ops    = fwspec->ops;
-	}
-	/*
-	 * If we have reason to believe the IOMMU driver missed the initial
-	 * probe for dev, replay it to get things in order.
-	 */
-	if (!err && dev->bus)
-		err = iommu_probe_device(dev);
+	if (err == -ENODEV || err == -EPROBE_DEFER)
+		return err;
+	if (err)
+		goto err_log;
 
-	/* Ignore all other errors apart from EPROBE_DEFER */
-	if (err < 0) {
-		if (err == -EPROBE_DEFER)
-			return err;
-		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		return -ENODEV;
-	}
-	if (!ops)
-		return -ENODEV;
+	err = iommu_probe_device(dev);
+	if (err)
+		goto err_log;
 	return 0;
+
+err_log:
+	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+	return err;
 }
 
 static enum iommu_resv_type __maybe_unused
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Instead of returning 1 and trying to handle positive error codes just
stick to the convention of returning -ENODEV. Remove references to ops
from of_iommu_configure(), a NULL ops will already generate an error code.

There is no reason to check dev->bus, if err=0 at this point then the
called configure functions thought there was an iommu and we should try to
probe it. Remove it.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/of_iommu.c | 42 +++++++++++++---------------------------
 1 file changed, 13 insertions(+), 29 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index e2fa29c16dd758..4f77495a2543ea 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -17,7 +17,7 @@
 #include <linux/slab.h>
 #include <linux/fsl/mc.h>
 
-#define NO_IOMMU	1
+#define NO_IOMMU	-ENODEV
 
 static int of_iommu_xlate(struct device *dev,
 			  struct of_phandle_args *iommu_spec)
@@ -117,9 +117,8 @@ static int of_iommu_configure_device(struct device_node *master_np,
 int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		       const u32 *id)
 {
-	const struct iommu_ops *ops = NULL;
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-	int err = NO_IOMMU;
+	int err;
 
 	if (!master_np)
 		return -ENODEV;
@@ -150,34 +149,19 @@ int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		err = of_iommu_configure_device(master_np, dev, id);
 	}
 
-	/*
-	 * Two success conditions can be represented by non-negative err here:
-	 * >0 : there is no IOMMU, or one was unavailable for non-fatal reasons
-	 *  0 : we found an IOMMU, and dev->fwspec is initialised appropriately
-	 * <0 : any actual error
-	 */
-	if (!err) {
-		/* The fwspec pointer changed, read it again */
-		fwspec = dev_iommu_fwspec_get(dev);
-		ops    = fwspec->ops;
-	}
-	/*
-	 * If we have reason to believe the IOMMU driver missed the initial
-	 * probe for dev, replay it to get things in order.
-	 */
-	if (!err && dev->bus)
-		err = iommu_probe_device(dev);
+	if (err == -ENODEV || err == -EPROBE_DEFER)
+		return err;
+	if (err)
+		goto err_log;
 
-	/* Ignore all other errors apart from EPROBE_DEFER */
-	if (err < 0) {
-		if (err == -EPROBE_DEFER)
-			return err;
-		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		return -ENODEV;
-	}
-	if (!ops)
-		return -ENODEV;
+	err = iommu_probe_device(dev);
+	if (err)
+		goto err_log;
 	return 0;
+
+err_log:
+	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+	return err;
 }
 
 static enum iommu_resv_type __maybe_unused
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Instead of returning 1 and trying to handle positive error codes just
stick to the convention of returning -ENODEV. Remove references to ops
from of_iommu_configure(), a NULL ops will already generate an error code.

There is no reason to check dev->bus, if err=0 at this point then the
called configure functions thought there was an iommu and we should try to
probe it. Remove it.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/of_iommu.c | 42 +++++++++++++---------------------------
 1 file changed, 13 insertions(+), 29 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index e2fa29c16dd758..4f77495a2543ea 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -17,7 +17,7 @@
 #include <linux/slab.h>
 #include <linux/fsl/mc.h>
 
-#define NO_IOMMU	1
+#define NO_IOMMU	-ENODEV
 
 static int of_iommu_xlate(struct device *dev,
 			  struct of_phandle_args *iommu_spec)
@@ -117,9 +117,8 @@ static int of_iommu_configure_device(struct device_node *master_np,
 int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		       const u32 *id)
 {
-	const struct iommu_ops *ops = NULL;
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-	int err = NO_IOMMU;
+	int err;
 
 	if (!master_np)
 		return -ENODEV;
@@ -150,34 +149,19 @@ int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		err = of_iommu_configure_device(master_np, dev, id);
 	}
 
-	/*
-	 * Two success conditions can be represented by non-negative err here:
-	 * >0 : there is no IOMMU, or one was unavailable for non-fatal reasons
-	 *  0 : we found an IOMMU, and dev->fwspec is initialised appropriately
-	 * <0 : any actual error
-	 */
-	if (!err) {
-		/* The fwspec pointer changed, read it again */
-		fwspec = dev_iommu_fwspec_get(dev);
-		ops    = fwspec->ops;
-	}
-	/*
-	 * If we have reason to believe the IOMMU driver missed the initial
-	 * probe for dev, replay it to get things in order.
-	 */
-	if (!err && dev->bus)
-		err = iommu_probe_device(dev);
+	if (err == -ENODEV || err == -EPROBE_DEFER)
+		return err;
+	if (err)
+		goto err_log;
 
-	/* Ignore all other errors apart from EPROBE_DEFER */
-	if (err < 0) {
-		if (err == -EPROBE_DEFER)
-			return err;
-		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		return -ENODEV;
-	}
-	if (!ops)
-		return -ENODEV;
+	err = iommu_probe_device(dev);
+	if (err)
+		goto err_log;
 	return 0;
+
+err_log:
+	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+	return err;
 }
 
 static enum iommu_resv_type __maybe_unused
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Instead of returning 1 and trying to handle positive error codes just
stick to the convention of returning -ENODEV. Remove references to ops
from of_iommu_configure(), a NULL ops will already generate an error code.

There is no reason to check dev->bus, if err=0 at this point then the
called configure functions thought there was an iommu and we should try to
probe it. Remove it.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/of_iommu.c | 42 +++++++++++++---------------------------
 1 file changed, 13 insertions(+), 29 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index e2fa29c16dd758..4f77495a2543ea 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -17,7 +17,7 @@
 #include <linux/slab.h>
 #include <linux/fsl/mc.h>
 
-#define NO_IOMMU	1
+#define NO_IOMMU	-ENODEV
 
 static int of_iommu_xlate(struct device *dev,
 			  struct of_phandle_args *iommu_spec)
@@ -117,9 +117,8 @@ static int of_iommu_configure_device(struct device_node *master_np,
 int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		       const u32 *id)
 {
-	const struct iommu_ops *ops = NULL;
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-	int err = NO_IOMMU;
+	int err;
 
 	if (!master_np)
 		return -ENODEV;
@@ -150,34 +149,19 @@ int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		err = of_iommu_configure_device(master_np, dev, id);
 	}
 
-	/*
-	 * Two success conditions can be represented by non-negative err here:
-	 * >0 : there is no IOMMU, or one was unavailable for non-fatal reasons
-	 *  0 : we found an IOMMU, and dev->fwspec is initialised appropriately
-	 * <0 : any actual error
-	 */
-	if (!err) {
-		/* The fwspec pointer changed, read it again */
-		fwspec = dev_iommu_fwspec_get(dev);
-		ops    = fwspec->ops;
-	}
-	/*
-	 * If we have reason to believe the IOMMU driver missed the initial
-	 * probe for dev, replay it to get things in order.
-	 */
-	if (!err && dev->bus)
-		err = iommu_probe_device(dev);
+	if (err == -ENODEV || err == -EPROBE_DEFER)
+		return err;
+	if (err)
+		goto err_log;
 
-	/* Ignore all other errors apart from EPROBE_DEFER */
-	if (err < 0) {
-		if (err == -EPROBE_DEFER)
-			return err;
-		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		return -ENODEV;
-	}
-	if (!ops)
-		return -ENODEV;
+	err = iommu_probe_device(dev);
+	if (err)
+		goto err_log;
 	return 0;
+
+err_log:
+	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+	return err;
 }
 
 static enum iommu_resv_type __maybe_unused
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:44   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Nothing needs this pointer. Return a normal error code with the usual
IOMMU semantic that ENODEV means 'there is no IOMMU driver'.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/acpi/scan.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index a6891ad0ceee2c..fbabde001a23a2 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1562,8 +1562,7 @@ static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
 	return fwspec ? fwspec->ops : NULL;
 }
 
-static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
-						       const u32 *id_in)
+static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 {
 	int err;
 	const struct iommu_ops *ops;
@@ -1574,7 +1573,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
 	 */
 	ops = acpi_iommu_fwspec_ops(dev);
 	if (ops)
-		return ops;
+		return 0;
 
 	err = iort_iommu_configure_id(dev, id_in);
 	if (err && err != -EPROBE_DEFER)
@@ -1589,12 +1588,14 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
 
 	/* Ignore all other errors apart from EPROBE_DEFER */
 	if (err == -EPROBE_DEFER) {
-		return ERR_PTR(err);
+		return err;
 	} else if (err) {
 		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		return NULL;
+		return -ENODEV;
 	}
-	return acpi_iommu_fwspec_ops(dev);
+	if (!acpi_iommu_fwspec_ops(dev))
+		return -ENODEV;
+	return 0;
 }
 
 #else /* !CONFIG_IOMMU_API */
@@ -1623,7 +1624,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
 int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 			  const u32 *input_id)
 {
-	const struct iommu_ops *iommu;
+	int ret;
 
 	if (attr == DEV_DMA_NOT_SUPPORTED) {
 		set_dma_ops(dev, &dma_dummy_ops);
@@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 
 	acpi_arch_dma_setup(dev);
 
-	iommu = acpi_iommu_configure_id(dev, input_id);
-	if (PTR_ERR(iommu) == -EPROBE_DEFER)
+	ret = acpi_iommu_configure_id(dev, input_id);
+	if (ret == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
+	/*
+	 * Historically this routine doesn't fail driver probing due to errors
+	 * in acpi_iommu_configure()
+	 */
+
 	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
 
 	return 0;
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Nothing needs this pointer. Return a normal error code with the usual
IOMMU semantic that ENODEV means 'there is no IOMMU driver'.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/acpi/scan.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index a6891ad0ceee2c..fbabde001a23a2 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1562,8 +1562,7 @@ static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
 	return fwspec ? fwspec->ops : NULL;
 }
 
-static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
-						       const u32 *id_in)
+static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 {
 	int err;
 	const struct iommu_ops *ops;
@@ -1574,7 +1573,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
 	 */
 	ops = acpi_iommu_fwspec_ops(dev);
 	if (ops)
-		return ops;
+		return 0;
 
 	err = iort_iommu_configure_id(dev, id_in);
 	if (err && err != -EPROBE_DEFER)
@@ -1589,12 +1588,14 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
 
 	/* Ignore all other errors apart from EPROBE_DEFER */
 	if (err == -EPROBE_DEFER) {
-		return ERR_PTR(err);
+		return err;
 	} else if (err) {
 		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		return NULL;
+		return -ENODEV;
 	}
-	return acpi_iommu_fwspec_ops(dev);
+	if (!acpi_iommu_fwspec_ops(dev))
+		return -ENODEV;
+	return 0;
 }
 
 #else /* !CONFIG_IOMMU_API */
@@ -1623,7 +1624,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
 int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 			  const u32 *input_id)
 {
-	const struct iommu_ops *iommu;
+	int ret;
 
 	if (attr == DEV_DMA_NOT_SUPPORTED) {
 		set_dma_ops(dev, &dma_dummy_ops);
@@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 
 	acpi_arch_dma_setup(dev);
 
-	iommu = acpi_iommu_configure_id(dev, input_id);
-	if (PTR_ERR(iommu) == -EPROBE_DEFER)
+	ret = acpi_iommu_configure_id(dev, input_id);
+	if (ret == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
+	/*
+	 * Historically this routine doesn't fail driver probing due to errors
+	 * in acpi_iommu_configure()
+	 */
+
 	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
 
 	return 0;
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Nothing needs this pointer. Return a normal error code with the usual
IOMMU semantic that ENODEV means 'there is no IOMMU driver'.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/acpi/scan.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index a6891ad0ceee2c..fbabde001a23a2 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1562,8 +1562,7 @@ static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
 	return fwspec ? fwspec->ops : NULL;
 }
 
-static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
-						       const u32 *id_in)
+static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 {
 	int err;
 	const struct iommu_ops *ops;
@@ -1574,7 +1573,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
 	 */
 	ops = acpi_iommu_fwspec_ops(dev);
 	if (ops)
-		return ops;
+		return 0;
 
 	err = iort_iommu_configure_id(dev, id_in);
 	if (err && err != -EPROBE_DEFER)
@@ -1589,12 +1588,14 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
 
 	/* Ignore all other errors apart from EPROBE_DEFER */
 	if (err == -EPROBE_DEFER) {
-		return ERR_PTR(err);
+		return err;
 	} else if (err) {
 		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		return NULL;
+		return -ENODEV;
 	}
-	return acpi_iommu_fwspec_ops(dev);
+	if (!acpi_iommu_fwspec_ops(dev))
+		return -ENODEV;
+	return 0;
 }
 
 #else /* !CONFIG_IOMMU_API */
@@ -1623,7 +1624,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
 int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 			  const u32 *input_id)
 {
-	const struct iommu_ops *iommu;
+	int ret;
 
 	if (attr == DEV_DMA_NOT_SUPPORTED) {
 		set_dma_ops(dev, &dma_dummy_ops);
@@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 
 	acpi_arch_dma_setup(dev);
 
-	iommu = acpi_iommu_configure_id(dev, input_id);
-	if (PTR_ERR(iommu) == -EPROBE_DEFER)
+	ret = acpi_iommu_configure_id(dev, input_id);
+	if (ret == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
+	/*
+	 * Historically this routine doesn't fail driver probing due to errors
+	 * in acpi_iommu_configure()
+	 */
+
 	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
 
 	return 0;
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Nothing needs this pointer. Return a normal error code with the usual
IOMMU semantic that ENODEV means 'there is no IOMMU driver'.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/acpi/scan.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index a6891ad0ceee2c..fbabde001a23a2 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1562,8 +1562,7 @@ static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
 	return fwspec ? fwspec->ops : NULL;
 }
 
-static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
-						       const u32 *id_in)
+static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 {
 	int err;
 	const struct iommu_ops *ops;
@@ -1574,7 +1573,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
 	 */
 	ops = acpi_iommu_fwspec_ops(dev);
 	if (ops)
-		return ops;
+		return 0;
 
 	err = iort_iommu_configure_id(dev, id_in);
 	if (err && err != -EPROBE_DEFER)
@@ -1589,12 +1588,14 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
 
 	/* Ignore all other errors apart from EPROBE_DEFER */
 	if (err == -EPROBE_DEFER) {
-		return ERR_PTR(err);
+		return err;
 	} else if (err) {
 		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		return NULL;
+		return -ENODEV;
 	}
-	return acpi_iommu_fwspec_ops(dev);
+	if (!acpi_iommu_fwspec_ops(dev))
+		return -ENODEV;
+	return 0;
 }
 
 #else /* !CONFIG_IOMMU_API */
@@ -1623,7 +1624,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
 int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 			  const u32 *input_id)
 {
-	const struct iommu_ops *iommu;
+	int ret;
 
 	if (attr == DEV_DMA_NOT_SUPPORTED) {
 		set_dma_ops(dev, &dma_dummy_ops);
@@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 
 	acpi_arch_dma_setup(dev);
 
-	iommu = acpi_iommu_configure_id(dev, input_id);
-	if (PTR_ERR(iommu) == -EPROBE_DEFER)
+	ret = acpi_iommu_configure_id(dev, input_id);
+	if (ret == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
+	/*
+	 * Historically this routine doesn't fail driver probing due to errors
+	 * in acpi_iommu_configure()
+	 */
+
 	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
 
 	return 0;
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Nothing needs this pointer. Return a normal error code with the usual
IOMMU semantic that ENODEV means 'there is no IOMMU driver'.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/acpi/scan.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index a6891ad0ceee2c..fbabde001a23a2 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1562,8 +1562,7 @@ static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
 	return fwspec ? fwspec->ops : NULL;
 }
 
-static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
-						       const u32 *id_in)
+static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 {
 	int err;
 	const struct iommu_ops *ops;
@@ -1574,7 +1573,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
 	 */
 	ops = acpi_iommu_fwspec_ops(dev);
 	if (ops)
-		return ops;
+		return 0;
 
 	err = iort_iommu_configure_id(dev, id_in);
 	if (err && err != -EPROBE_DEFER)
@@ -1589,12 +1588,14 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
 
 	/* Ignore all other errors apart from EPROBE_DEFER */
 	if (err == -EPROBE_DEFER) {
-		return ERR_PTR(err);
+		return err;
 	} else if (err) {
 		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		return NULL;
+		return -ENODEV;
 	}
-	return acpi_iommu_fwspec_ops(dev);
+	if (!acpi_iommu_fwspec_ops(dev))
+		return -ENODEV;
+	return 0;
 }
 
 #else /* !CONFIG_IOMMU_API */
@@ -1623,7 +1624,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
 int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 			  const u32 *input_id)
 {
-	const struct iommu_ops *iommu;
+	int ret;
 
 	if (attr == DEV_DMA_NOT_SUPPORTED) {
 		set_dma_ops(dev, &dma_dummy_ops);
@@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 
 	acpi_arch_dma_setup(dev);
 
-	iommu = acpi_iommu_configure_id(dev, input_id);
-	if (PTR_ERR(iommu) == -EPROBE_DEFER)
+	ret = acpi_iommu_configure_id(dev, input_id);
+	if (ret == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
+	/*
+	 * Historically this routine doesn't fail driver probing due to errors
+	 * in acpi_iommu_configure()
+	 */
+
 	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
 
 	return 0;
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 05/17] iommu: Make iommu_fwspec->ids a distinct allocation
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:44   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

The optimization of kreallocing the entire fwspec only works if the fwspec
pointer is always stored in the dev->iommu. Since we want to change this
remove the optimization and make the ids array a distinct allocation.

Allow a single id to be stored inside the iommu_fwspec as a common case
optimization.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 20 ++++++++++++--------
 include/linux/iommu.h |  3 ++-
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index c9a05bb49bfa17..d5e86985f6d363 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2948,8 +2948,7 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 	if (!dev_iommu_get(dev))
 		return -ENOMEM;
 
-	/* Preallocate for the overwhelmingly common case of 1 ID */
-	fwspec = kzalloc(struct_size(fwspec, ids, 1), GFP_KERNEL);
+	fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
 	if (!fwspec)
 		return -ENOMEM;
 
@@ -2982,13 +2981,18 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 		return -EINVAL;
 
 	new_num = fwspec->num_ids + num_ids;
-	if (new_num > 1) {
-		fwspec = krealloc(fwspec, struct_size(fwspec, ids, new_num),
-				  GFP_KERNEL);
-		if (!fwspec)
+	if (new_num <= 1) {
+		if (fwspec->ids != &fwspec->single_id)
+			kfree(fwspec->ids);
+		fwspec->ids = &fwspec->single_id;
+	} else if (new_num > fwspec->num_ids) {
+		ids = krealloc_array(
+			fwspec->ids != &fwspec->single_id ? fwspec->ids : NULL,
+			new_num, sizeof(fwspec->ids[0]),
+			GFP_KERNEL | __GFP_ZERO);
+		if (!ids)
 			return -ENOMEM;
-
-		dev_iommu_fwspec_set(dev, fwspec);
+		fwspec->ids = ids;
 	}
 
 	for (i = 0; i < num_ids; i++)
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index ddc25d2391063b..66ea1d08dc3f58 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -668,7 +668,8 @@ struct iommu_fwspec {
 	struct fwnode_handle	*iommu_fwnode;
 	u32			flags;
 	unsigned int		num_ids;
-	u32			ids[];
+	u32			single_id;
+	u32			*ids;
 };
 
 /* ATS is supported */
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 05/17] iommu: Make iommu_fwspec->ids a distinct allocation
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

The optimization of kreallocing the entire fwspec only works if the fwspec
pointer is always stored in the dev->iommu. Since we want to change this
remove the optimization and make the ids array a distinct allocation.

Allow a single id to be stored inside the iommu_fwspec as a common case
optimization.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 20 ++++++++++++--------
 include/linux/iommu.h |  3 ++-
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index c9a05bb49bfa17..d5e86985f6d363 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2948,8 +2948,7 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 	if (!dev_iommu_get(dev))
 		return -ENOMEM;
 
-	/* Preallocate for the overwhelmingly common case of 1 ID */
-	fwspec = kzalloc(struct_size(fwspec, ids, 1), GFP_KERNEL);
+	fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
 	if (!fwspec)
 		return -ENOMEM;
 
@@ -2982,13 +2981,18 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 		return -EINVAL;
 
 	new_num = fwspec->num_ids + num_ids;
-	if (new_num > 1) {
-		fwspec = krealloc(fwspec, struct_size(fwspec, ids, new_num),
-				  GFP_KERNEL);
-		if (!fwspec)
+	if (new_num <= 1) {
+		if (fwspec->ids != &fwspec->single_id)
+			kfree(fwspec->ids);
+		fwspec->ids = &fwspec->single_id;
+	} else if (new_num > fwspec->num_ids) {
+		ids = krealloc_array(
+			fwspec->ids != &fwspec->single_id ? fwspec->ids : NULL,
+			new_num, sizeof(fwspec->ids[0]),
+			GFP_KERNEL | __GFP_ZERO);
+		if (!ids)
 			return -ENOMEM;
-
-		dev_iommu_fwspec_set(dev, fwspec);
+		fwspec->ids = ids;
 	}
 
 	for (i = 0; i < num_ids; i++)
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index ddc25d2391063b..66ea1d08dc3f58 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -668,7 +668,8 @@ struct iommu_fwspec {
 	struct fwnode_handle	*iommu_fwnode;
 	u32			flags;
 	unsigned int		num_ids;
-	u32			ids[];
+	u32			single_id;
+	u32			*ids;
 };
 
 /* ATS is supported */
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 05/17] iommu: Make iommu_fwspec->ids a distinct allocation
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

The optimization of kreallocing the entire fwspec only works if the fwspec
pointer is always stored in the dev->iommu. Since we want to change this
remove the optimization and make the ids array a distinct allocation.

Allow a single id to be stored inside the iommu_fwspec as a common case
optimization.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 20 ++++++++++++--------
 include/linux/iommu.h |  3 ++-
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index c9a05bb49bfa17..d5e86985f6d363 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2948,8 +2948,7 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 	if (!dev_iommu_get(dev))
 		return -ENOMEM;
 
-	/* Preallocate for the overwhelmingly common case of 1 ID */
-	fwspec = kzalloc(struct_size(fwspec, ids, 1), GFP_KERNEL);
+	fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
 	if (!fwspec)
 		return -ENOMEM;
 
@@ -2982,13 +2981,18 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 		return -EINVAL;
 
 	new_num = fwspec->num_ids + num_ids;
-	if (new_num > 1) {
-		fwspec = krealloc(fwspec, struct_size(fwspec, ids, new_num),
-				  GFP_KERNEL);
-		if (!fwspec)
+	if (new_num <= 1) {
+		if (fwspec->ids != &fwspec->single_id)
+			kfree(fwspec->ids);
+		fwspec->ids = &fwspec->single_id;
+	} else if (new_num > fwspec->num_ids) {
+		ids = krealloc_array(
+			fwspec->ids != &fwspec->single_id ? fwspec->ids : NULL,
+			new_num, sizeof(fwspec->ids[0]),
+			GFP_KERNEL | __GFP_ZERO);
+		if (!ids)
 			return -ENOMEM;
-
-		dev_iommu_fwspec_set(dev, fwspec);
+		fwspec->ids = ids;
 	}
 
 	for (i = 0; i < num_ids; i++)
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index ddc25d2391063b..66ea1d08dc3f58 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -668,7 +668,8 @@ struct iommu_fwspec {
 	struct fwnode_handle	*iommu_fwnode;
 	u32			flags;
 	unsigned int		num_ids;
-	u32			ids[];
+	u32			single_id;
+	u32			*ids;
 };
 
 /* ATS is supported */
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 05/17] iommu: Make iommu_fwspec->ids a distinct allocation
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

The optimization of kreallocing the entire fwspec only works if the fwspec
pointer is always stored in the dev->iommu. Since we want to change this
remove the optimization and make the ids array a distinct allocation.

Allow a single id to be stored inside the iommu_fwspec as a common case
optimization.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 20 ++++++++++++--------
 include/linux/iommu.h |  3 ++-
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index c9a05bb49bfa17..d5e86985f6d363 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2948,8 +2948,7 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 	if (!dev_iommu_get(dev))
 		return -ENOMEM;
 
-	/* Preallocate for the overwhelmingly common case of 1 ID */
-	fwspec = kzalloc(struct_size(fwspec, ids, 1), GFP_KERNEL);
+	fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
 	if (!fwspec)
 		return -ENOMEM;
 
@@ -2982,13 +2981,18 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 		return -EINVAL;
 
 	new_num = fwspec->num_ids + num_ids;
-	if (new_num > 1) {
-		fwspec = krealloc(fwspec, struct_size(fwspec, ids, new_num),
-				  GFP_KERNEL);
-		if (!fwspec)
+	if (new_num <= 1) {
+		if (fwspec->ids != &fwspec->single_id)
+			kfree(fwspec->ids);
+		fwspec->ids = &fwspec->single_id;
+	} else if (new_num > fwspec->num_ids) {
+		ids = krealloc_array(
+			fwspec->ids != &fwspec->single_id ? fwspec->ids : NULL,
+			new_num, sizeof(fwspec->ids[0]),
+			GFP_KERNEL | __GFP_ZERO);
+		if (!ids)
 			return -ENOMEM;
-
-		dev_iommu_fwspec_set(dev, fwspec);
+		fwspec->ids = ids;
 	}
 
 	for (i = 0; i < num_ids; i++)
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index ddc25d2391063b..66ea1d08dc3f58 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -668,7 +668,8 @@ struct iommu_fwspec {
 	struct fwnode_handle	*iommu_fwnode;
 	u32			flags;
 	unsigned int		num_ids;
-	u32			ids[];
+	u32			single_id;
+	u32			*ids;
 };
 
 /* ATS is supported */
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 05/17] iommu: Make iommu_fwspec->ids a distinct allocation
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

The optimization of kreallocing the entire fwspec only works if the fwspec
pointer is always stored in the dev->iommu. Since we want to change this
remove the optimization and make the ids array a distinct allocation.

Allow a single id to be stored inside the iommu_fwspec as a common case
optimization.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 20 ++++++++++++--------
 include/linux/iommu.h |  3 ++-
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index c9a05bb49bfa17..d5e86985f6d363 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2948,8 +2948,7 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 	if (!dev_iommu_get(dev))
 		return -ENOMEM;
 
-	/* Preallocate for the overwhelmingly common case of 1 ID */
-	fwspec = kzalloc(struct_size(fwspec, ids, 1), GFP_KERNEL);
+	fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
 	if (!fwspec)
 		return -ENOMEM;
 
@@ -2982,13 +2981,18 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 		return -EINVAL;
 
 	new_num = fwspec->num_ids + num_ids;
-	if (new_num > 1) {
-		fwspec = krealloc(fwspec, struct_size(fwspec, ids, new_num),
-				  GFP_KERNEL);
-		if (!fwspec)
+	if (new_num <= 1) {
+		if (fwspec->ids != &fwspec->single_id)
+			kfree(fwspec->ids);
+		fwspec->ids = &fwspec->single_id;
+	} else if (new_num > fwspec->num_ids) {
+		ids = krealloc_array(
+			fwspec->ids != &fwspec->single_id ? fwspec->ids : NULL,
+			new_num, sizeof(fwspec->ids[0]),
+			GFP_KERNEL | __GFP_ZERO);
+		if (!ids)
 			return -ENOMEM;
-
-		dev_iommu_fwspec_set(dev, fwspec);
+		fwspec->ids = ids;
 	}
 
 	for (i = 0; i < num_ids; i++)
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index ddc25d2391063b..66ea1d08dc3f58 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -668,7 +668,8 @@ struct iommu_fwspec {
 	struct fwnode_handle	*iommu_fwnode;
 	u32			flags;
 	unsigned int		num_ids;
-	u32			ids[];
+	u32			single_id;
+	u32			*ids;
 };
 
 /* ATS is supported */
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 06/17] iommu: Add iommu_fwspec_alloc/dealloc()
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:44   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Allow fwspec to exist independently from the dev->iommu by providing
functions to allow allocating and freeing the raw struct iommu_fwspec.

Reflow the existing paths to call the new alloc/dealloc functions.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 82 ++++++++++++++++++++++++++++++++-----------
 include/linux/iommu.h | 11 +++++-
 2 files changed, 72 insertions(+), 21 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d5e86985f6d363..46f3d19a1291b0 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -361,10 +361,8 @@ static void dev_iommu_free(struct device *dev)
 	struct dev_iommu *param = dev->iommu;
 
 	dev->iommu = NULL;
-	if (param->fwspec) {
-		fwnode_handle_put(param->fwspec->iommu_fwnode);
-		kfree(param->fwspec);
-	}
+	if (param->fwspec)
+		iommu_fwspec_dealloc(param->fwspec);
 	kfree(param);
 }
 
@@ -2937,10 +2935,61 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 	return ops;
 }
 
+static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
+				     struct device *dev,
+				     struct fwnode_handle *iommu_fwnode)
+{
+	const struct iommu_ops *ops;
+
+	if (fwspec->iommu_fwnode) {
+		/*
+		 * fwspec->iommu_fwnode is the first iommu's fwnode. In the rare
+		 * case of multiple iommus for one device they must point to the
+		 * same driver, checked via same ops.
+		 */
+		ops = iommu_ops_from_fwnode(iommu_fwnode);
+		if (fwspec->ops != ops)
+			return -EINVAL;
+		return 0;
+	}
+
+	if (!fwspec->ops) {
+		ops = iommu_ops_from_fwnode(iommu_fwnode);
+		if (!ops)
+			return driver_deferred_probe_check_state(dev);
+		fwspec->ops = ops;
+	}
+
+	of_node_get(to_of_node(iommu_fwnode));
+	fwspec->iommu_fwnode = iommu_fwnode;
+	return 0;
+}
+
+struct iommu_fwspec *iommu_fwspec_alloc(void)
+{
+	struct iommu_fwspec *fwspec;
+
+	fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
+	if (!fwspec)
+		return ERR_PTR(-ENOMEM);
+	return fwspec;
+}
+
+void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec)
+{
+	if (!fwspec)
+		return;
+
+	if (fwspec->iommu_fwnode)
+		fwnode_handle_put(fwspec->iommu_fwnode);
+	kfree(fwspec);
+}
+
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	int ret;
 
 	if (fwspec)
 		return ops == fwspec->ops ? 0 : -EINVAL;
@@ -2948,29 +2997,22 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 	if (!dev_iommu_get(dev))
 		return -ENOMEM;
 
-	fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
-	if (!fwspec)
-		return -ENOMEM;
+	fwspec = iommu_fwspec_alloc();
+	if (IS_ERR(fwspec))
+		return PTR_ERR(fwspec);
 
-	of_node_get(to_of_node(iommu_fwnode));
-	fwspec->iommu_fwnode = iommu_fwnode;
 	fwspec->ops = ops;
+	ret = iommu_fwspec_assign_iommu(fwspec, dev, iommu_fwnode);
+	if (ret) {
+		iommu_fwspec_dealloc(fwspec);
+		return ret;
+	}
+
 	dev_iommu_fwspec_set(dev, fwspec);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_init);
 
-void iommu_fwspec_free(struct device *dev)
-{
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-
-	if (fwspec) {
-		fwnode_handle_put(fwspec->iommu_fwnode);
-		kfree(fwspec);
-		dev_iommu_fwspec_set(dev, NULL);
-	}
-}
-EXPORT_SYMBOL_GPL(iommu_fwspec_free);
 
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 {
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 66ea1d08dc3f58..b827dd6a5844b0 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -683,9 +683,18 @@ struct iommu_sva {
 	struct iommu_domain		*domain;
 };
 
+struct iommu_fwspec *iommu_fwspec_alloc(void);
+void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
+
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
-void iommu_fwspec_free(struct device *dev);
+static inline void iommu_fwspec_free(struct device *dev)
+{
+	if (!dev->iommu)
+		return;
+	iommu_fwspec_dealloc(dev->iommu->fwspec);
+	dev->iommu->fwspec = NULL;
+}
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
 const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
 
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 06/17] iommu: Add iommu_fwspec_alloc/dealloc()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Allow fwspec to exist independently from the dev->iommu by providing
functions to allow allocating and freeing the raw struct iommu_fwspec.

Reflow the existing paths to call the new alloc/dealloc functions.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 82 ++++++++++++++++++++++++++++++++-----------
 include/linux/iommu.h | 11 +++++-
 2 files changed, 72 insertions(+), 21 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d5e86985f6d363..46f3d19a1291b0 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -361,10 +361,8 @@ static void dev_iommu_free(struct device *dev)
 	struct dev_iommu *param = dev->iommu;
 
 	dev->iommu = NULL;
-	if (param->fwspec) {
-		fwnode_handle_put(param->fwspec->iommu_fwnode);
-		kfree(param->fwspec);
-	}
+	if (param->fwspec)
+		iommu_fwspec_dealloc(param->fwspec);
 	kfree(param);
 }
 
@@ -2937,10 +2935,61 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 	return ops;
 }
 
+static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
+				     struct device *dev,
+				     struct fwnode_handle *iommu_fwnode)
+{
+	const struct iommu_ops *ops;
+
+	if (fwspec->iommu_fwnode) {
+		/*
+		 * fwspec->iommu_fwnode is the first iommu's fwnode. In the rare
+		 * case of multiple iommus for one device they must point to the
+		 * same driver, checked via same ops.
+		 */
+		ops = iommu_ops_from_fwnode(iommu_fwnode);
+		if (fwspec->ops != ops)
+			return -EINVAL;
+		return 0;
+	}
+
+	if (!fwspec->ops) {
+		ops = iommu_ops_from_fwnode(iommu_fwnode);
+		if (!ops)
+			return driver_deferred_probe_check_state(dev);
+		fwspec->ops = ops;
+	}
+
+	of_node_get(to_of_node(iommu_fwnode));
+	fwspec->iommu_fwnode = iommu_fwnode;
+	return 0;
+}
+
+struct iommu_fwspec *iommu_fwspec_alloc(void)
+{
+	struct iommu_fwspec *fwspec;
+
+	fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
+	if (!fwspec)
+		return ERR_PTR(-ENOMEM);
+	return fwspec;
+}
+
+void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec)
+{
+	if (!fwspec)
+		return;
+
+	if (fwspec->iommu_fwnode)
+		fwnode_handle_put(fwspec->iommu_fwnode);
+	kfree(fwspec);
+}
+
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	int ret;
 
 	if (fwspec)
 		return ops == fwspec->ops ? 0 : -EINVAL;
@@ -2948,29 +2997,22 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 	if (!dev_iommu_get(dev))
 		return -ENOMEM;
 
-	fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
-	if (!fwspec)
-		return -ENOMEM;
+	fwspec = iommu_fwspec_alloc();
+	if (IS_ERR(fwspec))
+		return PTR_ERR(fwspec);
 
-	of_node_get(to_of_node(iommu_fwnode));
-	fwspec->iommu_fwnode = iommu_fwnode;
 	fwspec->ops = ops;
+	ret = iommu_fwspec_assign_iommu(fwspec, dev, iommu_fwnode);
+	if (ret) {
+		iommu_fwspec_dealloc(fwspec);
+		return ret;
+	}
+
 	dev_iommu_fwspec_set(dev, fwspec);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_init);
 
-void iommu_fwspec_free(struct device *dev)
-{
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-
-	if (fwspec) {
-		fwnode_handle_put(fwspec->iommu_fwnode);
-		kfree(fwspec);
-		dev_iommu_fwspec_set(dev, NULL);
-	}
-}
-EXPORT_SYMBOL_GPL(iommu_fwspec_free);
 
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 {
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 66ea1d08dc3f58..b827dd6a5844b0 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -683,9 +683,18 @@ struct iommu_sva {
 	struct iommu_domain		*domain;
 };
 
+struct iommu_fwspec *iommu_fwspec_alloc(void);
+void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
+
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
-void iommu_fwspec_free(struct device *dev);
+static inline void iommu_fwspec_free(struct device *dev)
+{
+	if (!dev->iommu)
+		return;
+	iommu_fwspec_dealloc(dev->iommu->fwspec);
+	dev->iommu->fwspec = NULL;
+}
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
 const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
 
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 06/17] iommu: Add iommu_fwspec_alloc/dealloc()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Allow fwspec to exist independently from the dev->iommu by providing
functions to allow allocating and freeing the raw struct iommu_fwspec.

Reflow the existing paths to call the new alloc/dealloc functions.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 82 ++++++++++++++++++++++++++++++++-----------
 include/linux/iommu.h | 11 +++++-
 2 files changed, 72 insertions(+), 21 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d5e86985f6d363..46f3d19a1291b0 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -361,10 +361,8 @@ static void dev_iommu_free(struct device *dev)
 	struct dev_iommu *param = dev->iommu;
 
 	dev->iommu = NULL;
-	if (param->fwspec) {
-		fwnode_handle_put(param->fwspec->iommu_fwnode);
-		kfree(param->fwspec);
-	}
+	if (param->fwspec)
+		iommu_fwspec_dealloc(param->fwspec);
 	kfree(param);
 }
 
@@ -2937,10 +2935,61 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 	return ops;
 }
 
+static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
+				     struct device *dev,
+				     struct fwnode_handle *iommu_fwnode)
+{
+	const struct iommu_ops *ops;
+
+	if (fwspec->iommu_fwnode) {
+		/*
+		 * fwspec->iommu_fwnode is the first iommu's fwnode. In the rare
+		 * case of multiple iommus for one device they must point to the
+		 * same driver, checked via same ops.
+		 */
+		ops = iommu_ops_from_fwnode(iommu_fwnode);
+		if (fwspec->ops != ops)
+			return -EINVAL;
+		return 0;
+	}
+
+	if (!fwspec->ops) {
+		ops = iommu_ops_from_fwnode(iommu_fwnode);
+		if (!ops)
+			return driver_deferred_probe_check_state(dev);
+		fwspec->ops = ops;
+	}
+
+	of_node_get(to_of_node(iommu_fwnode));
+	fwspec->iommu_fwnode = iommu_fwnode;
+	return 0;
+}
+
+struct iommu_fwspec *iommu_fwspec_alloc(void)
+{
+	struct iommu_fwspec *fwspec;
+
+	fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
+	if (!fwspec)
+		return ERR_PTR(-ENOMEM);
+	return fwspec;
+}
+
+void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec)
+{
+	if (!fwspec)
+		return;
+
+	if (fwspec->iommu_fwnode)
+		fwnode_handle_put(fwspec->iommu_fwnode);
+	kfree(fwspec);
+}
+
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	int ret;
 
 	if (fwspec)
 		return ops == fwspec->ops ? 0 : -EINVAL;
@@ -2948,29 +2997,22 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 	if (!dev_iommu_get(dev))
 		return -ENOMEM;
 
-	fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
-	if (!fwspec)
-		return -ENOMEM;
+	fwspec = iommu_fwspec_alloc();
+	if (IS_ERR(fwspec))
+		return PTR_ERR(fwspec);
 
-	of_node_get(to_of_node(iommu_fwnode));
-	fwspec->iommu_fwnode = iommu_fwnode;
 	fwspec->ops = ops;
+	ret = iommu_fwspec_assign_iommu(fwspec, dev, iommu_fwnode);
+	if (ret) {
+		iommu_fwspec_dealloc(fwspec);
+		return ret;
+	}
+
 	dev_iommu_fwspec_set(dev, fwspec);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_init);
 
-void iommu_fwspec_free(struct device *dev)
-{
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-
-	if (fwspec) {
-		fwnode_handle_put(fwspec->iommu_fwnode);
-		kfree(fwspec);
-		dev_iommu_fwspec_set(dev, NULL);
-	}
-}
-EXPORT_SYMBOL_GPL(iommu_fwspec_free);
 
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 {
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 66ea1d08dc3f58..b827dd6a5844b0 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -683,9 +683,18 @@ struct iommu_sva {
 	struct iommu_domain		*domain;
 };
 
+struct iommu_fwspec *iommu_fwspec_alloc(void);
+void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
+
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
-void iommu_fwspec_free(struct device *dev);
+static inline void iommu_fwspec_free(struct device *dev)
+{
+	if (!dev->iommu)
+		return;
+	iommu_fwspec_dealloc(dev->iommu->fwspec);
+	dev->iommu->fwspec = NULL;
+}
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
 const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
 
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 06/17] iommu: Add iommu_fwspec_alloc/dealloc()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Allow fwspec to exist independently from the dev->iommu by providing
functions to allow allocating and freeing the raw struct iommu_fwspec.

Reflow the existing paths to call the new alloc/dealloc functions.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 82 ++++++++++++++++++++++++++++++++-----------
 include/linux/iommu.h | 11 +++++-
 2 files changed, 72 insertions(+), 21 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d5e86985f6d363..46f3d19a1291b0 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -361,10 +361,8 @@ static void dev_iommu_free(struct device *dev)
 	struct dev_iommu *param = dev->iommu;
 
 	dev->iommu = NULL;
-	if (param->fwspec) {
-		fwnode_handle_put(param->fwspec->iommu_fwnode);
-		kfree(param->fwspec);
-	}
+	if (param->fwspec)
+		iommu_fwspec_dealloc(param->fwspec);
 	kfree(param);
 }
 
@@ -2937,10 +2935,61 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 	return ops;
 }
 
+static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
+				     struct device *dev,
+				     struct fwnode_handle *iommu_fwnode)
+{
+	const struct iommu_ops *ops;
+
+	if (fwspec->iommu_fwnode) {
+		/*
+		 * fwspec->iommu_fwnode is the first iommu's fwnode. In the rare
+		 * case of multiple iommus for one device they must point to the
+		 * same driver, checked via same ops.
+		 */
+		ops = iommu_ops_from_fwnode(iommu_fwnode);
+		if (fwspec->ops != ops)
+			return -EINVAL;
+		return 0;
+	}
+
+	if (!fwspec->ops) {
+		ops = iommu_ops_from_fwnode(iommu_fwnode);
+		if (!ops)
+			return driver_deferred_probe_check_state(dev);
+		fwspec->ops = ops;
+	}
+
+	of_node_get(to_of_node(iommu_fwnode));
+	fwspec->iommu_fwnode = iommu_fwnode;
+	return 0;
+}
+
+struct iommu_fwspec *iommu_fwspec_alloc(void)
+{
+	struct iommu_fwspec *fwspec;
+
+	fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
+	if (!fwspec)
+		return ERR_PTR(-ENOMEM);
+	return fwspec;
+}
+
+void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec)
+{
+	if (!fwspec)
+		return;
+
+	if (fwspec->iommu_fwnode)
+		fwnode_handle_put(fwspec->iommu_fwnode);
+	kfree(fwspec);
+}
+
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	int ret;
 
 	if (fwspec)
 		return ops == fwspec->ops ? 0 : -EINVAL;
@@ -2948,29 +2997,22 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 	if (!dev_iommu_get(dev))
 		return -ENOMEM;
 
-	fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
-	if (!fwspec)
-		return -ENOMEM;
+	fwspec = iommu_fwspec_alloc();
+	if (IS_ERR(fwspec))
+		return PTR_ERR(fwspec);
 
-	of_node_get(to_of_node(iommu_fwnode));
-	fwspec->iommu_fwnode = iommu_fwnode;
 	fwspec->ops = ops;
+	ret = iommu_fwspec_assign_iommu(fwspec, dev, iommu_fwnode);
+	if (ret) {
+		iommu_fwspec_dealloc(fwspec);
+		return ret;
+	}
+
 	dev_iommu_fwspec_set(dev, fwspec);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_init);
 
-void iommu_fwspec_free(struct device *dev)
-{
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-
-	if (fwspec) {
-		fwnode_handle_put(fwspec->iommu_fwnode);
-		kfree(fwspec);
-		dev_iommu_fwspec_set(dev, NULL);
-	}
-}
-EXPORT_SYMBOL_GPL(iommu_fwspec_free);
 
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 {
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 66ea1d08dc3f58..b827dd6a5844b0 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -683,9 +683,18 @@ struct iommu_sva {
 	struct iommu_domain		*domain;
 };
 
+struct iommu_fwspec *iommu_fwspec_alloc(void);
+void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
+
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
-void iommu_fwspec_free(struct device *dev);
+static inline void iommu_fwspec_free(struct device *dev)
+{
+	if (!dev->iommu)
+		return;
+	iommu_fwspec_dealloc(dev->iommu->fwspec);
+	dev->iommu->fwspec = NULL;
+}
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
 const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
 
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 06/17] iommu: Add iommu_fwspec_alloc/dealloc()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Allow fwspec to exist independently from the dev->iommu by providing
functions to allow allocating and freeing the raw struct iommu_fwspec.

Reflow the existing paths to call the new alloc/dealloc functions.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 82 ++++++++++++++++++++++++++++++++-----------
 include/linux/iommu.h | 11 +++++-
 2 files changed, 72 insertions(+), 21 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d5e86985f6d363..46f3d19a1291b0 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -361,10 +361,8 @@ static void dev_iommu_free(struct device *dev)
 	struct dev_iommu *param = dev->iommu;
 
 	dev->iommu = NULL;
-	if (param->fwspec) {
-		fwnode_handle_put(param->fwspec->iommu_fwnode);
-		kfree(param->fwspec);
-	}
+	if (param->fwspec)
+		iommu_fwspec_dealloc(param->fwspec);
 	kfree(param);
 }
 
@@ -2937,10 +2935,61 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 	return ops;
 }
 
+static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
+				     struct device *dev,
+				     struct fwnode_handle *iommu_fwnode)
+{
+	const struct iommu_ops *ops;
+
+	if (fwspec->iommu_fwnode) {
+		/*
+		 * fwspec->iommu_fwnode is the first iommu's fwnode. In the rare
+		 * case of multiple iommus for one device they must point to the
+		 * same driver, checked via same ops.
+		 */
+		ops = iommu_ops_from_fwnode(iommu_fwnode);
+		if (fwspec->ops != ops)
+			return -EINVAL;
+		return 0;
+	}
+
+	if (!fwspec->ops) {
+		ops = iommu_ops_from_fwnode(iommu_fwnode);
+		if (!ops)
+			return driver_deferred_probe_check_state(dev);
+		fwspec->ops = ops;
+	}
+
+	of_node_get(to_of_node(iommu_fwnode));
+	fwspec->iommu_fwnode = iommu_fwnode;
+	return 0;
+}
+
+struct iommu_fwspec *iommu_fwspec_alloc(void)
+{
+	struct iommu_fwspec *fwspec;
+
+	fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
+	if (!fwspec)
+		return ERR_PTR(-ENOMEM);
+	return fwspec;
+}
+
+void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec)
+{
+	if (!fwspec)
+		return;
+
+	if (fwspec->iommu_fwnode)
+		fwnode_handle_put(fwspec->iommu_fwnode);
+	kfree(fwspec);
+}
+
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	int ret;
 
 	if (fwspec)
 		return ops == fwspec->ops ? 0 : -EINVAL;
@@ -2948,29 +2997,22 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 	if (!dev_iommu_get(dev))
 		return -ENOMEM;
 
-	fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
-	if (!fwspec)
-		return -ENOMEM;
+	fwspec = iommu_fwspec_alloc();
+	if (IS_ERR(fwspec))
+		return PTR_ERR(fwspec);
 
-	of_node_get(to_of_node(iommu_fwnode));
-	fwspec->iommu_fwnode = iommu_fwnode;
 	fwspec->ops = ops;
+	ret = iommu_fwspec_assign_iommu(fwspec, dev, iommu_fwnode);
+	if (ret) {
+		iommu_fwspec_dealloc(fwspec);
+		return ret;
+	}
+
 	dev_iommu_fwspec_set(dev, fwspec);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_init);
 
-void iommu_fwspec_free(struct device *dev)
-{
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-
-	if (fwspec) {
-		fwnode_handle_put(fwspec->iommu_fwnode);
-		kfree(fwspec);
-		dev_iommu_fwspec_set(dev, NULL);
-	}
-}
-EXPORT_SYMBOL_GPL(iommu_fwspec_free);
 
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 {
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 66ea1d08dc3f58..b827dd6a5844b0 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -683,9 +683,18 @@ struct iommu_sva {
 	struct iommu_domain		*domain;
 };
 
+struct iommu_fwspec *iommu_fwspec_alloc(void);
+void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
+
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
-void iommu_fwspec_free(struct device *dev);
+static inline void iommu_fwspec_free(struct device *dev)
+{
+	if (!dev->iommu)
+		return;
+	iommu_fwspec_dealloc(dev->iommu->fwspec);
+	dev->iommu->fwspec = NULL;
+}
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
 const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
 
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 07/17] iommu: Add iommu_probe_device_fwspec()
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:44   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Instead of obtaining an iommu_fwspec from dev->iommu allow a caller
allocated fwspec to be passed into the probe logic. To keep the driver ops
APIs the same the fwspec is stored in dev->iommu under the
iommu_probe_device_lock.

If a fwspec is available use it to provide the ops instead of the bus.

The lifecycle logic is a bit tortured because of how the existing driver
code works. The new routine unconditionally takes ownership, even for
failure. This could be simplified we can get rid of the remaining
iommu_fwspec_init() callers someday.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 53 +++++++++++++++++++++++++++++++------------
 include/linux/iommu.h |  6 ++++-
 2 files changed, 44 insertions(+), 15 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 46f3d19a1291b0..36561c9fbf6859 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -386,16 +386,24 @@ static u32 dev_iommu_get_max_pasids(struct device *dev)
 
 /*
  * Init the dev->iommu and dev->iommu_group in the struct device and get the
- * driver probed
+ * driver probed. Take ownership of fwspec, it always freed on error
+ * or freed by iommu_deinit_device().
  */
-static int iommu_init_device(struct device *dev, const struct iommu_ops *ops)
+static int iommu_init_device(struct device *dev, struct iommu_fwspec *fwspec,
+			     const struct iommu_ops *ops)
 {
 	struct iommu_device *iommu_dev;
 	struct iommu_group *group;
 	int ret;
 
-	if (!dev_iommu_get(dev))
+	if (!dev_iommu_get(dev)) {
+		iommu_fwspec_dealloc(fwspec);
 		return -ENOMEM;
+	}
+
+	if (dev->iommu->fwspec && dev->iommu->fwspec != fwspec)
+		iommu_fwspec_dealloc(dev->iommu->fwspec);
+	dev->iommu->fwspec = fwspec;
 
 	if (!try_module_get(ops->owner)) {
 		ret = -EINVAL;
@@ -483,16 +491,17 @@ static void iommu_deinit_device(struct device *dev)
 	dev_iommu_free(dev);
 }
 
-static int __iommu_probe_device(struct device *dev, struct list_head *group_list)
+static int __iommu_probe_device(struct device *dev,
+				struct iommu_fwspec *caller_fwspec,
+				struct list_head *group_list)
 {
-	const struct iommu_ops *ops = dev->bus->iommu_ops;
+	struct iommu_fwspec *fwspec = caller_fwspec;
+	const struct iommu_ops *ops;
 	struct iommu_group *group;
 	static DEFINE_MUTEX(iommu_probe_device_lock);
 	struct group_device *gdev;
 	int ret;
 
-	if (!ops)
-		return -ENODEV;
 	/*
 	 * Serialise to avoid races between IOMMU drivers registering in
 	 * parallel and/or the "replay" calls from ACPI/OF code via client
@@ -502,13 +511,25 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
 	 */
 	mutex_lock(&iommu_probe_device_lock);
 
-	/* Device is probed already if in a group */
-	if (dev->iommu_group) {
-		ret = 0;
+	if (!fwspec && dev->iommu)
+		fwspec = dev->iommu->fwspec;
+	if (fwspec)
+		ops = fwspec->ops;
+	else
+		ops = dev->bus->iommu_ops;
+	if (!ops) {
+		ret = -ENODEV;
 		goto out_unlock;
 	}
 
-	ret = iommu_init_device(dev, ops);
+	/* Device is probed already if in a group */
+	if (dev->iommu_group) {
+		ret = 0;
+		iommu_fwspec_dealloc(caller_fwspec);
+		goto out_unlock;
+	}
+
+	ret = iommu_init_device(dev, fwspec, ops);
 	if (ret)
 		goto out_unlock;
 
@@ -566,12 +587,16 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
 	return ret;
 }
 
-int iommu_probe_device(struct device *dev)
+/*
+ * Ownership of fwspec always transfers to iommu_probe_device_fwspec(), it will
+ * be free'd even on failure.
+ */
+int iommu_probe_device_fwspec(struct device *dev, struct iommu_fwspec *fwspec)
 {
 	const struct iommu_ops *ops;
 	int ret;
 
-	ret = __iommu_probe_device(dev, NULL);
+	ret = __iommu_probe_device(dev, fwspec, NULL);
 	if (ret)
 		return ret;
 
@@ -1820,7 +1845,7 @@ static int probe_iommu_group(struct device *dev, void *data)
 	struct list_head *group_list = data;
 	int ret;
 
-	ret = __iommu_probe_device(dev, group_list);
+	ret = __iommu_probe_device(dev, NULL, group_list);
 	if (ret == -ENODEV)
 		ret = 0;
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index b827dd6a5844b0..531382d692d71a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -725,7 +725,11 @@ static inline void dev_iommu_priv_set(struct device *dev, void *priv)
 	dev->iommu->priv = priv;
 }
 
-int iommu_probe_device(struct device *dev);
+int iommu_probe_device_fwspec(struct device *dev, struct iommu_fwspec *fwspec);
+static inline int iommu_probe_device(struct device *dev)
+{
+	return iommu_probe_device_fwspec(dev, NULL);
+}
 
 int iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features f);
 int iommu_dev_disable_feature(struct device *dev, enum iommu_dev_features f);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 07/17] iommu: Add iommu_probe_device_fwspec()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Instead of obtaining an iommu_fwspec from dev->iommu allow a caller
allocated fwspec to be passed into the probe logic. To keep the driver ops
APIs the same the fwspec is stored in dev->iommu under the
iommu_probe_device_lock.

If a fwspec is available use it to provide the ops instead of the bus.

The lifecycle logic is a bit tortured because of how the existing driver
code works. The new routine unconditionally takes ownership, even for
failure. This could be simplified we can get rid of the remaining
iommu_fwspec_init() callers someday.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 53 +++++++++++++++++++++++++++++++------------
 include/linux/iommu.h |  6 ++++-
 2 files changed, 44 insertions(+), 15 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 46f3d19a1291b0..36561c9fbf6859 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -386,16 +386,24 @@ static u32 dev_iommu_get_max_pasids(struct device *dev)
 
 /*
  * Init the dev->iommu and dev->iommu_group in the struct device and get the
- * driver probed
+ * driver probed. Take ownership of fwspec, it always freed on error
+ * or freed by iommu_deinit_device().
  */
-static int iommu_init_device(struct device *dev, const struct iommu_ops *ops)
+static int iommu_init_device(struct device *dev, struct iommu_fwspec *fwspec,
+			     const struct iommu_ops *ops)
 {
 	struct iommu_device *iommu_dev;
 	struct iommu_group *group;
 	int ret;
 
-	if (!dev_iommu_get(dev))
+	if (!dev_iommu_get(dev)) {
+		iommu_fwspec_dealloc(fwspec);
 		return -ENOMEM;
+	}
+
+	if (dev->iommu->fwspec && dev->iommu->fwspec != fwspec)
+		iommu_fwspec_dealloc(dev->iommu->fwspec);
+	dev->iommu->fwspec = fwspec;
 
 	if (!try_module_get(ops->owner)) {
 		ret = -EINVAL;
@@ -483,16 +491,17 @@ static void iommu_deinit_device(struct device *dev)
 	dev_iommu_free(dev);
 }
 
-static int __iommu_probe_device(struct device *dev, struct list_head *group_list)
+static int __iommu_probe_device(struct device *dev,
+				struct iommu_fwspec *caller_fwspec,
+				struct list_head *group_list)
 {
-	const struct iommu_ops *ops = dev->bus->iommu_ops;
+	struct iommu_fwspec *fwspec = caller_fwspec;
+	const struct iommu_ops *ops;
 	struct iommu_group *group;
 	static DEFINE_MUTEX(iommu_probe_device_lock);
 	struct group_device *gdev;
 	int ret;
 
-	if (!ops)
-		return -ENODEV;
 	/*
 	 * Serialise to avoid races between IOMMU drivers registering in
 	 * parallel and/or the "replay" calls from ACPI/OF code via client
@@ -502,13 +511,25 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
 	 */
 	mutex_lock(&iommu_probe_device_lock);
 
-	/* Device is probed already if in a group */
-	if (dev->iommu_group) {
-		ret = 0;
+	if (!fwspec && dev->iommu)
+		fwspec = dev->iommu->fwspec;
+	if (fwspec)
+		ops = fwspec->ops;
+	else
+		ops = dev->bus->iommu_ops;
+	if (!ops) {
+		ret = -ENODEV;
 		goto out_unlock;
 	}
 
-	ret = iommu_init_device(dev, ops);
+	/* Device is probed already if in a group */
+	if (dev->iommu_group) {
+		ret = 0;
+		iommu_fwspec_dealloc(caller_fwspec);
+		goto out_unlock;
+	}
+
+	ret = iommu_init_device(dev, fwspec, ops);
 	if (ret)
 		goto out_unlock;
 
@@ -566,12 +587,16 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
 	return ret;
 }
 
-int iommu_probe_device(struct device *dev)
+/*
+ * Ownership of fwspec always transfers to iommu_probe_device_fwspec(), it will
+ * be free'd even on failure.
+ */
+int iommu_probe_device_fwspec(struct device *dev, struct iommu_fwspec *fwspec)
 {
 	const struct iommu_ops *ops;
 	int ret;
 
-	ret = __iommu_probe_device(dev, NULL);
+	ret = __iommu_probe_device(dev, fwspec, NULL);
 	if (ret)
 		return ret;
 
@@ -1820,7 +1845,7 @@ static int probe_iommu_group(struct device *dev, void *data)
 	struct list_head *group_list = data;
 	int ret;
 
-	ret = __iommu_probe_device(dev, group_list);
+	ret = __iommu_probe_device(dev, NULL, group_list);
 	if (ret == -ENODEV)
 		ret = 0;
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index b827dd6a5844b0..531382d692d71a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -725,7 +725,11 @@ static inline void dev_iommu_priv_set(struct device *dev, void *priv)
 	dev->iommu->priv = priv;
 }
 
-int iommu_probe_device(struct device *dev);
+int iommu_probe_device_fwspec(struct device *dev, struct iommu_fwspec *fwspec);
+static inline int iommu_probe_device(struct device *dev)
+{
+	return iommu_probe_device_fwspec(dev, NULL);
+}
 
 int iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features f);
 int iommu_dev_disable_feature(struct device *dev, enum iommu_dev_features f);
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 07/17] iommu: Add iommu_probe_device_fwspec()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Instead of obtaining an iommu_fwspec from dev->iommu allow a caller
allocated fwspec to be passed into the probe logic. To keep the driver ops
APIs the same the fwspec is stored in dev->iommu under the
iommu_probe_device_lock.

If a fwspec is available use it to provide the ops instead of the bus.

The lifecycle logic is a bit tortured because of how the existing driver
code works. The new routine unconditionally takes ownership, even for
failure. This could be simplified we can get rid of the remaining
iommu_fwspec_init() callers someday.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 53 +++++++++++++++++++++++++++++++------------
 include/linux/iommu.h |  6 ++++-
 2 files changed, 44 insertions(+), 15 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 46f3d19a1291b0..36561c9fbf6859 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -386,16 +386,24 @@ static u32 dev_iommu_get_max_pasids(struct device *dev)
 
 /*
  * Init the dev->iommu and dev->iommu_group in the struct device and get the
- * driver probed
+ * driver probed. Take ownership of fwspec, it always freed on error
+ * or freed by iommu_deinit_device().
  */
-static int iommu_init_device(struct device *dev, const struct iommu_ops *ops)
+static int iommu_init_device(struct device *dev, struct iommu_fwspec *fwspec,
+			     const struct iommu_ops *ops)
 {
 	struct iommu_device *iommu_dev;
 	struct iommu_group *group;
 	int ret;
 
-	if (!dev_iommu_get(dev))
+	if (!dev_iommu_get(dev)) {
+		iommu_fwspec_dealloc(fwspec);
 		return -ENOMEM;
+	}
+
+	if (dev->iommu->fwspec && dev->iommu->fwspec != fwspec)
+		iommu_fwspec_dealloc(dev->iommu->fwspec);
+	dev->iommu->fwspec = fwspec;
 
 	if (!try_module_get(ops->owner)) {
 		ret = -EINVAL;
@@ -483,16 +491,17 @@ static void iommu_deinit_device(struct device *dev)
 	dev_iommu_free(dev);
 }
 
-static int __iommu_probe_device(struct device *dev, struct list_head *group_list)
+static int __iommu_probe_device(struct device *dev,
+				struct iommu_fwspec *caller_fwspec,
+				struct list_head *group_list)
 {
-	const struct iommu_ops *ops = dev->bus->iommu_ops;
+	struct iommu_fwspec *fwspec = caller_fwspec;
+	const struct iommu_ops *ops;
 	struct iommu_group *group;
 	static DEFINE_MUTEX(iommu_probe_device_lock);
 	struct group_device *gdev;
 	int ret;
 
-	if (!ops)
-		return -ENODEV;
 	/*
 	 * Serialise to avoid races between IOMMU drivers registering in
 	 * parallel and/or the "replay" calls from ACPI/OF code via client
@@ -502,13 +511,25 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
 	 */
 	mutex_lock(&iommu_probe_device_lock);
 
-	/* Device is probed already if in a group */
-	if (dev->iommu_group) {
-		ret = 0;
+	if (!fwspec && dev->iommu)
+		fwspec = dev->iommu->fwspec;
+	if (fwspec)
+		ops = fwspec->ops;
+	else
+		ops = dev->bus->iommu_ops;
+	if (!ops) {
+		ret = -ENODEV;
 		goto out_unlock;
 	}
 
-	ret = iommu_init_device(dev, ops);
+	/* Device is probed already if in a group */
+	if (dev->iommu_group) {
+		ret = 0;
+		iommu_fwspec_dealloc(caller_fwspec);
+		goto out_unlock;
+	}
+
+	ret = iommu_init_device(dev, fwspec, ops);
 	if (ret)
 		goto out_unlock;
 
@@ -566,12 +587,16 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
 	return ret;
 }
 
-int iommu_probe_device(struct device *dev)
+/*
+ * Ownership of fwspec always transfers to iommu_probe_device_fwspec(), it will
+ * be free'd even on failure.
+ */
+int iommu_probe_device_fwspec(struct device *dev, struct iommu_fwspec *fwspec)
 {
 	const struct iommu_ops *ops;
 	int ret;
 
-	ret = __iommu_probe_device(dev, NULL);
+	ret = __iommu_probe_device(dev, fwspec, NULL);
 	if (ret)
 		return ret;
 
@@ -1820,7 +1845,7 @@ static int probe_iommu_group(struct device *dev, void *data)
 	struct list_head *group_list = data;
 	int ret;
 
-	ret = __iommu_probe_device(dev, group_list);
+	ret = __iommu_probe_device(dev, NULL, group_list);
 	if (ret == -ENODEV)
 		ret = 0;
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index b827dd6a5844b0..531382d692d71a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -725,7 +725,11 @@ static inline void dev_iommu_priv_set(struct device *dev, void *priv)
 	dev->iommu->priv = priv;
 }
 
-int iommu_probe_device(struct device *dev);
+int iommu_probe_device_fwspec(struct device *dev, struct iommu_fwspec *fwspec);
+static inline int iommu_probe_device(struct device *dev)
+{
+	return iommu_probe_device_fwspec(dev, NULL);
+}
 
 int iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features f);
 int iommu_dev_disable_feature(struct device *dev, enum iommu_dev_features f);
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 07/17] iommu: Add iommu_probe_device_fwspec()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Instead of obtaining an iommu_fwspec from dev->iommu allow a caller
allocated fwspec to be passed into the probe logic. To keep the driver ops
APIs the same the fwspec is stored in dev->iommu under the
iommu_probe_device_lock.

If a fwspec is available use it to provide the ops instead of the bus.

The lifecycle logic is a bit tortured because of how the existing driver
code works. The new routine unconditionally takes ownership, even for
failure. This could be simplified we can get rid of the remaining
iommu_fwspec_init() callers someday.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 53 +++++++++++++++++++++++++++++++------------
 include/linux/iommu.h |  6 ++++-
 2 files changed, 44 insertions(+), 15 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 46f3d19a1291b0..36561c9fbf6859 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -386,16 +386,24 @@ static u32 dev_iommu_get_max_pasids(struct device *dev)
 
 /*
  * Init the dev->iommu and dev->iommu_group in the struct device and get the
- * driver probed
+ * driver probed. Take ownership of fwspec, it always freed on error
+ * or freed by iommu_deinit_device().
  */
-static int iommu_init_device(struct device *dev, const struct iommu_ops *ops)
+static int iommu_init_device(struct device *dev, struct iommu_fwspec *fwspec,
+			     const struct iommu_ops *ops)
 {
 	struct iommu_device *iommu_dev;
 	struct iommu_group *group;
 	int ret;
 
-	if (!dev_iommu_get(dev))
+	if (!dev_iommu_get(dev)) {
+		iommu_fwspec_dealloc(fwspec);
 		return -ENOMEM;
+	}
+
+	if (dev->iommu->fwspec && dev->iommu->fwspec != fwspec)
+		iommu_fwspec_dealloc(dev->iommu->fwspec);
+	dev->iommu->fwspec = fwspec;
 
 	if (!try_module_get(ops->owner)) {
 		ret = -EINVAL;
@@ -483,16 +491,17 @@ static void iommu_deinit_device(struct device *dev)
 	dev_iommu_free(dev);
 }
 
-static int __iommu_probe_device(struct device *dev, struct list_head *group_list)
+static int __iommu_probe_device(struct device *dev,
+				struct iommu_fwspec *caller_fwspec,
+				struct list_head *group_list)
 {
-	const struct iommu_ops *ops = dev->bus->iommu_ops;
+	struct iommu_fwspec *fwspec = caller_fwspec;
+	const struct iommu_ops *ops;
 	struct iommu_group *group;
 	static DEFINE_MUTEX(iommu_probe_device_lock);
 	struct group_device *gdev;
 	int ret;
 
-	if (!ops)
-		return -ENODEV;
 	/*
 	 * Serialise to avoid races between IOMMU drivers registering in
 	 * parallel and/or the "replay" calls from ACPI/OF code via client
@@ -502,13 +511,25 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
 	 */
 	mutex_lock(&iommu_probe_device_lock);
 
-	/* Device is probed already if in a group */
-	if (dev->iommu_group) {
-		ret = 0;
+	if (!fwspec && dev->iommu)
+		fwspec = dev->iommu->fwspec;
+	if (fwspec)
+		ops = fwspec->ops;
+	else
+		ops = dev->bus->iommu_ops;
+	if (!ops) {
+		ret = -ENODEV;
 		goto out_unlock;
 	}
 
-	ret = iommu_init_device(dev, ops);
+	/* Device is probed already if in a group */
+	if (dev->iommu_group) {
+		ret = 0;
+		iommu_fwspec_dealloc(caller_fwspec);
+		goto out_unlock;
+	}
+
+	ret = iommu_init_device(dev, fwspec, ops);
 	if (ret)
 		goto out_unlock;
 
@@ -566,12 +587,16 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
 	return ret;
 }
 
-int iommu_probe_device(struct device *dev)
+/*
+ * Ownership of fwspec always transfers to iommu_probe_device_fwspec(), it will
+ * be free'd even on failure.
+ */
+int iommu_probe_device_fwspec(struct device *dev, struct iommu_fwspec *fwspec)
 {
 	const struct iommu_ops *ops;
 	int ret;
 
-	ret = __iommu_probe_device(dev, NULL);
+	ret = __iommu_probe_device(dev, fwspec, NULL);
 	if (ret)
 		return ret;
 
@@ -1820,7 +1845,7 @@ static int probe_iommu_group(struct device *dev, void *data)
 	struct list_head *group_list = data;
 	int ret;
 
-	ret = __iommu_probe_device(dev, group_list);
+	ret = __iommu_probe_device(dev, NULL, group_list);
 	if (ret == -ENODEV)
 		ret = 0;
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index b827dd6a5844b0..531382d692d71a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -725,7 +725,11 @@ static inline void dev_iommu_priv_set(struct device *dev, void *priv)
 	dev->iommu->priv = priv;
 }
 
-int iommu_probe_device(struct device *dev);
+int iommu_probe_device_fwspec(struct device *dev, struct iommu_fwspec *fwspec);
+static inline int iommu_probe_device(struct device *dev)
+{
+	return iommu_probe_device_fwspec(dev, NULL);
+}
 
 int iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features f);
 int iommu_dev_disable_feature(struct device *dev, enum iommu_dev_features f);
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 07/17] iommu: Add iommu_probe_device_fwspec()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Instead of obtaining an iommu_fwspec from dev->iommu allow a caller
allocated fwspec to be passed into the probe logic. To keep the driver ops
APIs the same the fwspec is stored in dev->iommu under the
iommu_probe_device_lock.

If a fwspec is available use it to provide the ops instead of the bus.

The lifecycle logic is a bit tortured because of how the existing driver
code works. The new routine unconditionally takes ownership, even for
failure. This could be simplified we can get rid of the remaining
iommu_fwspec_init() callers someday.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 53 +++++++++++++++++++++++++++++++------------
 include/linux/iommu.h |  6 ++++-
 2 files changed, 44 insertions(+), 15 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 46f3d19a1291b0..36561c9fbf6859 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -386,16 +386,24 @@ static u32 dev_iommu_get_max_pasids(struct device *dev)
 
 /*
  * Init the dev->iommu and dev->iommu_group in the struct device and get the
- * driver probed
+ * driver probed. Take ownership of fwspec, it always freed on error
+ * or freed by iommu_deinit_device().
  */
-static int iommu_init_device(struct device *dev, const struct iommu_ops *ops)
+static int iommu_init_device(struct device *dev, struct iommu_fwspec *fwspec,
+			     const struct iommu_ops *ops)
 {
 	struct iommu_device *iommu_dev;
 	struct iommu_group *group;
 	int ret;
 
-	if (!dev_iommu_get(dev))
+	if (!dev_iommu_get(dev)) {
+		iommu_fwspec_dealloc(fwspec);
 		return -ENOMEM;
+	}
+
+	if (dev->iommu->fwspec && dev->iommu->fwspec != fwspec)
+		iommu_fwspec_dealloc(dev->iommu->fwspec);
+	dev->iommu->fwspec = fwspec;
 
 	if (!try_module_get(ops->owner)) {
 		ret = -EINVAL;
@@ -483,16 +491,17 @@ static void iommu_deinit_device(struct device *dev)
 	dev_iommu_free(dev);
 }
 
-static int __iommu_probe_device(struct device *dev, struct list_head *group_list)
+static int __iommu_probe_device(struct device *dev,
+				struct iommu_fwspec *caller_fwspec,
+				struct list_head *group_list)
 {
-	const struct iommu_ops *ops = dev->bus->iommu_ops;
+	struct iommu_fwspec *fwspec = caller_fwspec;
+	const struct iommu_ops *ops;
 	struct iommu_group *group;
 	static DEFINE_MUTEX(iommu_probe_device_lock);
 	struct group_device *gdev;
 	int ret;
 
-	if (!ops)
-		return -ENODEV;
 	/*
 	 * Serialise to avoid races between IOMMU drivers registering in
 	 * parallel and/or the "replay" calls from ACPI/OF code via client
@@ -502,13 +511,25 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
 	 */
 	mutex_lock(&iommu_probe_device_lock);
 
-	/* Device is probed already if in a group */
-	if (dev->iommu_group) {
-		ret = 0;
+	if (!fwspec && dev->iommu)
+		fwspec = dev->iommu->fwspec;
+	if (fwspec)
+		ops = fwspec->ops;
+	else
+		ops = dev->bus->iommu_ops;
+	if (!ops) {
+		ret = -ENODEV;
 		goto out_unlock;
 	}
 
-	ret = iommu_init_device(dev, ops);
+	/* Device is probed already if in a group */
+	if (dev->iommu_group) {
+		ret = 0;
+		iommu_fwspec_dealloc(caller_fwspec);
+		goto out_unlock;
+	}
+
+	ret = iommu_init_device(dev, fwspec, ops);
 	if (ret)
 		goto out_unlock;
 
@@ -566,12 +587,16 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
 	return ret;
 }
 
-int iommu_probe_device(struct device *dev)
+/*
+ * Ownership of fwspec always transfers to iommu_probe_device_fwspec(), it will
+ * be free'd even on failure.
+ */
+int iommu_probe_device_fwspec(struct device *dev, struct iommu_fwspec *fwspec)
 {
 	const struct iommu_ops *ops;
 	int ret;
 
-	ret = __iommu_probe_device(dev, NULL);
+	ret = __iommu_probe_device(dev, fwspec, NULL);
 	if (ret)
 		return ret;
 
@@ -1820,7 +1845,7 @@ static int probe_iommu_group(struct device *dev, void *data)
 	struct list_head *group_list = data;
 	int ret;
 
-	ret = __iommu_probe_device(dev, group_list);
+	ret = __iommu_probe_device(dev, NULL, group_list);
 	if (ret == -ENODEV)
 		ret = 0;
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index b827dd6a5844b0..531382d692d71a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -725,7 +725,11 @@ static inline void dev_iommu_priv_set(struct device *dev, void *priv)
 	dev->iommu->priv = priv;
 }
 
-int iommu_probe_device(struct device *dev);
+int iommu_probe_device_fwspec(struct device *dev, struct iommu_fwspec *fwspec);
+static inline int iommu_probe_device(struct device *dev)
+{
+	return iommu_probe_device_fwspec(dev, NULL);
+}
 
 int iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features f);
 int iommu_dev_disable_feature(struct device *dev, enum iommu_dev_features f);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 08/17] of: Do not use dev->iommu within of_iommu_configure()
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:44   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This call chain is using dev->iommu->fwspec to pass around the fwspec
between the three parts (of_iommu_configure(), of_iommu_xlate(),
iommu_probe_device()).

However there is no locking around the accesses to dev->iommu, so this is
all racy.

Allocate a clean, local, fwspec at the start of of_iommu_configure(), pass
it through all functions on the stack to fill it with data, and finally
pass it into iommu_probe_device_fwspec() which will load it into
dev->iommu under a lock.

Move the actual call to ops->of_xlate into the core code under
iommu_fwspec_of_xlate().

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c    | 29 ++++++++++++++
 drivers/iommu/of_iommu.c | 82 +++++++++++++++++-----------------------
 include/linux/iommu.h    |  3 ++
 3 files changed, 67 insertions(+), 47 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 36561c9fbf6859..ad2963d69a0538 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2990,6 +2990,35 @@ static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
 	return 0;
 }
 
+int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
+			  struct fwnode_handle *iommu_fwnode,
+			  struct of_phandle_args *iommu_spec)
+{
+	int ret;
+
+	ret = iommu_fwspec_assign_iommu(fwspec, dev, iommu_fwnode);
+	if (ret)
+		return ret;
+
+	if (!fwspec->ops->of_xlate)
+		return -ENODEV;
+
+	if (!dev_iommu_get(dev))
+		return -ENOMEM;
+
+	/*
+	 * ops->of_xlate() requires the fwspec to be passed through dev->iommu,
+	 * set it temporarily.
+	 */
+	if (dev->iommu->fwspec && dev->iommu->fwspec != fwspec)
+		iommu_fwspec_dealloc(dev->iommu->fwspec);
+	dev->iommu->fwspec = fwspec;
+	ret = fwspec->ops->of_xlate(dev, iommu_spec);
+	if (dev->iommu->fwspec == fwspec)
+		dev->iommu->fwspec = NULL;
+	return ret;
+}
+
 struct iommu_fwspec *iommu_fwspec_alloc(void)
 {
 	struct iommu_fwspec *fwspec;
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 4f77495a2543ea..b232a6909e0d45 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -19,40 +19,19 @@
 
 #define NO_IOMMU	-ENODEV
 
-static int of_iommu_xlate(struct device *dev,
+static int of_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 			  struct of_phandle_args *iommu_spec)
 {
-	const struct iommu_ops *ops;
-	struct fwnode_handle *fwnode = &iommu_spec->np->fwnode;
-	int ret;
-
-	ops = iommu_ops_from_fwnode(fwnode);
-	if ((ops && !ops->of_xlate) ||
-	    !of_device_is_available(iommu_spec->np))
+	if (!of_device_is_available(iommu_spec->np))
 		return NO_IOMMU;
 
-	ret = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
-	if (ret)
-		return ret;
-	/*
-	 * The otherwise-empty fwspec handily serves to indicate the specific
-	 * IOMMU device we're waiting for, which will be useful if we ever get
-	 * a proper probe-ordering dependency mechanism in future.
-	 */
-	if (!ops)
-		return driver_deferred_probe_check_state(dev);
-
-	if (!try_module_get(ops->owner))
-		return -ENODEV;
-
-	ret = ops->of_xlate(dev, iommu_spec);
-	module_put(ops->owner);
-	return ret;
+	return iommu_fwspec_of_xlate(fwspec, dev, &iommu_spec->np->fwnode,
+				     iommu_spec);
 }
 
-static int of_iommu_configure_dev_id(struct device_node *master_np,
-				     struct device *dev,
-				     const u32 *id)
+static int of_iommu_configure_dev_id(struct iommu_fwspec *fwspec,
+				     struct device_node *master_np,
+				     struct device *dev, const u32 *id)
 {
 	struct of_phandle_args iommu_spec = { .args_count = 1 };
 	int err;
@@ -63,12 +42,13 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
 	if (err)
 		return err == -ENODEV ? NO_IOMMU : err;
 
-	err = of_iommu_xlate(dev, &iommu_spec);
+	err = of_iommu_xlate(fwspec, dev, &iommu_spec);
 	of_node_put(iommu_spec.np);
 	return err;
 }
 
-static int of_iommu_configure_dev(struct device_node *master_np,
+static int of_iommu_configure_dev(struct iommu_fwspec *fwspec,
+				  struct device_node *master_np,
 				  struct device *dev)
 {
 	struct of_phandle_args iommu_spec;
@@ -77,7 +57,7 @@ static int of_iommu_configure_dev(struct device_node *master_np,
 	while (!of_parse_phandle_with_args(master_np, "iommus",
 					   "#iommu-cells",
 					   idx, &iommu_spec)) {
-		err = of_iommu_xlate(dev, &iommu_spec);
+		err = of_iommu_xlate(fwspec, dev, &iommu_spec);
 		of_node_put(iommu_spec.np);
 		idx++;
 		if (err)
@@ -90,6 +70,7 @@ static int of_iommu_configure_dev(struct device_node *master_np,
 struct of_pci_iommu_alias_info {
 	struct device *dev;
 	struct device_node *np;
+	struct iommu_fwspec *fwspec;
 };
 
 static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
@@ -97,14 +78,16 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
 	struct of_pci_iommu_alias_info *info = data;
 	u32 input_id = alias;
 
-	return of_iommu_configure_dev_id(info->np, info->dev, &input_id);
+	return of_iommu_configure_dev_id(info->fwspec, info->np, info->dev,
+					 &input_id);
 }
 
-static int of_iommu_configure_device(struct device_node *master_np,
+static int of_iommu_configure_device(struct iommu_fwspec *fwspec,
+				     struct device_node *master_np,
 				     struct device *dev, const u32 *id)
 {
-	return (id) ? of_iommu_configure_dev_id(master_np, dev, id) :
-		      of_iommu_configure_dev(master_np, dev);
+	return (id) ? of_iommu_configure_dev_id(fwspec, master_np, dev, id) :
+		      of_iommu_configure_dev(fwspec, master_np, dev);
 }
 
 /*
@@ -117,19 +100,15 @@ static int of_iommu_configure_device(struct device_node *master_np,
 int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		       const u32 *id)
 {
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct iommu_fwspec *fwspec;
 	int err;
 
 	if (!master_np)
 		return -ENODEV;
 
-	if (fwspec) {
-		if (fwspec->ops)
-			return 0;
-
-		/* In the deferred case, start again from scratch */
-		iommu_fwspec_free(dev);
-	}
+	fwspec = iommu_fwspec_alloc();
+	if (IS_ERR(fwspec))
+		return PTR_ERR(fwspec);
 
 	/*
 	 * We don't currently walk up the tree looking for a parent IOMMU.
@@ -140,27 +119,36 @@ int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		struct of_pci_iommu_alias_info info = {
 			.dev = dev,
 			.np = master_np,
+			.fwspec = fwspec,
 		};
 
 		pci_request_acs();
 		err = pci_for_each_dma_alias(to_pci_dev(dev),
 					     of_pci_iommu_init, &info);
 	} else {
-		err = of_iommu_configure_device(master_np, dev, id);
+		err = of_iommu_configure_device(fwspec, master_np, dev, id);
 	}
 
 	if (err == -ENODEV || err == -EPROBE_DEFER)
-		return err;
+		goto err_free;
 	if (err)
 		goto err_log;
 
-	err = iommu_probe_device(dev);
-	if (err)
+	err = iommu_probe_device_fwspec(dev, fwspec);
+	if (err) {
+		/*
+		 * Ownership for fwspec always passes into
+		 * iommu_probe_device_fwspec()
+		 */
+		fwspec = NULL;
 		goto err_log;
+	}
 	return 0;
 
 err_log:
 	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+err_free:
+	iommu_fwspec_dealloc(fwspec);
 	return err;
 }
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 531382d692d71a..2644c61b572b8f 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -685,6 +685,9 @@ struct iommu_sva {
 
 struct iommu_fwspec *iommu_fwspec_alloc(void);
 void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
+int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
+			  struct fwnode_handle *iommu_fwnode,
+			  struct of_phandle_args *iommu_spec);
 
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 08/17] of: Do not use dev->iommu within of_iommu_configure()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This call chain is using dev->iommu->fwspec to pass around the fwspec
between the three parts (of_iommu_configure(), of_iommu_xlate(),
iommu_probe_device()).

However there is no locking around the accesses to dev->iommu, so this is
all racy.

Allocate a clean, local, fwspec at the start of of_iommu_configure(), pass
it through all functions on the stack to fill it with data, and finally
pass it into iommu_probe_device_fwspec() which will load it into
dev->iommu under a lock.

Move the actual call to ops->of_xlate into the core code under
iommu_fwspec_of_xlate().

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c    | 29 ++++++++++++++
 drivers/iommu/of_iommu.c | 82 +++++++++++++++++-----------------------
 include/linux/iommu.h    |  3 ++
 3 files changed, 67 insertions(+), 47 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 36561c9fbf6859..ad2963d69a0538 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2990,6 +2990,35 @@ static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
 	return 0;
 }
 
+int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
+			  struct fwnode_handle *iommu_fwnode,
+			  struct of_phandle_args *iommu_spec)
+{
+	int ret;
+
+	ret = iommu_fwspec_assign_iommu(fwspec, dev, iommu_fwnode);
+	if (ret)
+		return ret;
+
+	if (!fwspec->ops->of_xlate)
+		return -ENODEV;
+
+	if (!dev_iommu_get(dev))
+		return -ENOMEM;
+
+	/*
+	 * ops->of_xlate() requires the fwspec to be passed through dev->iommu,
+	 * set it temporarily.
+	 */
+	if (dev->iommu->fwspec && dev->iommu->fwspec != fwspec)
+		iommu_fwspec_dealloc(dev->iommu->fwspec);
+	dev->iommu->fwspec = fwspec;
+	ret = fwspec->ops->of_xlate(dev, iommu_spec);
+	if (dev->iommu->fwspec == fwspec)
+		dev->iommu->fwspec = NULL;
+	return ret;
+}
+
 struct iommu_fwspec *iommu_fwspec_alloc(void)
 {
 	struct iommu_fwspec *fwspec;
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 4f77495a2543ea..b232a6909e0d45 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -19,40 +19,19 @@
 
 #define NO_IOMMU	-ENODEV
 
-static int of_iommu_xlate(struct device *dev,
+static int of_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 			  struct of_phandle_args *iommu_spec)
 {
-	const struct iommu_ops *ops;
-	struct fwnode_handle *fwnode = &iommu_spec->np->fwnode;
-	int ret;
-
-	ops = iommu_ops_from_fwnode(fwnode);
-	if ((ops && !ops->of_xlate) ||
-	    !of_device_is_available(iommu_spec->np))
+	if (!of_device_is_available(iommu_spec->np))
 		return NO_IOMMU;
 
-	ret = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
-	if (ret)
-		return ret;
-	/*
-	 * The otherwise-empty fwspec handily serves to indicate the specific
-	 * IOMMU device we're waiting for, which will be useful if we ever get
-	 * a proper probe-ordering dependency mechanism in future.
-	 */
-	if (!ops)
-		return driver_deferred_probe_check_state(dev);
-
-	if (!try_module_get(ops->owner))
-		return -ENODEV;
-
-	ret = ops->of_xlate(dev, iommu_spec);
-	module_put(ops->owner);
-	return ret;
+	return iommu_fwspec_of_xlate(fwspec, dev, &iommu_spec->np->fwnode,
+				     iommu_spec);
 }
 
-static int of_iommu_configure_dev_id(struct device_node *master_np,
-				     struct device *dev,
-				     const u32 *id)
+static int of_iommu_configure_dev_id(struct iommu_fwspec *fwspec,
+				     struct device_node *master_np,
+				     struct device *dev, const u32 *id)
 {
 	struct of_phandle_args iommu_spec = { .args_count = 1 };
 	int err;
@@ -63,12 +42,13 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
 	if (err)
 		return err == -ENODEV ? NO_IOMMU : err;
 
-	err = of_iommu_xlate(dev, &iommu_spec);
+	err = of_iommu_xlate(fwspec, dev, &iommu_spec);
 	of_node_put(iommu_spec.np);
 	return err;
 }
 
-static int of_iommu_configure_dev(struct device_node *master_np,
+static int of_iommu_configure_dev(struct iommu_fwspec *fwspec,
+				  struct device_node *master_np,
 				  struct device *dev)
 {
 	struct of_phandle_args iommu_spec;
@@ -77,7 +57,7 @@ static int of_iommu_configure_dev(struct device_node *master_np,
 	while (!of_parse_phandle_with_args(master_np, "iommus",
 					   "#iommu-cells",
 					   idx, &iommu_spec)) {
-		err = of_iommu_xlate(dev, &iommu_spec);
+		err = of_iommu_xlate(fwspec, dev, &iommu_spec);
 		of_node_put(iommu_spec.np);
 		idx++;
 		if (err)
@@ -90,6 +70,7 @@ static int of_iommu_configure_dev(struct device_node *master_np,
 struct of_pci_iommu_alias_info {
 	struct device *dev;
 	struct device_node *np;
+	struct iommu_fwspec *fwspec;
 };
 
 static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
@@ -97,14 +78,16 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
 	struct of_pci_iommu_alias_info *info = data;
 	u32 input_id = alias;
 
-	return of_iommu_configure_dev_id(info->np, info->dev, &input_id);
+	return of_iommu_configure_dev_id(info->fwspec, info->np, info->dev,
+					 &input_id);
 }
 
-static int of_iommu_configure_device(struct device_node *master_np,
+static int of_iommu_configure_device(struct iommu_fwspec *fwspec,
+				     struct device_node *master_np,
 				     struct device *dev, const u32 *id)
 {
-	return (id) ? of_iommu_configure_dev_id(master_np, dev, id) :
-		      of_iommu_configure_dev(master_np, dev);
+	return (id) ? of_iommu_configure_dev_id(fwspec, master_np, dev, id) :
+		      of_iommu_configure_dev(fwspec, master_np, dev);
 }
 
 /*
@@ -117,19 +100,15 @@ static int of_iommu_configure_device(struct device_node *master_np,
 int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		       const u32 *id)
 {
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct iommu_fwspec *fwspec;
 	int err;
 
 	if (!master_np)
 		return -ENODEV;
 
-	if (fwspec) {
-		if (fwspec->ops)
-			return 0;
-
-		/* In the deferred case, start again from scratch */
-		iommu_fwspec_free(dev);
-	}
+	fwspec = iommu_fwspec_alloc();
+	if (IS_ERR(fwspec))
+		return PTR_ERR(fwspec);
 
 	/*
 	 * We don't currently walk up the tree looking for a parent IOMMU.
@@ -140,27 +119,36 @@ int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		struct of_pci_iommu_alias_info info = {
 			.dev = dev,
 			.np = master_np,
+			.fwspec = fwspec,
 		};
 
 		pci_request_acs();
 		err = pci_for_each_dma_alias(to_pci_dev(dev),
 					     of_pci_iommu_init, &info);
 	} else {
-		err = of_iommu_configure_device(master_np, dev, id);
+		err = of_iommu_configure_device(fwspec, master_np, dev, id);
 	}
 
 	if (err == -ENODEV || err == -EPROBE_DEFER)
-		return err;
+		goto err_free;
 	if (err)
 		goto err_log;
 
-	err = iommu_probe_device(dev);
-	if (err)
+	err = iommu_probe_device_fwspec(dev, fwspec);
+	if (err) {
+		/*
+		 * Ownership for fwspec always passes into
+		 * iommu_probe_device_fwspec()
+		 */
+		fwspec = NULL;
 		goto err_log;
+	}
 	return 0;
 
 err_log:
 	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+err_free:
+	iommu_fwspec_dealloc(fwspec);
 	return err;
 }
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 531382d692d71a..2644c61b572b8f 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -685,6 +685,9 @@ struct iommu_sva {
 
 struct iommu_fwspec *iommu_fwspec_alloc(void);
 void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
+int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
+			  struct fwnode_handle *iommu_fwnode,
+			  struct of_phandle_args *iommu_spec);
 
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 08/17] of: Do not use dev->iommu within of_iommu_configure()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This call chain is using dev->iommu->fwspec to pass around the fwspec
between the three parts (of_iommu_configure(), of_iommu_xlate(),
iommu_probe_device()).

However there is no locking around the accesses to dev->iommu, so this is
all racy.

Allocate a clean, local, fwspec at the start of of_iommu_configure(), pass
it through all functions on the stack to fill it with data, and finally
pass it into iommu_probe_device_fwspec() which will load it into
dev->iommu under a lock.

Move the actual call to ops->of_xlate into the core code under
iommu_fwspec_of_xlate().

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c    | 29 ++++++++++++++
 drivers/iommu/of_iommu.c | 82 +++++++++++++++++-----------------------
 include/linux/iommu.h    |  3 ++
 3 files changed, 67 insertions(+), 47 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 36561c9fbf6859..ad2963d69a0538 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2990,6 +2990,35 @@ static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
 	return 0;
 }
 
+int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
+			  struct fwnode_handle *iommu_fwnode,
+			  struct of_phandle_args *iommu_spec)
+{
+	int ret;
+
+	ret = iommu_fwspec_assign_iommu(fwspec, dev, iommu_fwnode);
+	if (ret)
+		return ret;
+
+	if (!fwspec->ops->of_xlate)
+		return -ENODEV;
+
+	if (!dev_iommu_get(dev))
+		return -ENOMEM;
+
+	/*
+	 * ops->of_xlate() requires the fwspec to be passed through dev->iommu,
+	 * set it temporarily.
+	 */
+	if (dev->iommu->fwspec && dev->iommu->fwspec != fwspec)
+		iommu_fwspec_dealloc(dev->iommu->fwspec);
+	dev->iommu->fwspec = fwspec;
+	ret = fwspec->ops->of_xlate(dev, iommu_spec);
+	if (dev->iommu->fwspec == fwspec)
+		dev->iommu->fwspec = NULL;
+	return ret;
+}
+
 struct iommu_fwspec *iommu_fwspec_alloc(void)
 {
 	struct iommu_fwspec *fwspec;
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 4f77495a2543ea..b232a6909e0d45 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -19,40 +19,19 @@
 
 #define NO_IOMMU	-ENODEV
 
-static int of_iommu_xlate(struct device *dev,
+static int of_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 			  struct of_phandle_args *iommu_spec)
 {
-	const struct iommu_ops *ops;
-	struct fwnode_handle *fwnode = &iommu_spec->np->fwnode;
-	int ret;
-
-	ops = iommu_ops_from_fwnode(fwnode);
-	if ((ops && !ops->of_xlate) ||
-	    !of_device_is_available(iommu_spec->np))
+	if (!of_device_is_available(iommu_spec->np))
 		return NO_IOMMU;
 
-	ret = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
-	if (ret)
-		return ret;
-	/*
-	 * The otherwise-empty fwspec handily serves to indicate the specific
-	 * IOMMU device we're waiting for, which will be useful if we ever get
-	 * a proper probe-ordering dependency mechanism in future.
-	 */
-	if (!ops)
-		return driver_deferred_probe_check_state(dev);
-
-	if (!try_module_get(ops->owner))
-		return -ENODEV;
-
-	ret = ops->of_xlate(dev, iommu_spec);
-	module_put(ops->owner);
-	return ret;
+	return iommu_fwspec_of_xlate(fwspec, dev, &iommu_spec->np->fwnode,
+				     iommu_spec);
 }
 
-static int of_iommu_configure_dev_id(struct device_node *master_np,
-				     struct device *dev,
-				     const u32 *id)
+static int of_iommu_configure_dev_id(struct iommu_fwspec *fwspec,
+				     struct device_node *master_np,
+				     struct device *dev, const u32 *id)
 {
 	struct of_phandle_args iommu_spec = { .args_count = 1 };
 	int err;
@@ -63,12 +42,13 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
 	if (err)
 		return err == -ENODEV ? NO_IOMMU : err;
 
-	err = of_iommu_xlate(dev, &iommu_spec);
+	err = of_iommu_xlate(fwspec, dev, &iommu_spec);
 	of_node_put(iommu_spec.np);
 	return err;
 }
 
-static int of_iommu_configure_dev(struct device_node *master_np,
+static int of_iommu_configure_dev(struct iommu_fwspec *fwspec,
+				  struct device_node *master_np,
 				  struct device *dev)
 {
 	struct of_phandle_args iommu_spec;
@@ -77,7 +57,7 @@ static int of_iommu_configure_dev(struct device_node *master_np,
 	while (!of_parse_phandle_with_args(master_np, "iommus",
 					   "#iommu-cells",
 					   idx, &iommu_spec)) {
-		err = of_iommu_xlate(dev, &iommu_spec);
+		err = of_iommu_xlate(fwspec, dev, &iommu_spec);
 		of_node_put(iommu_spec.np);
 		idx++;
 		if (err)
@@ -90,6 +70,7 @@ static int of_iommu_configure_dev(struct device_node *master_np,
 struct of_pci_iommu_alias_info {
 	struct device *dev;
 	struct device_node *np;
+	struct iommu_fwspec *fwspec;
 };
 
 static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
@@ -97,14 +78,16 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
 	struct of_pci_iommu_alias_info *info = data;
 	u32 input_id = alias;
 
-	return of_iommu_configure_dev_id(info->np, info->dev, &input_id);
+	return of_iommu_configure_dev_id(info->fwspec, info->np, info->dev,
+					 &input_id);
 }
 
-static int of_iommu_configure_device(struct device_node *master_np,
+static int of_iommu_configure_device(struct iommu_fwspec *fwspec,
+				     struct device_node *master_np,
 				     struct device *dev, const u32 *id)
 {
-	return (id) ? of_iommu_configure_dev_id(master_np, dev, id) :
-		      of_iommu_configure_dev(master_np, dev);
+	return (id) ? of_iommu_configure_dev_id(fwspec, master_np, dev, id) :
+		      of_iommu_configure_dev(fwspec, master_np, dev);
 }
 
 /*
@@ -117,19 +100,15 @@ static int of_iommu_configure_device(struct device_node *master_np,
 int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		       const u32 *id)
 {
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct iommu_fwspec *fwspec;
 	int err;
 
 	if (!master_np)
 		return -ENODEV;
 
-	if (fwspec) {
-		if (fwspec->ops)
-			return 0;
-
-		/* In the deferred case, start again from scratch */
-		iommu_fwspec_free(dev);
-	}
+	fwspec = iommu_fwspec_alloc();
+	if (IS_ERR(fwspec))
+		return PTR_ERR(fwspec);
 
 	/*
 	 * We don't currently walk up the tree looking for a parent IOMMU.
@@ -140,27 +119,36 @@ int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		struct of_pci_iommu_alias_info info = {
 			.dev = dev,
 			.np = master_np,
+			.fwspec = fwspec,
 		};
 
 		pci_request_acs();
 		err = pci_for_each_dma_alias(to_pci_dev(dev),
 					     of_pci_iommu_init, &info);
 	} else {
-		err = of_iommu_configure_device(master_np, dev, id);
+		err = of_iommu_configure_device(fwspec, master_np, dev, id);
 	}
 
 	if (err == -ENODEV || err == -EPROBE_DEFER)
-		return err;
+		goto err_free;
 	if (err)
 		goto err_log;
 
-	err = iommu_probe_device(dev);
-	if (err)
+	err = iommu_probe_device_fwspec(dev, fwspec);
+	if (err) {
+		/*
+		 * Ownership for fwspec always passes into
+		 * iommu_probe_device_fwspec()
+		 */
+		fwspec = NULL;
 		goto err_log;
+	}
 	return 0;
 
 err_log:
 	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+err_free:
+	iommu_fwspec_dealloc(fwspec);
 	return err;
 }
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 531382d692d71a..2644c61b572b8f 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -685,6 +685,9 @@ struct iommu_sva {
 
 struct iommu_fwspec *iommu_fwspec_alloc(void);
 void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
+int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
+			  struct fwnode_handle *iommu_fwnode,
+			  struct of_phandle_args *iommu_spec);
 
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 08/17] of: Do not use dev->iommu within of_iommu_configure()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This call chain is using dev->iommu->fwspec to pass around the fwspec
between the three parts (of_iommu_configure(), of_iommu_xlate(),
iommu_probe_device()).

However there is no locking around the accesses to dev->iommu, so this is
all racy.

Allocate a clean, local, fwspec at the start of of_iommu_configure(), pass
it through all functions on the stack to fill it with data, and finally
pass it into iommu_probe_device_fwspec() which will load it into
dev->iommu under a lock.

Move the actual call to ops->of_xlate into the core code under
iommu_fwspec_of_xlate().

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c    | 29 ++++++++++++++
 drivers/iommu/of_iommu.c | 82 +++++++++++++++++-----------------------
 include/linux/iommu.h    |  3 ++
 3 files changed, 67 insertions(+), 47 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 36561c9fbf6859..ad2963d69a0538 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2990,6 +2990,35 @@ static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
 	return 0;
 }
 
+int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
+			  struct fwnode_handle *iommu_fwnode,
+			  struct of_phandle_args *iommu_spec)
+{
+	int ret;
+
+	ret = iommu_fwspec_assign_iommu(fwspec, dev, iommu_fwnode);
+	if (ret)
+		return ret;
+
+	if (!fwspec->ops->of_xlate)
+		return -ENODEV;
+
+	if (!dev_iommu_get(dev))
+		return -ENOMEM;
+
+	/*
+	 * ops->of_xlate() requires the fwspec to be passed through dev->iommu,
+	 * set it temporarily.
+	 */
+	if (dev->iommu->fwspec && dev->iommu->fwspec != fwspec)
+		iommu_fwspec_dealloc(dev->iommu->fwspec);
+	dev->iommu->fwspec = fwspec;
+	ret = fwspec->ops->of_xlate(dev, iommu_spec);
+	if (dev->iommu->fwspec == fwspec)
+		dev->iommu->fwspec = NULL;
+	return ret;
+}
+
 struct iommu_fwspec *iommu_fwspec_alloc(void)
 {
 	struct iommu_fwspec *fwspec;
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 4f77495a2543ea..b232a6909e0d45 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -19,40 +19,19 @@
 
 #define NO_IOMMU	-ENODEV
 
-static int of_iommu_xlate(struct device *dev,
+static int of_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 			  struct of_phandle_args *iommu_spec)
 {
-	const struct iommu_ops *ops;
-	struct fwnode_handle *fwnode = &iommu_spec->np->fwnode;
-	int ret;
-
-	ops = iommu_ops_from_fwnode(fwnode);
-	if ((ops && !ops->of_xlate) ||
-	    !of_device_is_available(iommu_spec->np))
+	if (!of_device_is_available(iommu_spec->np))
 		return NO_IOMMU;
 
-	ret = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
-	if (ret)
-		return ret;
-	/*
-	 * The otherwise-empty fwspec handily serves to indicate the specific
-	 * IOMMU device we're waiting for, which will be useful if we ever get
-	 * a proper probe-ordering dependency mechanism in future.
-	 */
-	if (!ops)
-		return driver_deferred_probe_check_state(dev);
-
-	if (!try_module_get(ops->owner))
-		return -ENODEV;
-
-	ret = ops->of_xlate(dev, iommu_spec);
-	module_put(ops->owner);
-	return ret;
+	return iommu_fwspec_of_xlate(fwspec, dev, &iommu_spec->np->fwnode,
+				     iommu_spec);
 }
 
-static int of_iommu_configure_dev_id(struct device_node *master_np,
-				     struct device *dev,
-				     const u32 *id)
+static int of_iommu_configure_dev_id(struct iommu_fwspec *fwspec,
+				     struct device_node *master_np,
+				     struct device *dev, const u32 *id)
 {
 	struct of_phandle_args iommu_spec = { .args_count = 1 };
 	int err;
@@ -63,12 +42,13 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
 	if (err)
 		return err == -ENODEV ? NO_IOMMU : err;
 
-	err = of_iommu_xlate(dev, &iommu_spec);
+	err = of_iommu_xlate(fwspec, dev, &iommu_spec);
 	of_node_put(iommu_spec.np);
 	return err;
 }
 
-static int of_iommu_configure_dev(struct device_node *master_np,
+static int of_iommu_configure_dev(struct iommu_fwspec *fwspec,
+				  struct device_node *master_np,
 				  struct device *dev)
 {
 	struct of_phandle_args iommu_spec;
@@ -77,7 +57,7 @@ static int of_iommu_configure_dev(struct device_node *master_np,
 	while (!of_parse_phandle_with_args(master_np, "iommus",
 					   "#iommu-cells",
 					   idx, &iommu_spec)) {
-		err = of_iommu_xlate(dev, &iommu_spec);
+		err = of_iommu_xlate(fwspec, dev, &iommu_spec);
 		of_node_put(iommu_spec.np);
 		idx++;
 		if (err)
@@ -90,6 +70,7 @@ static int of_iommu_configure_dev(struct device_node *master_np,
 struct of_pci_iommu_alias_info {
 	struct device *dev;
 	struct device_node *np;
+	struct iommu_fwspec *fwspec;
 };
 
 static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
@@ -97,14 +78,16 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
 	struct of_pci_iommu_alias_info *info = data;
 	u32 input_id = alias;
 
-	return of_iommu_configure_dev_id(info->np, info->dev, &input_id);
+	return of_iommu_configure_dev_id(info->fwspec, info->np, info->dev,
+					 &input_id);
 }
 
-static int of_iommu_configure_device(struct device_node *master_np,
+static int of_iommu_configure_device(struct iommu_fwspec *fwspec,
+				     struct device_node *master_np,
 				     struct device *dev, const u32 *id)
 {
-	return (id) ? of_iommu_configure_dev_id(master_np, dev, id) :
-		      of_iommu_configure_dev(master_np, dev);
+	return (id) ? of_iommu_configure_dev_id(fwspec, master_np, dev, id) :
+		      of_iommu_configure_dev(fwspec, master_np, dev);
 }
 
 /*
@@ -117,19 +100,15 @@ static int of_iommu_configure_device(struct device_node *master_np,
 int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		       const u32 *id)
 {
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct iommu_fwspec *fwspec;
 	int err;
 
 	if (!master_np)
 		return -ENODEV;
 
-	if (fwspec) {
-		if (fwspec->ops)
-			return 0;
-
-		/* In the deferred case, start again from scratch */
-		iommu_fwspec_free(dev);
-	}
+	fwspec = iommu_fwspec_alloc();
+	if (IS_ERR(fwspec))
+		return PTR_ERR(fwspec);
 
 	/*
 	 * We don't currently walk up the tree looking for a parent IOMMU.
@@ -140,27 +119,36 @@ int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		struct of_pci_iommu_alias_info info = {
 			.dev = dev,
 			.np = master_np,
+			.fwspec = fwspec,
 		};
 
 		pci_request_acs();
 		err = pci_for_each_dma_alias(to_pci_dev(dev),
 					     of_pci_iommu_init, &info);
 	} else {
-		err = of_iommu_configure_device(master_np, dev, id);
+		err = of_iommu_configure_device(fwspec, master_np, dev, id);
 	}
 
 	if (err == -ENODEV || err == -EPROBE_DEFER)
-		return err;
+		goto err_free;
 	if (err)
 		goto err_log;
 
-	err = iommu_probe_device(dev);
-	if (err)
+	err = iommu_probe_device_fwspec(dev, fwspec);
+	if (err) {
+		/*
+		 * Ownership for fwspec always passes into
+		 * iommu_probe_device_fwspec()
+		 */
+		fwspec = NULL;
 		goto err_log;
+	}
 	return 0;
 
 err_log:
 	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+err_free:
+	iommu_fwspec_dealloc(fwspec);
 	return err;
 }
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 531382d692d71a..2644c61b572b8f 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -685,6 +685,9 @@ struct iommu_sva {
 
 struct iommu_fwspec *iommu_fwspec_alloc(void);
 void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
+int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
+			  struct fwnode_handle *iommu_fwnode,
+			  struct of_phandle_args *iommu_spec);
 
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 08/17] of: Do not use dev->iommu within of_iommu_configure()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This call chain is using dev->iommu->fwspec to pass around the fwspec
between the three parts (of_iommu_configure(), of_iommu_xlate(),
iommu_probe_device()).

However there is no locking around the accesses to dev->iommu, so this is
all racy.

Allocate a clean, local, fwspec at the start of of_iommu_configure(), pass
it through all functions on the stack to fill it with data, and finally
pass it into iommu_probe_device_fwspec() which will load it into
dev->iommu under a lock.

Move the actual call to ops->of_xlate into the core code under
iommu_fwspec_of_xlate().

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c    | 29 ++++++++++++++
 drivers/iommu/of_iommu.c | 82 +++++++++++++++++-----------------------
 include/linux/iommu.h    |  3 ++
 3 files changed, 67 insertions(+), 47 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 36561c9fbf6859..ad2963d69a0538 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2990,6 +2990,35 @@ static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
 	return 0;
 }
 
+int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
+			  struct fwnode_handle *iommu_fwnode,
+			  struct of_phandle_args *iommu_spec)
+{
+	int ret;
+
+	ret = iommu_fwspec_assign_iommu(fwspec, dev, iommu_fwnode);
+	if (ret)
+		return ret;
+
+	if (!fwspec->ops->of_xlate)
+		return -ENODEV;
+
+	if (!dev_iommu_get(dev))
+		return -ENOMEM;
+
+	/*
+	 * ops->of_xlate() requires the fwspec to be passed through dev->iommu,
+	 * set it temporarily.
+	 */
+	if (dev->iommu->fwspec && dev->iommu->fwspec != fwspec)
+		iommu_fwspec_dealloc(dev->iommu->fwspec);
+	dev->iommu->fwspec = fwspec;
+	ret = fwspec->ops->of_xlate(dev, iommu_spec);
+	if (dev->iommu->fwspec == fwspec)
+		dev->iommu->fwspec = NULL;
+	return ret;
+}
+
 struct iommu_fwspec *iommu_fwspec_alloc(void)
 {
 	struct iommu_fwspec *fwspec;
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 4f77495a2543ea..b232a6909e0d45 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -19,40 +19,19 @@
 
 #define NO_IOMMU	-ENODEV
 
-static int of_iommu_xlate(struct device *dev,
+static int of_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 			  struct of_phandle_args *iommu_spec)
 {
-	const struct iommu_ops *ops;
-	struct fwnode_handle *fwnode = &iommu_spec->np->fwnode;
-	int ret;
-
-	ops = iommu_ops_from_fwnode(fwnode);
-	if ((ops && !ops->of_xlate) ||
-	    !of_device_is_available(iommu_spec->np))
+	if (!of_device_is_available(iommu_spec->np))
 		return NO_IOMMU;
 
-	ret = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
-	if (ret)
-		return ret;
-	/*
-	 * The otherwise-empty fwspec handily serves to indicate the specific
-	 * IOMMU device we're waiting for, which will be useful if we ever get
-	 * a proper probe-ordering dependency mechanism in future.
-	 */
-	if (!ops)
-		return driver_deferred_probe_check_state(dev);
-
-	if (!try_module_get(ops->owner))
-		return -ENODEV;
-
-	ret = ops->of_xlate(dev, iommu_spec);
-	module_put(ops->owner);
-	return ret;
+	return iommu_fwspec_of_xlate(fwspec, dev, &iommu_spec->np->fwnode,
+				     iommu_spec);
 }
 
-static int of_iommu_configure_dev_id(struct device_node *master_np,
-				     struct device *dev,
-				     const u32 *id)
+static int of_iommu_configure_dev_id(struct iommu_fwspec *fwspec,
+				     struct device_node *master_np,
+				     struct device *dev, const u32 *id)
 {
 	struct of_phandle_args iommu_spec = { .args_count = 1 };
 	int err;
@@ -63,12 +42,13 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
 	if (err)
 		return err == -ENODEV ? NO_IOMMU : err;
 
-	err = of_iommu_xlate(dev, &iommu_spec);
+	err = of_iommu_xlate(fwspec, dev, &iommu_spec);
 	of_node_put(iommu_spec.np);
 	return err;
 }
 
-static int of_iommu_configure_dev(struct device_node *master_np,
+static int of_iommu_configure_dev(struct iommu_fwspec *fwspec,
+				  struct device_node *master_np,
 				  struct device *dev)
 {
 	struct of_phandle_args iommu_spec;
@@ -77,7 +57,7 @@ static int of_iommu_configure_dev(struct device_node *master_np,
 	while (!of_parse_phandle_with_args(master_np, "iommus",
 					   "#iommu-cells",
 					   idx, &iommu_spec)) {
-		err = of_iommu_xlate(dev, &iommu_spec);
+		err = of_iommu_xlate(fwspec, dev, &iommu_spec);
 		of_node_put(iommu_spec.np);
 		idx++;
 		if (err)
@@ -90,6 +70,7 @@ static int of_iommu_configure_dev(struct device_node *master_np,
 struct of_pci_iommu_alias_info {
 	struct device *dev;
 	struct device_node *np;
+	struct iommu_fwspec *fwspec;
 };
 
 static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
@@ -97,14 +78,16 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
 	struct of_pci_iommu_alias_info *info = data;
 	u32 input_id = alias;
 
-	return of_iommu_configure_dev_id(info->np, info->dev, &input_id);
+	return of_iommu_configure_dev_id(info->fwspec, info->np, info->dev,
+					 &input_id);
 }
 
-static int of_iommu_configure_device(struct device_node *master_np,
+static int of_iommu_configure_device(struct iommu_fwspec *fwspec,
+				     struct device_node *master_np,
 				     struct device *dev, const u32 *id)
 {
-	return (id) ? of_iommu_configure_dev_id(master_np, dev, id) :
-		      of_iommu_configure_dev(master_np, dev);
+	return (id) ? of_iommu_configure_dev_id(fwspec, master_np, dev, id) :
+		      of_iommu_configure_dev(fwspec, master_np, dev);
 }
 
 /*
@@ -117,19 +100,15 @@ static int of_iommu_configure_device(struct device_node *master_np,
 int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		       const u32 *id)
 {
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct iommu_fwspec *fwspec;
 	int err;
 
 	if (!master_np)
 		return -ENODEV;
 
-	if (fwspec) {
-		if (fwspec->ops)
-			return 0;
-
-		/* In the deferred case, start again from scratch */
-		iommu_fwspec_free(dev);
-	}
+	fwspec = iommu_fwspec_alloc();
+	if (IS_ERR(fwspec))
+		return PTR_ERR(fwspec);
 
 	/*
 	 * We don't currently walk up the tree looking for a parent IOMMU.
@@ -140,27 +119,36 @@ int of_iommu_configure(struct device *dev, struct device_node *master_np,
 		struct of_pci_iommu_alias_info info = {
 			.dev = dev,
 			.np = master_np,
+			.fwspec = fwspec,
 		};
 
 		pci_request_acs();
 		err = pci_for_each_dma_alias(to_pci_dev(dev),
 					     of_pci_iommu_init, &info);
 	} else {
-		err = of_iommu_configure_device(master_np, dev, id);
+		err = of_iommu_configure_device(fwspec, master_np, dev, id);
 	}
 
 	if (err == -ENODEV || err == -EPROBE_DEFER)
-		return err;
+		goto err_free;
 	if (err)
 		goto err_log;
 
-	err = iommu_probe_device(dev);
-	if (err)
+	err = iommu_probe_device_fwspec(dev, fwspec);
+	if (err) {
+		/*
+		 * Ownership for fwspec always passes into
+		 * iommu_probe_device_fwspec()
+		 */
+		fwspec = NULL;
 		goto err_log;
+	}
 	return 0;
 
 err_log:
 	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+err_free:
+	iommu_fwspec_dealloc(fwspec);
 	return err;
 }
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 531382d692d71a..2644c61b572b8f 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -685,6 +685,9 @@ struct iommu_sva {
 
 struct iommu_fwspec *iommu_fwspec_alloc(void);
 void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
+int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
+			  struct fwnode_handle *iommu_fwnode,
+			  struct of_phandle_args *iommu_spec);
 
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 09/17] iommu: Add iommu_fwspec_append_ids()
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:44   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is a version of iommu_fwspec_add_ids() that takes in the fwspec as an
argument instead of getting it through dev->iommu.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 17 +++++++++++------
 include/linux/iommu.h |  1 +
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ad2963d69a0538..15dbe2d9eb24c2 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3067,15 +3067,10 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_init);
 
-
-int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
+int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids, int num_ids)
 {
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	int i, new_num;
 
-	if (!fwspec)
-		return -EINVAL;
-
 	new_num = fwspec->num_ids + num_ids;
 	if (new_num <= 1) {
 		if (fwspec->ids != &fwspec->single_id)
@@ -3097,6 +3092,16 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 	fwspec->num_ids = new_num;
 	return 0;
 }
+EXPORT_SYMBOL_GPL(iommu_fwspec_append_ids);
+
+int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
+{
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+
+	if (!fwspec)
+		return -EINVAL;
+	return iommu_fwspec_append_ids(fwspec, ids, num_ids);
+}
 EXPORT_SYMBOL_GPL(iommu_fwspec_add_ids);
 
 /*
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 2644c61b572b8f..c5a5e2b5e2cc2a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -700,6 +700,7 @@ static inline void iommu_fwspec_free(struct device *dev)
 }
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
 const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
+int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids, int num_ids);
 
 static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
 {
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 09/17] iommu: Add iommu_fwspec_append_ids()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is a version of iommu_fwspec_add_ids() that takes in the fwspec as an
argument instead of getting it through dev->iommu.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 17 +++++++++++------
 include/linux/iommu.h |  1 +
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ad2963d69a0538..15dbe2d9eb24c2 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3067,15 +3067,10 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_init);
 
-
-int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
+int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids, int num_ids)
 {
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	int i, new_num;
 
-	if (!fwspec)
-		return -EINVAL;
-
 	new_num = fwspec->num_ids + num_ids;
 	if (new_num <= 1) {
 		if (fwspec->ids != &fwspec->single_id)
@@ -3097,6 +3092,16 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 	fwspec->num_ids = new_num;
 	return 0;
 }
+EXPORT_SYMBOL_GPL(iommu_fwspec_append_ids);
+
+int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
+{
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+
+	if (!fwspec)
+		return -EINVAL;
+	return iommu_fwspec_append_ids(fwspec, ids, num_ids);
+}
 EXPORT_SYMBOL_GPL(iommu_fwspec_add_ids);
 
 /*
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 2644c61b572b8f..c5a5e2b5e2cc2a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -700,6 +700,7 @@ static inline void iommu_fwspec_free(struct device *dev)
 }
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
 const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
+int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids, int num_ids);
 
 static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
 {
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 09/17] iommu: Add iommu_fwspec_append_ids()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is a version of iommu_fwspec_add_ids() that takes in the fwspec as an
argument instead of getting it through dev->iommu.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 17 +++++++++++------
 include/linux/iommu.h |  1 +
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ad2963d69a0538..15dbe2d9eb24c2 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3067,15 +3067,10 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_init);
 
-
-int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
+int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids, int num_ids)
 {
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	int i, new_num;
 
-	if (!fwspec)
-		return -EINVAL;
-
 	new_num = fwspec->num_ids + num_ids;
 	if (new_num <= 1) {
 		if (fwspec->ids != &fwspec->single_id)
@@ -3097,6 +3092,16 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 	fwspec->num_ids = new_num;
 	return 0;
 }
+EXPORT_SYMBOL_GPL(iommu_fwspec_append_ids);
+
+int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
+{
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+
+	if (!fwspec)
+		return -EINVAL;
+	return iommu_fwspec_append_ids(fwspec, ids, num_ids);
+}
 EXPORT_SYMBOL_GPL(iommu_fwspec_add_ids);
 
 /*
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 2644c61b572b8f..c5a5e2b5e2cc2a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -700,6 +700,7 @@ static inline void iommu_fwspec_free(struct device *dev)
 }
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
 const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
+int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids, int num_ids);
 
 static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
 {
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 09/17] iommu: Add iommu_fwspec_append_ids()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is a version of iommu_fwspec_add_ids() that takes in the fwspec as an
argument instead of getting it through dev->iommu.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 17 +++++++++++------
 include/linux/iommu.h |  1 +
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ad2963d69a0538..15dbe2d9eb24c2 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3067,15 +3067,10 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_init);
 
-
-int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
+int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids, int num_ids)
 {
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	int i, new_num;
 
-	if (!fwspec)
-		return -EINVAL;
-
 	new_num = fwspec->num_ids + num_ids;
 	if (new_num <= 1) {
 		if (fwspec->ids != &fwspec->single_id)
@@ -3097,6 +3092,16 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 	fwspec->num_ids = new_num;
 	return 0;
 }
+EXPORT_SYMBOL_GPL(iommu_fwspec_append_ids);
+
+int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
+{
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+
+	if (!fwspec)
+		return -EINVAL;
+	return iommu_fwspec_append_ids(fwspec, ids, num_ids);
+}
 EXPORT_SYMBOL_GPL(iommu_fwspec_add_ids);
 
 /*
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 2644c61b572b8f..c5a5e2b5e2cc2a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -700,6 +700,7 @@ static inline void iommu_fwspec_free(struct device *dev)
 }
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
 const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
+int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids, int num_ids);
 
 static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
 {
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 09/17] iommu: Add iommu_fwspec_append_ids()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is a version of iommu_fwspec_add_ids() that takes in the fwspec as an
argument instead of getting it through dev->iommu.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 17 +++++++++++------
 include/linux/iommu.h |  1 +
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ad2963d69a0538..15dbe2d9eb24c2 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3067,15 +3067,10 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_init);
 
-
-int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
+int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids, int num_ids)
 {
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	int i, new_num;
 
-	if (!fwspec)
-		return -EINVAL;
-
 	new_num = fwspec->num_ids + num_ids;
 	if (new_num <= 1) {
 		if (fwspec->ids != &fwspec->single_id)
@@ -3097,6 +3092,16 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 	fwspec->num_ids = new_num;
 	return 0;
 }
+EXPORT_SYMBOL_GPL(iommu_fwspec_append_ids);
+
+int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
+{
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+
+	if (!fwspec)
+		return -EINVAL;
+	return iommu_fwspec_append_ids(fwspec, ids, num_ids);
+}
 EXPORT_SYMBOL_GPL(iommu_fwspec_add_ids);
 
 /*
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 2644c61b572b8f..c5a5e2b5e2cc2a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -700,6 +700,7 @@ static inline void iommu_fwspec_free(struct device *dev)
 }
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
 const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
+int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids, int num_ids);
 
 static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
 {
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:44   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This call chain is using dev->iommu->fwspec to pass around the fwspec
between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
iommu_probe_device()).

However there is no locking around the accesses to dev->iommu, so this is
all racy.

Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
pass it through all functions on the stack to fill it with data, and
finally pass it into iommu_probe_device_fwspec() which will load it into
dev->iommu under a lock.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/acpi/arm64/iort.c | 39 ++++++++---------
 drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
 drivers/acpi/viot.c       | 44 ++++++++++---------
 drivers/iommu/iommu.c     |  5 +--
 include/acpi/acpi_bus.h   |  8 ++--
 include/linux/acpi_iort.h |  3 +-
 include/linux/acpi_viot.h |  5 ++-
 include/linux/iommu.h     |  2 +
 8 files changed, 97 insertions(+), 98 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 6496ff5a6ba20d..accd01dcfe93f5 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
 	return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
 }
 
-static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
-			    u32 streamid)
+static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
+			    struct acpi_iort_node *node, u32 streamid)
 {
-	const struct iommu_ops *ops;
 	struct fwnode_handle *iort_fwnode;
 
 	if (!node)
@@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
 	 * in the kernel or not, defer the IOMMU configuration
 	 * or just abort it.
 	 */
-	ops = iommu_ops_from_fwnode(iort_fwnode);
-	if (!ops)
-		return iort_iommu_driver_enabled(node->type) ?
-		       -EPROBE_DEFER : -ENODEV;
-
-	return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
+	return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
+				      iort_iommu_driver_enabled(node->type));
 }
 
 struct iort_pci_alias_info {
 	struct device *dev;
 	struct acpi_iort_node *node;
+	struct iommu_fwspec *fwspec;
 };
 
 static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
@@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
 
 	parent = iort_node_map_id(info->node, alias, &streamid,
 				  IORT_IOMMU_TYPE);
-	return iort_iommu_xlate(info->dev, parent, streamid);
+	return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
 }
 
 static void iort_named_component_init(struct device *dev,
@@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
 		dev_warn(dev, "Could not add device properties\n");
 }
 
-static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
+static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
+			     struct acpi_iort_node *node)
 {
 	struct acpi_iort_node *parent;
 	int err = -ENODEV, i = 0;
@@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
 						   i++);
 
 		if (parent)
-			err = iort_iommu_xlate(dev, parent, streamid);
+			err = iort_iommu_xlate(fwspec, dev, parent, streamid);
 	} while (parent && !err);
 
 	return err;
 }
 
-static int iort_nc_iommu_map_id(struct device *dev,
+static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
 				struct acpi_iort_node *node,
 				const u32 *in_id)
 {
@@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
 
 	parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
 	if (parent)
-		return iort_iommu_xlate(dev, parent, streamid);
+		return iort_iommu_xlate(fwspec, dev, parent, streamid);
 
 	return -ENODEV;
 }
@@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
  *
  * Returns: 0 on success, <0 on failure
  */
-int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
+int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
+			    const u32 *id_in)
 {
 	struct acpi_iort_node *node;
 	int err = -ENODEV;
 
 	if (dev_is_pci(dev)) {
-		struct iommu_fwspec *fwspec;
 		struct pci_bus *bus = to_pci_dev(dev)->bus;
-		struct iort_pci_alias_info info = { .dev = dev };
+		struct iort_pci_alias_info info = { .dev = dev,
+						    .fwspec = fwspec };
 
 		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
 				      iort_match_node_callback, &bus->dev);
@@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
 		err = pci_for_each_dma_alias(to_pci_dev(dev),
 					     iort_pci_iommu_init, &info);
 
-		fwspec = dev_iommu_fwspec_get(dev);
-		if (fwspec && iort_pci_rc_supports_ats(node))
+		if (iort_pci_rc_supports_ats(node))
 			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
 	} else {
 		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
@@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
 		if (!node)
 			return -ENODEV;
 
-		err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
-			      iort_nc_iommu_map(dev, node);
+		err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
+			      iort_nc_iommu_map(fwspec, dev, node);
 
 		if (!err)
 			iort_named_component_init(dev, node);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index fbabde001a23a2..1e01a8e0316867 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
 }
 
 #ifdef CONFIG_IOMMU_API
-int acpi_iommu_fwspec_init(struct device *dev, u32 id,
-			   struct fwnode_handle *fwnode,
-			   const struct iommu_ops *ops)
+int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
+			   u32 id, struct fwnode_handle *fwnode,
+			   bool iommu_driver_available)
 {
-	int ret = iommu_fwspec_init(dev, fwnode, ops);
+	int ret;
 
-	if (!ret)
-		ret = iommu_fwspec_add_ids(dev, &id, 1);
-
-	return ret;
-}
-
-static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
-{
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-
-	return fwspec ? fwspec->ops : NULL;
+	ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
+	if (ret) {
+		if (ret == -EPROBE_DEFER && !iommu_driver_available)
+			return -ENODEV;
+		return ret;
+	}
+	return iommu_fwspec_append_ids(fwspec, &id, 1);
 }
 
 static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 {
 	int err;
-	const struct iommu_ops *ops;
+	struct iommu_fwspec *fwspec;
 
-	/*
-	 * If we already translated the fwspec there is nothing left to do,
-	 * return the iommu_ops.
-	 */
-	ops = acpi_iommu_fwspec_ops(dev);
-	if (ops)
-		return 0;
+	fwspec = iommu_fwspec_alloc();
+	if (IS_ERR(fwspec))
+		return PTR_ERR(fwspec);
 
-	err = iort_iommu_configure_id(dev, id_in);
-	if (err && err != -EPROBE_DEFER)
-		err = viot_iommu_configure(dev);
+	err = iort_iommu_configure_id(fwspec, dev, id_in);
+	if (err == -ENODEV)
+		err = viot_iommu_configure(fwspec, dev);
+	if (err == -ENODEV || err == -EPROBE_DEFER)
+		goto err_free;
+	if (err)
+		goto err_log;
 
-	/*
-	 * If we have reason to believe the IOMMU driver missed the initial
-	 * iommu_probe_device() call for dev, replay it to get things in order.
-	 */
-	if (!err && dev->bus)
-		err = iommu_probe_device(dev);
-
-	/* Ignore all other errors apart from EPROBE_DEFER */
-	if (err == -EPROBE_DEFER) {
-		return err;
-	} else if (err) {
-		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		return -ENODEV;
+	err = iommu_probe_device_fwspec(dev, fwspec);
+	if (err) {
+		/*
+		 * Ownership for fwspec always passes into
+		 * iommu_probe_device_fwspec()
+		 */
+		fwspec = NULL;
+		goto err_log;
 	}
-	if (!acpi_iommu_fwspec_ops(dev))
-		return -ENODEV;
-	return 0;
+
+err_log:
+	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+err_free:
+	iommu_fwspec_dealloc(fwspec);
+	return err;
 }
 
 #else /* !CONFIG_IOMMU_API */
 
-int acpi_iommu_fwspec_init(struct device *dev, u32 id,
-			   struct fwnode_handle *fwnode,
-			   const struct iommu_ops *ops)
+int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
+			   u32 id, struct fwnode_handle *fwnode,
+			   bool iommu_driver_available)
 {
 	return -ENODEV;
 }
 
-static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
-						       const u32 *id_in)
+static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 {
-	return NULL;
+	return -ENODEV;
 }
 
 #endif /* !CONFIG_IOMMU_API */
diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
index c8025921c129b2..33b511dd202d15 100644
--- a/drivers/acpi/viot.c
+++ b/drivers/acpi/viot.c
@@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
 	acpi_put_table(hdr);
 }
 
-static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
-			       u32 epid)
+static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
+			       struct viot_iommu *viommu, u32 epid)
 {
-	const struct iommu_ops *ops;
-
 	if (!viommu)
 		return -ENODEV;
 
@@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
 	if (device_match_fwnode(dev, viommu->fwnode))
 		return -EINVAL;
 
-	ops = iommu_ops_from_fwnode(viommu->fwnode);
-	if (!ops)
-		return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
-			-EPROBE_DEFER : -ENODEV;
-
-	return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
+	return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
+				      IS_ENABLED(CONFIG_VIRTIO_IOMMU));
 }
 
+struct viot_pci_alias_info {
+	struct device *dev;
+	struct iommu_fwspec *fwspec;
+};
+
 static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
 {
 	u32 epid;
 	struct viot_endpoint *ep;
-	struct device *aliased_dev = data;
+	struct viot_pci_alias_info *info = data;
 	u32 domain_nr = pci_domain_nr(pdev->bus);
 
 	list_for_each_entry(ep, &viot_pci_ranges, list) {
@@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
 			epid = ((domain_nr - ep->segment_start) << 16) +
 				dev_id - ep->bdf_start + ep->endpoint_id;
 
-			return viot_dev_iommu_init(aliased_dev, ep->viommu,
-						   epid);
+			return viot_dev_iommu_init(info->fwspec, info->dev,
+						   ep->viommu, epid);
 		}
 	}
 	return -ENODEV;
 }
 
-static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
+static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
+				    struct platform_device *pdev)
 {
 	struct resource *mem;
 	struct viot_endpoint *ep;
@@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
 
 	list_for_each_entry(ep, &viot_mmio_endpoints, list) {
 		if (ep->address == mem->start)
-			return viot_dev_iommu_init(&pdev->dev, ep->viommu,
-						   ep->endpoint_id);
+			return viot_dev_iommu_init(fwspec, &pdev->dev,
+						   ep->viommu, ep->endpoint_id);
 	}
 	return -ENODEV;
 }
@@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
  *
  * Return: 0 on success, <0 on failure
  */
-int viot_iommu_configure(struct device *dev)
+int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
 {
-	if (dev_is_pci(dev))
+	if (dev_is_pci(dev)) {
+		struct viot_pci_alias_info info = { .dev = dev,
+						    .fwspec = fwspec };
 		return pci_for_each_dma_alias(to_pci_dev(dev),
-					      viot_pci_dev_iommu_init, dev);
+					      viot_pci_dev_iommu_init, &info);
+	}
 	else if (dev_is_platform(dev))
-		return viot_mmio_dev_iommu_init(to_platform_device(dev));
+		return viot_mmio_dev_iommu_init(fwspec,
+						to_platform_device(dev));
 	return -ENODEV;
 }
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 15dbe2d9eb24c2..9cfba9d12d1400 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 	return ops;
 }
 
-static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
-				     struct device *dev,
-				     struct fwnode_handle *iommu_fwnode)
+int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
+			      struct fwnode_handle *iommu_fwnode)
 {
 	const struct iommu_ops *ops;
 
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 254685085c825c..70f97096c776e4 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -12,6 +12,8 @@
 #include <linux/device.h>
 #include <linux/property.h>
 
+struct iommu_fwspec;
+
 /* TBD: Make dynamic */
 #define ACPI_MAX_HANDLES	10
 struct acpi_handle_list {
@@ -625,9 +627,9 @@ struct acpi_pci_root {
 
 bool acpi_dma_supported(const struct acpi_device *adev);
 enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
-int acpi_iommu_fwspec_init(struct device *dev, u32 id,
-			   struct fwnode_handle *fwnode,
-			   const struct iommu_ops *ops);
+int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
+			   u32 id, struct fwnode_handle *fwnode,
+			   bool iommu_driver_available);
 int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
 int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 			   const u32 *input_id);
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 1cb65592c95dd3..80794ec45d1693 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
 		       struct list_head *head);
 /* IOMMU interface */
 int iort_dma_get_ranges(struct device *dev, u64 *size);
-int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
+int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
+			    const u32 *id_in);
 void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
 phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
 #else
diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
index a5a12243156377..f1874cb6d43c09 100644
--- a/include/linux/acpi_viot.h
+++ b/include/linux/acpi_viot.h
@@ -8,11 +8,12 @@
 #ifdef CONFIG_ACPI_VIOT
 void __init acpi_viot_early_init(void);
 void __init acpi_viot_init(void);
-int viot_iommu_configure(struct device *dev);
+int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
 #else
 static inline void acpi_viot_early_init(void) {}
 static inline void acpi_viot_init(void) {}
-static inline int viot_iommu_configure(struct device *dev)
+static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
+				       struct device *dev)
 {
 	return -ENODEV;
 }
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index c5a5e2b5e2cc2a..27e4605d498850 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
 int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 			  struct fwnode_handle *iommu_fwnode,
 			  struct of_phandle_args *iommu_spec);
+int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
+			      struct fwnode_handle *iommu_fwnode);
 
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This call chain is using dev->iommu->fwspec to pass around the fwspec
between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
iommu_probe_device()).

However there is no locking around the accesses to dev->iommu, so this is
all racy.

Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
pass it through all functions on the stack to fill it with data, and
finally pass it into iommu_probe_device_fwspec() which will load it into
dev->iommu under a lock.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/acpi/arm64/iort.c | 39 ++++++++---------
 drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
 drivers/acpi/viot.c       | 44 ++++++++++---------
 drivers/iommu/iommu.c     |  5 +--
 include/acpi/acpi_bus.h   |  8 ++--
 include/linux/acpi_iort.h |  3 +-
 include/linux/acpi_viot.h |  5 ++-
 include/linux/iommu.h     |  2 +
 8 files changed, 97 insertions(+), 98 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 6496ff5a6ba20d..accd01dcfe93f5 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
 	return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
 }
 
-static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
-			    u32 streamid)
+static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
+			    struct acpi_iort_node *node, u32 streamid)
 {
-	const struct iommu_ops *ops;
 	struct fwnode_handle *iort_fwnode;
 
 	if (!node)
@@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
 	 * in the kernel or not, defer the IOMMU configuration
 	 * or just abort it.
 	 */
-	ops = iommu_ops_from_fwnode(iort_fwnode);
-	if (!ops)
-		return iort_iommu_driver_enabled(node->type) ?
-		       -EPROBE_DEFER : -ENODEV;
-
-	return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
+	return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
+				      iort_iommu_driver_enabled(node->type));
 }
 
 struct iort_pci_alias_info {
 	struct device *dev;
 	struct acpi_iort_node *node;
+	struct iommu_fwspec *fwspec;
 };
 
 static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
@@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
 
 	parent = iort_node_map_id(info->node, alias, &streamid,
 				  IORT_IOMMU_TYPE);
-	return iort_iommu_xlate(info->dev, parent, streamid);
+	return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
 }
 
 static void iort_named_component_init(struct device *dev,
@@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
 		dev_warn(dev, "Could not add device properties\n");
 }
 
-static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
+static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
+			     struct acpi_iort_node *node)
 {
 	struct acpi_iort_node *parent;
 	int err = -ENODEV, i = 0;
@@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
 						   i++);
 
 		if (parent)
-			err = iort_iommu_xlate(dev, parent, streamid);
+			err = iort_iommu_xlate(fwspec, dev, parent, streamid);
 	} while (parent && !err);
 
 	return err;
 }
 
-static int iort_nc_iommu_map_id(struct device *dev,
+static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
 				struct acpi_iort_node *node,
 				const u32 *in_id)
 {
@@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
 
 	parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
 	if (parent)
-		return iort_iommu_xlate(dev, parent, streamid);
+		return iort_iommu_xlate(fwspec, dev, parent, streamid);
 
 	return -ENODEV;
 }
@@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
  *
  * Returns: 0 on success, <0 on failure
  */
-int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
+int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
+			    const u32 *id_in)
 {
 	struct acpi_iort_node *node;
 	int err = -ENODEV;
 
 	if (dev_is_pci(dev)) {
-		struct iommu_fwspec *fwspec;
 		struct pci_bus *bus = to_pci_dev(dev)->bus;
-		struct iort_pci_alias_info info = { .dev = dev };
+		struct iort_pci_alias_info info = { .dev = dev,
+						    .fwspec = fwspec };
 
 		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
 				      iort_match_node_callback, &bus->dev);
@@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
 		err = pci_for_each_dma_alias(to_pci_dev(dev),
 					     iort_pci_iommu_init, &info);
 
-		fwspec = dev_iommu_fwspec_get(dev);
-		if (fwspec && iort_pci_rc_supports_ats(node))
+		if (iort_pci_rc_supports_ats(node))
 			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
 	} else {
 		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
@@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
 		if (!node)
 			return -ENODEV;
 
-		err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
-			      iort_nc_iommu_map(dev, node);
+		err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
+			      iort_nc_iommu_map(fwspec, dev, node);
 
 		if (!err)
 			iort_named_component_init(dev, node);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index fbabde001a23a2..1e01a8e0316867 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
 }
 
 #ifdef CONFIG_IOMMU_API
-int acpi_iommu_fwspec_init(struct device *dev, u32 id,
-			   struct fwnode_handle *fwnode,
-			   const struct iommu_ops *ops)
+int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
+			   u32 id, struct fwnode_handle *fwnode,
+			   bool iommu_driver_available)
 {
-	int ret = iommu_fwspec_init(dev, fwnode, ops);
+	int ret;
 
-	if (!ret)
-		ret = iommu_fwspec_add_ids(dev, &id, 1);
-
-	return ret;
-}
-
-static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
-{
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-
-	return fwspec ? fwspec->ops : NULL;
+	ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
+	if (ret) {
+		if (ret == -EPROBE_DEFER && !iommu_driver_available)
+			return -ENODEV;
+		return ret;
+	}
+	return iommu_fwspec_append_ids(fwspec, &id, 1);
 }
 
 static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 {
 	int err;
-	const struct iommu_ops *ops;
+	struct iommu_fwspec *fwspec;
 
-	/*
-	 * If we already translated the fwspec there is nothing left to do,
-	 * return the iommu_ops.
-	 */
-	ops = acpi_iommu_fwspec_ops(dev);
-	if (ops)
-		return 0;
+	fwspec = iommu_fwspec_alloc();
+	if (IS_ERR(fwspec))
+		return PTR_ERR(fwspec);
 
-	err = iort_iommu_configure_id(dev, id_in);
-	if (err && err != -EPROBE_DEFER)
-		err = viot_iommu_configure(dev);
+	err = iort_iommu_configure_id(fwspec, dev, id_in);
+	if (err == -ENODEV)
+		err = viot_iommu_configure(fwspec, dev);
+	if (err == -ENODEV || err == -EPROBE_DEFER)
+		goto err_free;
+	if (err)
+		goto err_log;
 
-	/*
-	 * If we have reason to believe the IOMMU driver missed the initial
-	 * iommu_probe_device() call for dev, replay it to get things in order.
-	 */
-	if (!err && dev->bus)
-		err = iommu_probe_device(dev);
-
-	/* Ignore all other errors apart from EPROBE_DEFER */
-	if (err == -EPROBE_DEFER) {
-		return err;
-	} else if (err) {
-		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		return -ENODEV;
+	err = iommu_probe_device_fwspec(dev, fwspec);
+	if (err) {
+		/*
+		 * Ownership for fwspec always passes into
+		 * iommu_probe_device_fwspec()
+		 */
+		fwspec = NULL;
+		goto err_log;
 	}
-	if (!acpi_iommu_fwspec_ops(dev))
-		return -ENODEV;
-	return 0;
+
+err_log:
+	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+err_free:
+	iommu_fwspec_dealloc(fwspec);
+	return err;
 }
 
 #else /* !CONFIG_IOMMU_API */
 
-int acpi_iommu_fwspec_init(struct device *dev, u32 id,
-			   struct fwnode_handle *fwnode,
-			   const struct iommu_ops *ops)
+int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
+			   u32 id, struct fwnode_handle *fwnode,
+			   bool iommu_driver_available)
 {
 	return -ENODEV;
 }
 
-static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
-						       const u32 *id_in)
+static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 {
-	return NULL;
+	return -ENODEV;
 }
 
 #endif /* !CONFIG_IOMMU_API */
diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
index c8025921c129b2..33b511dd202d15 100644
--- a/drivers/acpi/viot.c
+++ b/drivers/acpi/viot.c
@@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
 	acpi_put_table(hdr);
 }
 
-static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
-			       u32 epid)
+static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
+			       struct viot_iommu *viommu, u32 epid)
 {
-	const struct iommu_ops *ops;
-
 	if (!viommu)
 		return -ENODEV;
 
@@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
 	if (device_match_fwnode(dev, viommu->fwnode))
 		return -EINVAL;
 
-	ops = iommu_ops_from_fwnode(viommu->fwnode);
-	if (!ops)
-		return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
-			-EPROBE_DEFER : -ENODEV;
-
-	return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
+	return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
+				      IS_ENABLED(CONFIG_VIRTIO_IOMMU));
 }
 
+struct viot_pci_alias_info {
+	struct device *dev;
+	struct iommu_fwspec *fwspec;
+};
+
 static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
 {
 	u32 epid;
 	struct viot_endpoint *ep;
-	struct device *aliased_dev = data;
+	struct viot_pci_alias_info *info = data;
 	u32 domain_nr = pci_domain_nr(pdev->bus);
 
 	list_for_each_entry(ep, &viot_pci_ranges, list) {
@@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
 			epid = ((domain_nr - ep->segment_start) << 16) +
 				dev_id - ep->bdf_start + ep->endpoint_id;
 
-			return viot_dev_iommu_init(aliased_dev, ep->viommu,
-						   epid);
+			return viot_dev_iommu_init(info->fwspec, info->dev,
+						   ep->viommu, epid);
 		}
 	}
 	return -ENODEV;
 }
 
-static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
+static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
+				    struct platform_device *pdev)
 {
 	struct resource *mem;
 	struct viot_endpoint *ep;
@@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
 
 	list_for_each_entry(ep, &viot_mmio_endpoints, list) {
 		if (ep->address == mem->start)
-			return viot_dev_iommu_init(&pdev->dev, ep->viommu,
-						   ep->endpoint_id);
+			return viot_dev_iommu_init(fwspec, &pdev->dev,
+						   ep->viommu, ep->endpoint_id);
 	}
 	return -ENODEV;
 }
@@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
  *
  * Return: 0 on success, <0 on failure
  */
-int viot_iommu_configure(struct device *dev)
+int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
 {
-	if (dev_is_pci(dev))
+	if (dev_is_pci(dev)) {
+		struct viot_pci_alias_info info = { .dev = dev,
+						    .fwspec = fwspec };
 		return pci_for_each_dma_alias(to_pci_dev(dev),
-					      viot_pci_dev_iommu_init, dev);
+					      viot_pci_dev_iommu_init, &info);
+	}
 	else if (dev_is_platform(dev))
-		return viot_mmio_dev_iommu_init(to_platform_device(dev));
+		return viot_mmio_dev_iommu_init(fwspec,
+						to_platform_device(dev));
 	return -ENODEV;
 }
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 15dbe2d9eb24c2..9cfba9d12d1400 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 	return ops;
 }
 
-static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
-				     struct device *dev,
-				     struct fwnode_handle *iommu_fwnode)
+int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
+			      struct fwnode_handle *iommu_fwnode)
 {
 	const struct iommu_ops *ops;
 
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 254685085c825c..70f97096c776e4 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -12,6 +12,8 @@
 #include <linux/device.h>
 #include <linux/property.h>
 
+struct iommu_fwspec;
+
 /* TBD: Make dynamic */
 #define ACPI_MAX_HANDLES	10
 struct acpi_handle_list {
@@ -625,9 +627,9 @@ struct acpi_pci_root {
 
 bool acpi_dma_supported(const struct acpi_device *adev);
 enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
-int acpi_iommu_fwspec_init(struct device *dev, u32 id,
-			   struct fwnode_handle *fwnode,
-			   const struct iommu_ops *ops);
+int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
+			   u32 id, struct fwnode_handle *fwnode,
+			   bool iommu_driver_available);
 int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
 int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 			   const u32 *input_id);
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 1cb65592c95dd3..80794ec45d1693 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
 		       struct list_head *head);
 /* IOMMU interface */
 int iort_dma_get_ranges(struct device *dev, u64 *size);
-int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
+int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
+			    const u32 *id_in);
 void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
 phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
 #else
diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
index a5a12243156377..f1874cb6d43c09 100644
--- a/include/linux/acpi_viot.h
+++ b/include/linux/acpi_viot.h
@@ -8,11 +8,12 @@
 #ifdef CONFIG_ACPI_VIOT
 void __init acpi_viot_early_init(void);
 void __init acpi_viot_init(void);
-int viot_iommu_configure(struct device *dev);
+int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
 #else
 static inline void acpi_viot_early_init(void) {}
 static inline void acpi_viot_init(void) {}
-static inline int viot_iommu_configure(struct device *dev)
+static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
+				       struct device *dev)
 {
 	return -ENODEV;
 }
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index c5a5e2b5e2cc2a..27e4605d498850 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
 int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 			  struct fwnode_handle *iommu_fwnode,
 			  struct of_phandle_args *iommu_spec);
+int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
+			      struct fwnode_handle *iommu_fwnode);
 
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This call chain is using dev->iommu->fwspec to pass around the fwspec
between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
iommu_probe_device()).

However there is no locking around the accesses to dev->iommu, so this is
all racy.

Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
pass it through all functions on the stack to fill it with data, and
finally pass it into iommu_probe_device_fwspec() which will load it into
dev->iommu under a lock.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/acpi/arm64/iort.c | 39 ++++++++---------
 drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
 drivers/acpi/viot.c       | 44 ++++++++++---------
 drivers/iommu/iommu.c     |  5 +--
 include/acpi/acpi_bus.h   |  8 ++--
 include/linux/acpi_iort.h |  3 +-
 include/linux/acpi_viot.h |  5 ++-
 include/linux/iommu.h     |  2 +
 8 files changed, 97 insertions(+), 98 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 6496ff5a6ba20d..accd01dcfe93f5 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
 	return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
 }
 
-static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
-			    u32 streamid)
+static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
+			    struct acpi_iort_node *node, u32 streamid)
 {
-	const struct iommu_ops *ops;
 	struct fwnode_handle *iort_fwnode;
 
 	if (!node)
@@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
 	 * in the kernel or not, defer the IOMMU configuration
 	 * or just abort it.
 	 */
-	ops = iommu_ops_from_fwnode(iort_fwnode);
-	if (!ops)
-		return iort_iommu_driver_enabled(node->type) ?
-		       -EPROBE_DEFER : -ENODEV;
-
-	return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
+	return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
+				      iort_iommu_driver_enabled(node->type));
 }
 
 struct iort_pci_alias_info {
 	struct device *dev;
 	struct acpi_iort_node *node;
+	struct iommu_fwspec *fwspec;
 };
 
 static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
@@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
 
 	parent = iort_node_map_id(info->node, alias, &streamid,
 				  IORT_IOMMU_TYPE);
-	return iort_iommu_xlate(info->dev, parent, streamid);
+	return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
 }
 
 static void iort_named_component_init(struct device *dev,
@@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
 		dev_warn(dev, "Could not add device properties\n");
 }
 
-static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
+static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
+			     struct acpi_iort_node *node)
 {
 	struct acpi_iort_node *parent;
 	int err = -ENODEV, i = 0;
@@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
 						   i++);
 
 		if (parent)
-			err = iort_iommu_xlate(dev, parent, streamid);
+			err = iort_iommu_xlate(fwspec, dev, parent, streamid);
 	} while (parent && !err);
 
 	return err;
 }
 
-static int iort_nc_iommu_map_id(struct device *dev,
+static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
 				struct acpi_iort_node *node,
 				const u32 *in_id)
 {
@@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
 
 	parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
 	if (parent)
-		return iort_iommu_xlate(dev, parent, streamid);
+		return iort_iommu_xlate(fwspec, dev, parent, streamid);
 
 	return -ENODEV;
 }
@@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
  *
  * Returns: 0 on success, <0 on failure
  */
-int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
+int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
+			    const u32 *id_in)
 {
 	struct acpi_iort_node *node;
 	int err = -ENODEV;
 
 	if (dev_is_pci(dev)) {
-		struct iommu_fwspec *fwspec;
 		struct pci_bus *bus = to_pci_dev(dev)->bus;
-		struct iort_pci_alias_info info = { .dev = dev };
+		struct iort_pci_alias_info info = { .dev = dev,
+						    .fwspec = fwspec };
 
 		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
 				      iort_match_node_callback, &bus->dev);
@@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
 		err = pci_for_each_dma_alias(to_pci_dev(dev),
 					     iort_pci_iommu_init, &info);
 
-		fwspec = dev_iommu_fwspec_get(dev);
-		if (fwspec && iort_pci_rc_supports_ats(node))
+		if (iort_pci_rc_supports_ats(node))
 			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
 	} else {
 		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
@@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
 		if (!node)
 			return -ENODEV;
 
-		err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
-			      iort_nc_iommu_map(dev, node);
+		err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
+			      iort_nc_iommu_map(fwspec, dev, node);
 
 		if (!err)
 			iort_named_component_init(dev, node);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index fbabde001a23a2..1e01a8e0316867 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
 }
 
 #ifdef CONFIG_IOMMU_API
-int acpi_iommu_fwspec_init(struct device *dev, u32 id,
-			   struct fwnode_handle *fwnode,
-			   const struct iommu_ops *ops)
+int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
+			   u32 id, struct fwnode_handle *fwnode,
+			   bool iommu_driver_available)
 {
-	int ret = iommu_fwspec_init(dev, fwnode, ops);
+	int ret;
 
-	if (!ret)
-		ret = iommu_fwspec_add_ids(dev, &id, 1);
-
-	return ret;
-}
-
-static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
-{
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-
-	return fwspec ? fwspec->ops : NULL;
+	ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
+	if (ret) {
+		if (ret == -EPROBE_DEFER && !iommu_driver_available)
+			return -ENODEV;
+		return ret;
+	}
+	return iommu_fwspec_append_ids(fwspec, &id, 1);
 }
 
 static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 {
 	int err;
-	const struct iommu_ops *ops;
+	struct iommu_fwspec *fwspec;
 
-	/*
-	 * If we already translated the fwspec there is nothing left to do,
-	 * return the iommu_ops.
-	 */
-	ops = acpi_iommu_fwspec_ops(dev);
-	if (ops)
-		return 0;
+	fwspec = iommu_fwspec_alloc();
+	if (IS_ERR(fwspec))
+		return PTR_ERR(fwspec);
 
-	err = iort_iommu_configure_id(dev, id_in);
-	if (err && err != -EPROBE_DEFER)
-		err = viot_iommu_configure(dev);
+	err = iort_iommu_configure_id(fwspec, dev, id_in);
+	if (err == -ENODEV)
+		err = viot_iommu_configure(fwspec, dev);
+	if (err == -ENODEV || err == -EPROBE_DEFER)
+		goto err_free;
+	if (err)
+		goto err_log;
 
-	/*
-	 * If we have reason to believe the IOMMU driver missed the initial
-	 * iommu_probe_device() call for dev, replay it to get things in order.
-	 */
-	if (!err && dev->bus)
-		err = iommu_probe_device(dev);
-
-	/* Ignore all other errors apart from EPROBE_DEFER */
-	if (err == -EPROBE_DEFER) {
-		return err;
-	} else if (err) {
-		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		return -ENODEV;
+	err = iommu_probe_device_fwspec(dev, fwspec);
+	if (err) {
+		/*
+		 * Ownership for fwspec always passes into
+		 * iommu_probe_device_fwspec()
+		 */
+		fwspec = NULL;
+		goto err_log;
 	}
-	if (!acpi_iommu_fwspec_ops(dev))
-		return -ENODEV;
-	return 0;
+
+err_log:
+	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+err_free:
+	iommu_fwspec_dealloc(fwspec);
+	return err;
 }
 
 #else /* !CONFIG_IOMMU_API */
 
-int acpi_iommu_fwspec_init(struct device *dev, u32 id,
-			   struct fwnode_handle *fwnode,
-			   const struct iommu_ops *ops)
+int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
+			   u32 id, struct fwnode_handle *fwnode,
+			   bool iommu_driver_available)
 {
 	return -ENODEV;
 }
 
-static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
-						       const u32 *id_in)
+static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 {
-	return NULL;
+	return -ENODEV;
 }
 
 #endif /* !CONFIG_IOMMU_API */
diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
index c8025921c129b2..33b511dd202d15 100644
--- a/drivers/acpi/viot.c
+++ b/drivers/acpi/viot.c
@@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
 	acpi_put_table(hdr);
 }
 
-static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
-			       u32 epid)
+static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
+			       struct viot_iommu *viommu, u32 epid)
 {
-	const struct iommu_ops *ops;
-
 	if (!viommu)
 		return -ENODEV;
 
@@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
 	if (device_match_fwnode(dev, viommu->fwnode))
 		return -EINVAL;
 
-	ops = iommu_ops_from_fwnode(viommu->fwnode);
-	if (!ops)
-		return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
-			-EPROBE_DEFER : -ENODEV;
-
-	return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
+	return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
+				      IS_ENABLED(CONFIG_VIRTIO_IOMMU));
 }
 
+struct viot_pci_alias_info {
+	struct device *dev;
+	struct iommu_fwspec *fwspec;
+};
+
 static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
 {
 	u32 epid;
 	struct viot_endpoint *ep;
-	struct device *aliased_dev = data;
+	struct viot_pci_alias_info *info = data;
 	u32 domain_nr = pci_domain_nr(pdev->bus);
 
 	list_for_each_entry(ep, &viot_pci_ranges, list) {
@@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
 			epid = ((domain_nr - ep->segment_start) << 16) +
 				dev_id - ep->bdf_start + ep->endpoint_id;
 
-			return viot_dev_iommu_init(aliased_dev, ep->viommu,
-						   epid);
+			return viot_dev_iommu_init(info->fwspec, info->dev,
+						   ep->viommu, epid);
 		}
 	}
 	return -ENODEV;
 }
 
-static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
+static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
+				    struct platform_device *pdev)
 {
 	struct resource *mem;
 	struct viot_endpoint *ep;
@@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
 
 	list_for_each_entry(ep, &viot_mmio_endpoints, list) {
 		if (ep->address == mem->start)
-			return viot_dev_iommu_init(&pdev->dev, ep->viommu,
-						   ep->endpoint_id);
+			return viot_dev_iommu_init(fwspec, &pdev->dev,
+						   ep->viommu, ep->endpoint_id);
 	}
 	return -ENODEV;
 }
@@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
  *
  * Return: 0 on success, <0 on failure
  */
-int viot_iommu_configure(struct device *dev)
+int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
 {
-	if (dev_is_pci(dev))
+	if (dev_is_pci(dev)) {
+		struct viot_pci_alias_info info = { .dev = dev,
+						    .fwspec = fwspec };
 		return pci_for_each_dma_alias(to_pci_dev(dev),
-					      viot_pci_dev_iommu_init, dev);
+					      viot_pci_dev_iommu_init, &info);
+	}
 	else if (dev_is_platform(dev))
-		return viot_mmio_dev_iommu_init(to_platform_device(dev));
+		return viot_mmio_dev_iommu_init(fwspec,
+						to_platform_device(dev));
 	return -ENODEV;
 }
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 15dbe2d9eb24c2..9cfba9d12d1400 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 	return ops;
 }
 
-static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
-				     struct device *dev,
-				     struct fwnode_handle *iommu_fwnode)
+int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
+			      struct fwnode_handle *iommu_fwnode)
 {
 	const struct iommu_ops *ops;
 
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 254685085c825c..70f97096c776e4 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -12,6 +12,8 @@
 #include <linux/device.h>
 #include <linux/property.h>
 
+struct iommu_fwspec;
+
 /* TBD: Make dynamic */
 #define ACPI_MAX_HANDLES	10
 struct acpi_handle_list {
@@ -625,9 +627,9 @@ struct acpi_pci_root {
 
 bool acpi_dma_supported(const struct acpi_device *adev);
 enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
-int acpi_iommu_fwspec_init(struct device *dev, u32 id,
-			   struct fwnode_handle *fwnode,
-			   const struct iommu_ops *ops);
+int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
+			   u32 id, struct fwnode_handle *fwnode,
+			   bool iommu_driver_available);
 int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
 int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 			   const u32 *input_id);
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 1cb65592c95dd3..80794ec45d1693 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
 		       struct list_head *head);
 /* IOMMU interface */
 int iort_dma_get_ranges(struct device *dev, u64 *size);
-int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
+int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
+			    const u32 *id_in);
 void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
 phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
 #else
diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
index a5a12243156377..f1874cb6d43c09 100644
--- a/include/linux/acpi_viot.h
+++ b/include/linux/acpi_viot.h
@@ -8,11 +8,12 @@
 #ifdef CONFIG_ACPI_VIOT
 void __init acpi_viot_early_init(void);
 void __init acpi_viot_init(void);
-int viot_iommu_configure(struct device *dev);
+int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
 #else
 static inline void acpi_viot_early_init(void) {}
 static inline void acpi_viot_init(void) {}
-static inline int viot_iommu_configure(struct device *dev)
+static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
+				       struct device *dev)
 {
 	return -ENODEV;
 }
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index c5a5e2b5e2cc2a..27e4605d498850 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
 int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 			  struct fwnode_handle *iommu_fwnode,
 			  struct of_phandle_args *iommu_spec);
+int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
+			      struct fwnode_handle *iommu_fwnode);
 
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This call chain is using dev->iommu->fwspec to pass around the fwspec
between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
iommu_probe_device()).

However there is no locking around the accesses to dev->iommu, so this is
all racy.

Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
pass it through all functions on the stack to fill it with data, and
finally pass it into iommu_probe_device_fwspec() which will load it into
dev->iommu under a lock.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/acpi/arm64/iort.c | 39 ++++++++---------
 drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
 drivers/acpi/viot.c       | 44 ++++++++++---------
 drivers/iommu/iommu.c     |  5 +--
 include/acpi/acpi_bus.h   |  8 ++--
 include/linux/acpi_iort.h |  3 +-
 include/linux/acpi_viot.h |  5 ++-
 include/linux/iommu.h     |  2 +
 8 files changed, 97 insertions(+), 98 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 6496ff5a6ba20d..accd01dcfe93f5 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
 	return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
 }
 
-static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
-			    u32 streamid)
+static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
+			    struct acpi_iort_node *node, u32 streamid)
 {
-	const struct iommu_ops *ops;
 	struct fwnode_handle *iort_fwnode;
 
 	if (!node)
@@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
 	 * in the kernel or not, defer the IOMMU configuration
 	 * or just abort it.
 	 */
-	ops = iommu_ops_from_fwnode(iort_fwnode);
-	if (!ops)
-		return iort_iommu_driver_enabled(node->type) ?
-		       -EPROBE_DEFER : -ENODEV;
-
-	return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
+	return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
+				      iort_iommu_driver_enabled(node->type));
 }
 
 struct iort_pci_alias_info {
 	struct device *dev;
 	struct acpi_iort_node *node;
+	struct iommu_fwspec *fwspec;
 };
 
 static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
@@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
 
 	parent = iort_node_map_id(info->node, alias, &streamid,
 				  IORT_IOMMU_TYPE);
-	return iort_iommu_xlate(info->dev, parent, streamid);
+	return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
 }
 
 static void iort_named_component_init(struct device *dev,
@@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
 		dev_warn(dev, "Could not add device properties\n");
 }
 
-static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
+static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
+			     struct acpi_iort_node *node)
 {
 	struct acpi_iort_node *parent;
 	int err = -ENODEV, i = 0;
@@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
 						   i++);
 
 		if (parent)
-			err = iort_iommu_xlate(dev, parent, streamid);
+			err = iort_iommu_xlate(fwspec, dev, parent, streamid);
 	} while (parent && !err);
 
 	return err;
 }
 
-static int iort_nc_iommu_map_id(struct device *dev,
+static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
 				struct acpi_iort_node *node,
 				const u32 *in_id)
 {
@@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
 
 	parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
 	if (parent)
-		return iort_iommu_xlate(dev, parent, streamid);
+		return iort_iommu_xlate(fwspec, dev, parent, streamid);
 
 	return -ENODEV;
 }
@@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
  *
  * Returns: 0 on success, <0 on failure
  */
-int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
+int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
+			    const u32 *id_in)
 {
 	struct acpi_iort_node *node;
 	int err = -ENODEV;
 
 	if (dev_is_pci(dev)) {
-		struct iommu_fwspec *fwspec;
 		struct pci_bus *bus = to_pci_dev(dev)->bus;
-		struct iort_pci_alias_info info = { .dev = dev };
+		struct iort_pci_alias_info info = { .dev = dev,
+						    .fwspec = fwspec };
 
 		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
 				      iort_match_node_callback, &bus->dev);
@@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
 		err = pci_for_each_dma_alias(to_pci_dev(dev),
 					     iort_pci_iommu_init, &info);
 
-		fwspec = dev_iommu_fwspec_get(dev);
-		if (fwspec && iort_pci_rc_supports_ats(node))
+		if (iort_pci_rc_supports_ats(node))
 			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
 	} else {
 		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
@@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
 		if (!node)
 			return -ENODEV;
 
-		err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
-			      iort_nc_iommu_map(dev, node);
+		err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
+			      iort_nc_iommu_map(fwspec, dev, node);
 
 		if (!err)
 			iort_named_component_init(dev, node);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index fbabde001a23a2..1e01a8e0316867 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
 }
 
 #ifdef CONFIG_IOMMU_API
-int acpi_iommu_fwspec_init(struct device *dev, u32 id,
-			   struct fwnode_handle *fwnode,
-			   const struct iommu_ops *ops)
+int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
+			   u32 id, struct fwnode_handle *fwnode,
+			   bool iommu_driver_available)
 {
-	int ret = iommu_fwspec_init(dev, fwnode, ops);
+	int ret;
 
-	if (!ret)
-		ret = iommu_fwspec_add_ids(dev, &id, 1);
-
-	return ret;
-}
-
-static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
-{
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-
-	return fwspec ? fwspec->ops : NULL;
+	ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
+	if (ret) {
+		if (ret == -EPROBE_DEFER && !iommu_driver_available)
+			return -ENODEV;
+		return ret;
+	}
+	return iommu_fwspec_append_ids(fwspec, &id, 1);
 }
 
 static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 {
 	int err;
-	const struct iommu_ops *ops;
+	struct iommu_fwspec *fwspec;
 
-	/*
-	 * If we already translated the fwspec there is nothing left to do,
-	 * return the iommu_ops.
-	 */
-	ops = acpi_iommu_fwspec_ops(dev);
-	if (ops)
-		return 0;
+	fwspec = iommu_fwspec_alloc();
+	if (IS_ERR(fwspec))
+		return PTR_ERR(fwspec);
 
-	err = iort_iommu_configure_id(dev, id_in);
-	if (err && err != -EPROBE_DEFER)
-		err = viot_iommu_configure(dev);
+	err = iort_iommu_configure_id(fwspec, dev, id_in);
+	if (err == -ENODEV)
+		err = viot_iommu_configure(fwspec, dev);
+	if (err == -ENODEV || err == -EPROBE_DEFER)
+		goto err_free;
+	if (err)
+		goto err_log;
 
-	/*
-	 * If we have reason to believe the IOMMU driver missed the initial
-	 * iommu_probe_device() call for dev, replay it to get things in order.
-	 */
-	if (!err && dev->bus)
-		err = iommu_probe_device(dev);
-
-	/* Ignore all other errors apart from EPROBE_DEFER */
-	if (err == -EPROBE_DEFER) {
-		return err;
-	} else if (err) {
-		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		return -ENODEV;
+	err = iommu_probe_device_fwspec(dev, fwspec);
+	if (err) {
+		/*
+		 * Ownership for fwspec always passes into
+		 * iommu_probe_device_fwspec()
+		 */
+		fwspec = NULL;
+		goto err_log;
 	}
-	if (!acpi_iommu_fwspec_ops(dev))
-		return -ENODEV;
-	return 0;
+
+err_log:
+	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+err_free:
+	iommu_fwspec_dealloc(fwspec);
+	return err;
 }
 
 #else /* !CONFIG_IOMMU_API */
 
-int acpi_iommu_fwspec_init(struct device *dev, u32 id,
-			   struct fwnode_handle *fwnode,
-			   const struct iommu_ops *ops)
+int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
+			   u32 id, struct fwnode_handle *fwnode,
+			   bool iommu_driver_available)
 {
 	return -ENODEV;
 }
 
-static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
-						       const u32 *id_in)
+static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 {
-	return NULL;
+	return -ENODEV;
 }
 
 #endif /* !CONFIG_IOMMU_API */
diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
index c8025921c129b2..33b511dd202d15 100644
--- a/drivers/acpi/viot.c
+++ b/drivers/acpi/viot.c
@@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
 	acpi_put_table(hdr);
 }
 
-static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
-			       u32 epid)
+static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
+			       struct viot_iommu *viommu, u32 epid)
 {
-	const struct iommu_ops *ops;
-
 	if (!viommu)
 		return -ENODEV;
 
@@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
 	if (device_match_fwnode(dev, viommu->fwnode))
 		return -EINVAL;
 
-	ops = iommu_ops_from_fwnode(viommu->fwnode);
-	if (!ops)
-		return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
-			-EPROBE_DEFER : -ENODEV;
-
-	return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
+	return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
+				      IS_ENABLED(CONFIG_VIRTIO_IOMMU));
 }
 
+struct viot_pci_alias_info {
+	struct device *dev;
+	struct iommu_fwspec *fwspec;
+};
+
 static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
 {
 	u32 epid;
 	struct viot_endpoint *ep;
-	struct device *aliased_dev = data;
+	struct viot_pci_alias_info *info = data;
 	u32 domain_nr = pci_domain_nr(pdev->bus);
 
 	list_for_each_entry(ep, &viot_pci_ranges, list) {
@@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
 			epid = ((domain_nr - ep->segment_start) << 16) +
 				dev_id - ep->bdf_start + ep->endpoint_id;
 
-			return viot_dev_iommu_init(aliased_dev, ep->viommu,
-						   epid);
+			return viot_dev_iommu_init(info->fwspec, info->dev,
+						   ep->viommu, epid);
 		}
 	}
 	return -ENODEV;
 }
 
-static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
+static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
+				    struct platform_device *pdev)
 {
 	struct resource *mem;
 	struct viot_endpoint *ep;
@@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
 
 	list_for_each_entry(ep, &viot_mmio_endpoints, list) {
 		if (ep->address == mem->start)
-			return viot_dev_iommu_init(&pdev->dev, ep->viommu,
-						   ep->endpoint_id);
+			return viot_dev_iommu_init(fwspec, &pdev->dev,
+						   ep->viommu, ep->endpoint_id);
 	}
 	return -ENODEV;
 }
@@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
  *
  * Return: 0 on success, <0 on failure
  */
-int viot_iommu_configure(struct device *dev)
+int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
 {
-	if (dev_is_pci(dev))
+	if (dev_is_pci(dev)) {
+		struct viot_pci_alias_info info = { .dev = dev,
+						    .fwspec = fwspec };
 		return pci_for_each_dma_alias(to_pci_dev(dev),
-					      viot_pci_dev_iommu_init, dev);
+					      viot_pci_dev_iommu_init, &info);
+	}
 	else if (dev_is_platform(dev))
-		return viot_mmio_dev_iommu_init(to_platform_device(dev));
+		return viot_mmio_dev_iommu_init(fwspec,
+						to_platform_device(dev));
 	return -ENODEV;
 }
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 15dbe2d9eb24c2..9cfba9d12d1400 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 	return ops;
 }
 
-static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
-				     struct device *dev,
-				     struct fwnode_handle *iommu_fwnode)
+int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
+			      struct fwnode_handle *iommu_fwnode)
 {
 	const struct iommu_ops *ops;
 
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 254685085c825c..70f97096c776e4 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -12,6 +12,8 @@
 #include <linux/device.h>
 #include <linux/property.h>
 
+struct iommu_fwspec;
+
 /* TBD: Make dynamic */
 #define ACPI_MAX_HANDLES	10
 struct acpi_handle_list {
@@ -625,9 +627,9 @@ struct acpi_pci_root {
 
 bool acpi_dma_supported(const struct acpi_device *adev);
 enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
-int acpi_iommu_fwspec_init(struct device *dev, u32 id,
-			   struct fwnode_handle *fwnode,
-			   const struct iommu_ops *ops);
+int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
+			   u32 id, struct fwnode_handle *fwnode,
+			   bool iommu_driver_available);
 int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
 int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 			   const u32 *input_id);
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 1cb65592c95dd3..80794ec45d1693 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
 		       struct list_head *head);
 /* IOMMU interface */
 int iort_dma_get_ranges(struct device *dev, u64 *size);
-int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
+int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
+			    const u32 *id_in);
 void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
 phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
 #else
diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
index a5a12243156377..f1874cb6d43c09 100644
--- a/include/linux/acpi_viot.h
+++ b/include/linux/acpi_viot.h
@@ -8,11 +8,12 @@
 #ifdef CONFIG_ACPI_VIOT
 void __init acpi_viot_early_init(void);
 void __init acpi_viot_init(void);
-int viot_iommu_configure(struct device *dev);
+int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
 #else
 static inline void acpi_viot_early_init(void) {}
 static inline void acpi_viot_init(void) {}
-static inline int viot_iommu_configure(struct device *dev)
+static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
+				       struct device *dev)
 {
 	return -ENODEV;
 }
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index c5a5e2b5e2cc2a..27e4605d498850 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
 int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 			  struct fwnode_handle *iommu_fwnode,
 			  struct of_phandle_args *iommu_spec);
+int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
+			      struct fwnode_handle *iommu_fwnode);
 
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This call chain is using dev->iommu->fwspec to pass around the fwspec
between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
iommu_probe_device()).

However there is no locking around the accesses to dev->iommu, so this is
all racy.

Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
pass it through all functions on the stack to fill it with data, and
finally pass it into iommu_probe_device_fwspec() which will load it into
dev->iommu under a lock.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/acpi/arm64/iort.c | 39 ++++++++---------
 drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
 drivers/acpi/viot.c       | 44 ++++++++++---------
 drivers/iommu/iommu.c     |  5 +--
 include/acpi/acpi_bus.h   |  8 ++--
 include/linux/acpi_iort.h |  3 +-
 include/linux/acpi_viot.h |  5 ++-
 include/linux/iommu.h     |  2 +
 8 files changed, 97 insertions(+), 98 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 6496ff5a6ba20d..accd01dcfe93f5 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
 	return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
 }
 
-static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
-			    u32 streamid)
+static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
+			    struct acpi_iort_node *node, u32 streamid)
 {
-	const struct iommu_ops *ops;
 	struct fwnode_handle *iort_fwnode;
 
 	if (!node)
@@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
 	 * in the kernel or not, defer the IOMMU configuration
 	 * or just abort it.
 	 */
-	ops = iommu_ops_from_fwnode(iort_fwnode);
-	if (!ops)
-		return iort_iommu_driver_enabled(node->type) ?
-		       -EPROBE_DEFER : -ENODEV;
-
-	return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
+	return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
+				      iort_iommu_driver_enabled(node->type));
 }
 
 struct iort_pci_alias_info {
 	struct device *dev;
 	struct acpi_iort_node *node;
+	struct iommu_fwspec *fwspec;
 };
 
 static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
@@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
 
 	parent = iort_node_map_id(info->node, alias, &streamid,
 				  IORT_IOMMU_TYPE);
-	return iort_iommu_xlate(info->dev, parent, streamid);
+	return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
 }
 
 static void iort_named_component_init(struct device *dev,
@@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
 		dev_warn(dev, "Could not add device properties\n");
 }
 
-static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
+static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
+			     struct acpi_iort_node *node)
 {
 	struct acpi_iort_node *parent;
 	int err = -ENODEV, i = 0;
@@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
 						   i++);
 
 		if (parent)
-			err = iort_iommu_xlate(dev, parent, streamid);
+			err = iort_iommu_xlate(fwspec, dev, parent, streamid);
 	} while (parent && !err);
 
 	return err;
 }
 
-static int iort_nc_iommu_map_id(struct device *dev,
+static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
 				struct acpi_iort_node *node,
 				const u32 *in_id)
 {
@@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
 
 	parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
 	if (parent)
-		return iort_iommu_xlate(dev, parent, streamid);
+		return iort_iommu_xlate(fwspec, dev, parent, streamid);
 
 	return -ENODEV;
 }
@@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
  *
  * Returns: 0 on success, <0 on failure
  */
-int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
+int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
+			    const u32 *id_in)
 {
 	struct acpi_iort_node *node;
 	int err = -ENODEV;
 
 	if (dev_is_pci(dev)) {
-		struct iommu_fwspec *fwspec;
 		struct pci_bus *bus = to_pci_dev(dev)->bus;
-		struct iort_pci_alias_info info = { .dev = dev };
+		struct iort_pci_alias_info info = { .dev = dev,
+						    .fwspec = fwspec };
 
 		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
 				      iort_match_node_callback, &bus->dev);
@@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
 		err = pci_for_each_dma_alias(to_pci_dev(dev),
 					     iort_pci_iommu_init, &info);
 
-		fwspec = dev_iommu_fwspec_get(dev);
-		if (fwspec && iort_pci_rc_supports_ats(node))
+		if (iort_pci_rc_supports_ats(node))
 			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
 	} else {
 		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
@@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
 		if (!node)
 			return -ENODEV;
 
-		err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
-			      iort_nc_iommu_map(dev, node);
+		err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
+			      iort_nc_iommu_map(fwspec, dev, node);
 
 		if (!err)
 			iort_named_component_init(dev, node);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index fbabde001a23a2..1e01a8e0316867 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
 }
 
 #ifdef CONFIG_IOMMU_API
-int acpi_iommu_fwspec_init(struct device *dev, u32 id,
-			   struct fwnode_handle *fwnode,
-			   const struct iommu_ops *ops)
+int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
+			   u32 id, struct fwnode_handle *fwnode,
+			   bool iommu_driver_available)
 {
-	int ret = iommu_fwspec_init(dev, fwnode, ops);
+	int ret;
 
-	if (!ret)
-		ret = iommu_fwspec_add_ids(dev, &id, 1);
-
-	return ret;
-}
-
-static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
-{
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-
-	return fwspec ? fwspec->ops : NULL;
+	ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
+	if (ret) {
+		if (ret == -EPROBE_DEFER && !iommu_driver_available)
+			return -ENODEV;
+		return ret;
+	}
+	return iommu_fwspec_append_ids(fwspec, &id, 1);
 }
 
 static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 {
 	int err;
-	const struct iommu_ops *ops;
+	struct iommu_fwspec *fwspec;
 
-	/*
-	 * If we already translated the fwspec there is nothing left to do,
-	 * return the iommu_ops.
-	 */
-	ops = acpi_iommu_fwspec_ops(dev);
-	if (ops)
-		return 0;
+	fwspec = iommu_fwspec_alloc();
+	if (IS_ERR(fwspec))
+		return PTR_ERR(fwspec);
 
-	err = iort_iommu_configure_id(dev, id_in);
-	if (err && err != -EPROBE_DEFER)
-		err = viot_iommu_configure(dev);
+	err = iort_iommu_configure_id(fwspec, dev, id_in);
+	if (err == -ENODEV)
+		err = viot_iommu_configure(fwspec, dev);
+	if (err == -ENODEV || err == -EPROBE_DEFER)
+		goto err_free;
+	if (err)
+		goto err_log;
 
-	/*
-	 * If we have reason to believe the IOMMU driver missed the initial
-	 * iommu_probe_device() call for dev, replay it to get things in order.
-	 */
-	if (!err && dev->bus)
-		err = iommu_probe_device(dev);
-
-	/* Ignore all other errors apart from EPROBE_DEFER */
-	if (err == -EPROBE_DEFER) {
-		return err;
-	} else if (err) {
-		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		return -ENODEV;
+	err = iommu_probe_device_fwspec(dev, fwspec);
+	if (err) {
+		/*
+		 * Ownership for fwspec always passes into
+		 * iommu_probe_device_fwspec()
+		 */
+		fwspec = NULL;
+		goto err_log;
 	}
-	if (!acpi_iommu_fwspec_ops(dev))
-		return -ENODEV;
-	return 0;
+
+err_log:
+	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+err_free:
+	iommu_fwspec_dealloc(fwspec);
+	return err;
 }
 
 #else /* !CONFIG_IOMMU_API */
 
-int acpi_iommu_fwspec_init(struct device *dev, u32 id,
-			   struct fwnode_handle *fwnode,
-			   const struct iommu_ops *ops)
+int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
+			   u32 id, struct fwnode_handle *fwnode,
+			   bool iommu_driver_available)
 {
 	return -ENODEV;
 }
 
-static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
-						       const u32 *id_in)
+static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 {
-	return NULL;
+	return -ENODEV;
 }
 
 #endif /* !CONFIG_IOMMU_API */
diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
index c8025921c129b2..33b511dd202d15 100644
--- a/drivers/acpi/viot.c
+++ b/drivers/acpi/viot.c
@@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
 	acpi_put_table(hdr);
 }
 
-static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
-			       u32 epid)
+static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
+			       struct viot_iommu *viommu, u32 epid)
 {
-	const struct iommu_ops *ops;
-
 	if (!viommu)
 		return -ENODEV;
 
@@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
 	if (device_match_fwnode(dev, viommu->fwnode))
 		return -EINVAL;
 
-	ops = iommu_ops_from_fwnode(viommu->fwnode);
-	if (!ops)
-		return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
-			-EPROBE_DEFER : -ENODEV;
-
-	return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
+	return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
+				      IS_ENABLED(CONFIG_VIRTIO_IOMMU));
 }
 
+struct viot_pci_alias_info {
+	struct device *dev;
+	struct iommu_fwspec *fwspec;
+};
+
 static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
 {
 	u32 epid;
 	struct viot_endpoint *ep;
-	struct device *aliased_dev = data;
+	struct viot_pci_alias_info *info = data;
 	u32 domain_nr = pci_domain_nr(pdev->bus);
 
 	list_for_each_entry(ep, &viot_pci_ranges, list) {
@@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
 			epid = ((domain_nr - ep->segment_start) << 16) +
 				dev_id - ep->bdf_start + ep->endpoint_id;
 
-			return viot_dev_iommu_init(aliased_dev, ep->viommu,
-						   epid);
+			return viot_dev_iommu_init(info->fwspec, info->dev,
+						   ep->viommu, epid);
 		}
 	}
 	return -ENODEV;
 }
 
-static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
+static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
+				    struct platform_device *pdev)
 {
 	struct resource *mem;
 	struct viot_endpoint *ep;
@@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
 
 	list_for_each_entry(ep, &viot_mmio_endpoints, list) {
 		if (ep->address == mem->start)
-			return viot_dev_iommu_init(&pdev->dev, ep->viommu,
-						   ep->endpoint_id);
+			return viot_dev_iommu_init(fwspec, &pdev->dev,
+						   ep->viommu, ep->endpoint_id);
 	}
 	return -ENODEV;
 }
@@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
  *
  * Return: 0 on success, <0 on failure
  */
-int viot_iommu_configure(struct device *dev)
+int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
 {
-	if (dev_is_pci(dev))
+	if (dev_is_pci(dev)) {
+		struct viot_pci_alias_info info = { .dev = dev,
+						    .fwspec = fwspec };
 		return pci_for_each_dma_alias(to_pci_dev(dev),
-					      viot_pci_dev_iommu_init, dev);
+					      viot_pci_dev_iommu_init, &info);
+	}
 	else if (dev_is_platform(dev))
-		return viot_mmio_dev_iommu_init(to_platform_device(dev));
+		return viot_mmio_dev_iommu_init(fwspec,
+						to_platform_device(dev));
 	return -ENODEV;
 }
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 15dbe2d9eb24c2..9cfba9d12d1400 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 	return ops;
 }
 
-static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
-				     struct device *dev,
-				     struct fwnode_handle *iommu_fwnode)
+int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
+			      struct fwnode_handle *iommu_fwnode)
 {
 	const struct iommu_ops *ops;
 
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 254685085c825c..70f97096c776e4 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -12,6 +12,8 @@
 #include <linux/device.h>
 #include <linux/property.h>
 
+struct iommu_fwspec;
+
 /* TBD: Make dynamic */
 #define ACPI_MAX_HANDLES	10
 struct acpi_handle_list {
@@ -625,9 +627,9 @@ struct acpi_pci_root {
 
 bool acpi_dma_supported(const struct acpi_device *adev);
 enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
-int acpi_iommu_fwspec_init(struct device *dev, u32 id,
-			   struct fwnode_handle *fwnode,
-			   const struct iommu_ops *ops);
+int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
+			   u32 id, struct fwnode_handle *fwnode,
+			   bool iommu_driver_available);
 int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
 int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 			   const u32 *input_id);
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 1cb65592c95dd3..80794ec45d1693 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
 		       struct list_head *head);
 /* IOMMU interface */
 int iort_dma_get_ranges(struct device *dev, u64 *size);
-int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
+int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
+			    const u32 *id_in);
 void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
 phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
 #else
diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
index a5a12243156377..f1874cb6d43c09 100644
--- a/include/linux/acpi_viot.h
+++ b/include/linux/acpi_viot.h
@@ -8,11 +8,12 @@
 #ifdef CONFIG_ACPI_VIOT
 void __init acpi_viot_early_init(void);
 void __init acpi_viot_init(void);
-int viot_iommu_configure(struct device *dev);
+int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
 #else
 static inline void acpi_viot_early_init(void) {}
 static inline void acpi_viot_init(void) {}
-static inline int viot_iommu_configure(struct device *dev)
+static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
+				       struct device *dev)
 {
 	return -ENODEV;
 }
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index c5a5e2b5e2cc2a..27e4605d498850 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
 int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 			  struct fwnode_handle *iommu_fwnode,
 			  struct of_phandle_args *iommu_spec);
+int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
+			      struct fwnode_handle *iommu_fwnode);
 
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 11/17] iommu: Hold iommu_probe_device_lock while calling ops->of_xlate
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:44   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This resolves the race around touching dev->iommu while generating the OF
fwspec on the of_iommu_configure() flow:

     CPU0                                     CPU1
of_iommu_configure()                iommu_device_register()
 ..                                   bus_iommu_probe()
  iommu_fwspec_of_xlate()              __iommu_probe_device()
                                        iommu_init_device()
   dev_iommu_get()
                                          .. ops->probe fails, no fwspec ..
                                          dev_iommu_free()
   dev->iommu->fwspec    *crash*

CPU1 is holding the iommu_probe_device_lock for iommu_init_device(),
holding it around the of_xlate() and its related manipulation of
dev->iommu will close it.

The approach also closes a similar race for what should be a successful
probe where the above basic construction results in ops->probe observing a
partially initialized fwspec.

Reported-by: Zhenhua Huang <quic_zhenhuah@quicinc.com>
Closes: https://lore.kernel.org/linux-arm-kernel/20231017163337.GE282036@ziepe.ca/T/#mee0d7bdc375541934a571ae69f43b9660f8e7312
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9cfba9d12d1400..62c82a28cd5db3 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -41,6 +41,7 @@
 static struct kset *iommu_group_kset;
 static DEFINE_IDA(iommu_group_ida);
 static DEFINE_IDA(iommu_global_pasid_ida);
+static DEFINE_MUTEX(iommu_probe_device_lock);
 
 static unsigned int iommu_def_domain_type __read_mostly;
 static bool iommu_dma_strict __read_mostly = IS_ENABLED(CONFIG_IOMMU_DEFAULT_DMA_STRICT);
@@ -498,7 +499,6 @@ static int __iommu_probe_device(struct device *dev,
 	struct iommu_fwspec *fwspec = caller_fwspec;
 	const struct iommu_ops *ops;
 	struct iommu_group *group;
-	static DEFINE_MUTEX(iommu_probe_device_lock);
 	struct group_device *gdev;
 	int ret;
 
@@ -3002,8 +3002,11 @@ int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 	if (!fwspec->ops->of_xlate)
 		return -ENODEV;
 
-	if (!dev_iommu_get(dev))
+	mutex_lock(&iommu_probe_device_lock);
+	if (!dev_iommu_get(dev)) {
+		mutex_unlock(&iommu_probe_device_lock);
 		return -ENOMEM;
+	}
 
 	/*
 	 * ops->of_xlate() requires the fwspec to be passed through dev->iommu,
@@ -3015,6 +3018,7 @@ int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 	ret = fwspec->ops->of_xlate(dev, iommu_spec);
 	if (dev->iommu->fwspec == fwspec)
 		dev->iommu->fwspec = NULL;
+	mutex_unlock(&iommu_probe_device_lock);
 	return ret;
 }
 
@@ -3044,6 +3048,8 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	int ret;
 
+	lockdep_assert_held(&iommu_probe_device_lock);
+
 	if (fwspec)
 		return ops == fwspec->ops ? 0 : -EINVAL;
 
@@ -3097,6 +3103,8 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 
+	lockdep_assert_held(&iommu_probe_device_lock);
+
 	if (!fwspec)
 		return -EINVAL;
 	return iommu_fwspec_append_ids(fwspec, ids, num_ids);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 11/17] iommu: Hold iommu_probe_device_lock while calling ops->of_xlate
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This resolves the race around touching dev->iommu while generating the OF
fwspec on the of_iommu_configure() flow:

     CPU0                                     CPU1
of_iommu_configure()                iommu_device_register()
 ..                                   bus_iommu_probe()
  iommu_fwspec_of_xlate()              __iommu_probe_device()
                                        iommu_init_device()
   dev_iommu_get()
                                          .. ops->probe fails, no fwspec ..
                                          dev_iommu_free()
   dev->iommu->fwspec    *crash*

CPU1 is holding the iommu_probe_device_lock for iommu_init_device(),
holding it around the of_xlate() and its related manipulation of
dev->iommu will close it.

The approach also closes a similar race for what should be a successful
probe where the above basic construction results in ops->probe observing a
partially initialized fwspec.

Reported-by: Zhenhua Huang <quic_zhenhuah@quicinc.com>
Closes: https://lore.kernel.org/linux-arm-kernel/20231017163337.GE282036@ziepe.ca/T/#mee0d7bdc375541934a571ae69f43b9660f8e7312
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9cfba9d12d1400..62c82a28cd5db3 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -41,6 +41,7 @@
 static struct kset *iommu_group_kset;
 static DEFINE_IDA(iommu_group_ida);
 static DEFINE_IDA(iommu_global_pasid_ida);
+static DEFINE_MUTEX(iommu_probe_device_lock);
 
 static unsigned int iommu_def_domain_type __read_mostly;
 static bool iommu_dma_strict __read_mostly = IS_ENABLED(CONFIG_IOMMU_DEFAULT_DMA_STRICT);
@@ -498,7 +499,6 @@ static int __iommu_probe_device(struct device *dev,
 	struct iommu_fwspec *fwspec = caller_fwspec;
 	const struct iommu_ops *ops;
 	struct iommu_group *group;
-	static DEFINE_MUTEX(iommu_probe_device_lock);
 	struct group_device *gdev;
 	int ret;
 
@@ -3002,8 +3002,11 @@ int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 	if (!fwspec->ops->of_xlate)
 		return -ENODEV;
 
-	if (!dev_iommu_get(dev))
+	mutex_lock(&iommu_probe_device_lock);
+	if (!dev_iommu_get(dev)) {
+		mutex_unlock(&iommu_probe_device_lock);
 		return -ENOMEM;
+	}
 
 	/*
 	 * ops->of_xlate() requires the fwspec to be passed through dev->iommu,
@@ -3015,6 +3018,7 @@ int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 	ret = fwspec->ops->of_xlate(dev, iommu_spec);
 	if (dev->iommu->fwspec == fwspec)
 		dev->iommu->fwspec = NULL;
+	mutex_unlock(&iommu_probe_device_lock);
 	return ret;
 }
 
@@ -3044,6 +3048,8 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	int ret;
 
+	lockdep_assert_held(&iommu_probe_device_lock);
+
 	if (fwspec)
 		return ops == fwspec->ops ? 0 : -EINVAL;
 
@@ -3097,6 +3103,8 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 
+	lockdep_assert_held(&iommu_probe_device_lock);
+
 	if (!fwspec)
 		return -EINVAL;
 	return iommu_fwspec_append_ids(fwspec, ids, num_ids);
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 11/17] iommu: Hold iommu_probe_device_lock while calling ops->of_xlate
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This resolves the race around touching dev->iommu while generating the OF
fwspec on the of_iommu_configure() flow:

     CPU0                                     CPU1
of_iommu_configure()                iommu_device_register()
 ..                                   bus_iommu_probe()
  iommu_fwspec_of_xlate()              __iommu_probe_device()
                                        iommu_init_device()
   dev_iommu_get()
                                          .. ops->probe fails, no fwspec ..
                                          dev_iommu_free()
   dev->iommu->fwspec    *crash*

CPU1 is holding the iommu_probe_device_lock for iommu_init_device(),
holding it around the of_xlate() and its related manipulation of
dev->iommu will close it.

The approach also closes a similar race for what should be a successful
probe where the above basic construction results in ops->probe observing a
partially initialized fwspec.

Reported-by: Zhenhua Huang <quic_zhenhuah@quicinc.com>
Closes: https://lore.kernel.org/linux-arm-kernel/20231017163337.GE282036@ziepe.ca/T/#mee0d7bdc375541934a571ae69f43b9660f8e7312
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9cfba9d12d1400..62c82a28cd5db3 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -41,6 +41,7 @@
 static struct kset *iommu_group_kset;
 static DEFINE_IDA(iommu_group_ida);
 static DEFINE_IDA(iommu_global_pasid_ida);
+static DEFINE_MUTEX(iommu_probe_device_lock);
 
 static unsigned int iommu_def_domain_type __read_mostly;
 static bool iommu_dma_strict __read_mostly = IS_ENABLED(CONFIG_IOMMU_DEFAULT_DMA_STRICT);
@@ -498,7 +499,6 @@ static int __iommu_probe_device(struct device *dev,
 	struct iommu_fwspec *fwspec = caller_fwspec;
 	const struct iommu_ops *ops;
 	struct iommu_group *group;
-	static DEFINE_MUTEX(iommu_probe_device_lock);
 	struct group_device *gdev;
 	int ret;
 
@@ -3002,8 +3002,11 @@ int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 	if (!fwspec->ops->of_xlate)
 		return -ENODEV;
 
-	if (!dev_iommu_get(dev))
+	mutex_lock(&iommu_probe_device_lock);
+	if (!dev_iommu_get(dev)) {
+		mutex_unlock(&iommu_probe_device_lock);
 		return -ENOMEM;
+	}
 
 	/*
 	 * ops->of_xlate() requires the fwspec to be passed through dev->iommu,
@@ -3015,6 +3018,7 @@ int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 	ret = fwspec->ops->of_xlate(dev, iommu_spec);
 	if (dev->iommu->fwspec == fwspec)
 		dev->iommu->fwspec = NULL;
+	mutex_unlock(&iommu_probe_device_lock);
 	return ret;
 }
 
@@ -3044,6 +3048,8 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	int ret;
 
+	lockdep_assert_held(&iommu_probe_device_lock);
+
 	if (fwspec)
 		return ops == fwspec->ops ? 0 : -EINVAL;
 
@@ -3097,6 +3103,8 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 
+	lockdep_assert_held(&iommu_probe_device_lock);
+
 	if (!fwspec)
 		return -EINVAL;
 	return iommu_fwspec_append_ids(fwspec, ids, num_ids);
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 11/17] iommu: Hold iommu_probe_device_lock while calling ops->of_xlate
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This resolves the race around touching dev->iommu while generating the OF
fwspec on the of_iommu_configure() flow:

     CPU0                                     CPU1
of_iommu_configure()                iommu_device_register()
 ..                                   bus_iommu_probe()
  iommu_fwspec_of_xlate()              __iommu_probe_device()
                                        iommu_init_device()
   dev_iommu_get()
                                          .. ops->probe fails, no fwspec ..
                                          dev_iommu_free()
   dev->iommu->fwspec    *crash*

CPU1 is holding the iommu_probe_device_lock for iommu_init_device(),
holding it around the of_xlate() and its related manipulation of
dev->iommu will close it.

The approach also closes a similar race for what should be a successful
probe where the above basic construction results in ops->probe observing a
partially initialized fwspec.

Reported-by: Zhenhua Huang <quic_zhenhuah@quicinc.com>
Closes: https://lore.kernel.org/linux-arm-kernel/20231017163337.GE282036@ziepe.ca/T/#mee0d7bdc375541934a571ae69f43b9660f8e7312
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9cfba9d12d1400..62c82a28cd5db3 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -41,6 +41,7 @@
 static struct kset *iommu_group_kset;
 static DEFINE_IDA(iommu_group_ida);
 static DEFINE_IDA(iommu_global_pasid_ida);
+static DEFINE_MUTEX(iommu_probe_device_lock);
 
 static unsigned int iommu_def_domain_type __read_mostly;
 static bool iommu_dma_strict __read_mostly = IS_ENABLED(CONFIG_IOMMU_DEFAULT_DMA_STRICT);
@@ -498,7 +499,6 @@ static int __iommu_probe_device(struct device *dev,
 	struct iommu_fwspec *fwspec = caller_fwspec;
 	const struct iommu_ops *ops;
 	struct iommu_group *group;
-	static DEFINE_MUTEX(iommu_probe_device_lock);
 	struct group_device *gdev;
 	int ret;
 
@@ -3002,8 +3002,11 @@ int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 	if (!fwspec->ops->of_xlate)
 		return -ENODEV;
 
-	if (!dev_iommu_get(dev))
+	mutex_lock(&iommu_probe_device_lock);
+	if (!dev_iommu_get(dev)) {
+		mutex_unlock(&iommu_probe_device_lock);
 		return -ENOMEM;
+	}
 
 	/*
 	 * ops->of_xlate() requires the fwspec to be passed through dev->iommu,
@@ -3015,6 +3018,7 @@ int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 	ret = fwspec->ops->of_xlate(dev, iommu_spec);
 	if (dev->iommu->fwspec == fwspec)
 		dev->iommu->fwspec = NULL;
+	mutex_unlock(&iommu_probe_device_lock);
 	return ret;
 }
 
@@ -3044,6 +3048,8 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	int ret;
 
+	lockdep_assert_held(&iommu_probe_device_lock);
+
 	if (fwspec)
 		return ops == fwspec->ops ? 0 : -EINVAL;
 
@@ -3097,6 +3103,8 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 
+	lockdep_assert_held(&iommu_probe_device_lock);
+
 	if (!fwspec)
 		return -EINVAL;
 	return iommu_fwspec_append_ids(fwspec, ids, num_ids);
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 11/17] iommu: Hold iommu_probe_device_lock while calling ops->of_xlate
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This resolves the race around touching dev->iommu while generating the OF
fwspec on the of_iommu_configure() flow:

     CPU0                                     CPU1
of_iommu_configure()                iommu_device_register()
 ..                                   bus_iommu_probe()
  iommu_fwspec_of_xlate()              __iommu_probe_device()
                                        iommu_init_device()
   dev_iommu_get()
                                          .. ops->probe fails, no fwspec ..
                                          dev_iommu_free()
   dev->iommu->fwspec    *crash*

CPU1 is holding the iommu_probe_device_lock for iommu_init_device(),
holding it around the of_xlate() and its related manipulation of
dev->iommu will close it.

The approach also closes a similar race for what should be a successful
probe where the above basic construction results in ops->probe observing a
partially initialized fwspec.

Reported-by: Zhenhua Huang <quic_zhenhuah@quicinc.com>
Closes: https://lore.kernel.org/linux-arm-kernel/20231017163337.GE282036@ziepe.ca/T/#mee0d7bdc375541934a571ae69f43b9660f8e7312
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9cfba9d12d1400..62c82a28cd5db3 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -41,6 +41,7 @@
 static struct kset *iommu_group_kset;
 static DEFINE_IDA(iommu_group_ida);
 static DEFINE_IDA(iommu_global_pasid_ida);
+static DEFINE_MUTEX(iommu_probe_device_lock);
 
 static unsigned int iommu_def_domain_type __read_mostly;
 static bool iommu_dma_strict __read_mostly = IS_ENABLED(CONFIG_IOMMU_DEFAULT_DMA_STRICT);
@@ -498,7 +499,6 @@ static int __iommu_probe_device(struct device *dev,
 	struct iommu_fwspec *fwspec = caller_fwspec;
 	const struct iommu_ops *ops;
 	struct iommu_group *group;
-	static DEFINE_MUTEX(iommu_probe_device_lock);
 	struct group_device *gdev;
 	int ret;
 
@@ -3002,8 +3002,11 @@ int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 	if (!fwspec->ops->of_xlate)
 		return -ENODEV;
 
-	if (!dev_iommu_get(dev))
+	mutex_lock(&iommu_probe_device_lock);
+	if (!dev_iommu_get(dev)) {
+		mutex_unlock(&iommu_probe_device_lock);
 		return -ENOMEM;
+	}
 
 	/*
 	 * ops->of_xlate() requires the fwspec to be passed through dev->iommu,
@@ -3015,6 +3018,7 @@ int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 	ret = fwspec->ops->of_xlate(dev, iommu_spec);
 	if (dev->iommu->fwspec == fwspec)
 		dev->iommu->fwspec = NULL;
+	mutex_unlock(&iommu_probe_device_lock);
 	return ret;
 }
 
@@ -3044,6 +3048,8 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	int ret;
 
+	lockdep_assert_held(&iommu_probe_device_lock);
+
 	if (fwspec)
 		return ops == fwspec->ops ? 0 : -EINVAL;
 
@@ -3097,6 +3103,8 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 
+	lockdep_assert_held(&iommu_probe_device_lock);
+
 	if (!fwspec)
 		return -EINVAL;
 	return iommu_fwspec_append_ids(fwspec, ids, num_ids);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 12/17] iommu: Make iommu_ops_from_fwnode() static
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:44   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

There are no external callers now.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 3 ++-
 include/linux/iommu.h | 6 ------
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 62c82a28cd5db3..becd1b881e62dc 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2945,7 +2945,8 @@ bool iommu_default_passthrough(void)
 }
 EXPORT_SYMBOL_GPL(iommu_default_passthrough);
 
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
+static const struct iommu_ops *
+iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 {
 	const struct iommu_ops *ops = NULL;
 	struct iommu_device *iommu;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 27e4605d498850..37948eee8d7394 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -701,7 +701,6 @@ static inline void iommu_fwspec_free(struct device *dev)
 	dev->iommu->fwspec = NULL;
 }
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
 int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids, int num_ids);
 
 static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
@@ -1044,11 +1043,6 @@ static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
 }
 
 static inline
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
-{
-	return NULL;
-}
-
 static inline int
 iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features feat)
 {
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 12/17] iommu: Make iommu_ops_from_fwnode() static
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

There are no external callers now.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 3 ++-
 include/linux/iommu.h | 6 ------
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 62c82a28cd5db3..becd1b881e62dc 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2945,7 +2945,8 @@ bool iommu_default_passthrough(void)
 }
 EXPORT_SYMBOL_GPL(iommu_default_passthrough);
 
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
+static const struct iommu_ops *
+iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 {
 	const struct iommu_ops *ops = NULL;
 	struct iommu_device *iommu;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 27e4605d498850..37948eee8d7394 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -701,7 +701,6 @@ static inline void iommu_fwspec_free(struct device *dev)
 	dev->iommu->fwspec = NULL;
 }
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
 int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids, int num_ids);
 
 static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
@@ -1044,11 +1043,6 @@ static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
 }
 
 static inline
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
-{
-	return NULL;
-}
-
 static inline int
 iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features feat)
 {
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 12/17] iommu: Make iommu_ops_from_fwnode() static
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

There are no external callers now.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 3 ++-
 include/linux/iommu.h | 6 ------
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 62c82a28cd5db3..becd1b881e62dc 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2945,7 +2945,8 @@ bool iommu_default_passthrough(void)
 }
 EXPORT_SYMBOL_GPL(iommu_default_passthrough);
 
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
+static const struct iommu_ops *
+iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 {
 	const struct iommu_ops *ops = NULL;
 	struct iommu_device *iommu;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 27e4605d498850..37948eee8d7394 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -701,7 +701,6 @@ static inline void iommu_fwspec_free(struct device *dev)
 	dev->iommu->fwspec = NULL;
 }
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
 int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids, int num_ids);
 
 static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
@@ -1044,11 +1043,6 @@ static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
 }
 
 static inline
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
-{
-	return NULL;
-}
-
 static inline int
 iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features feat)
 {
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 12/17] iommu: Make iommu_ops_from_fwnode() static
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

There are no external callers now.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 3 ++-
 include/linux/iommu.h | 6 ------
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 62c82a28cd5db3..becd1b881e62dc 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2945,7 +2945,8 @@ bool iommu_default_passthrough(void)
 }
 EXPORT_SYMBOL_GPL(iommu_default_passthrough);
 
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
+static const struct iommu_ops *
+iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 {
 	const struct iommu_ops *ops = NULL;
 	struct iommu_device *iommu;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 27e4605d498850..37948eee8d7394 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -701,7 +701,6 @@ static inline void iommu_fwspec_free(struct device *dev)
 	dev->iommu->fwspec = NULL;
 }
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
 int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids, int num_ids);
 
 static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
@@ -1044,11 +1043,6 @@ static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
 }
 
 static inline
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
-{
-	return NULL;
-}
-
 static inline int
 iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features feat)
 {
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 12/17] iommu: Make iommu_ops_from_fwnode() static
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

There are no external callers now.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 3 ++-
 include/linux/iommu.h | 6 ------
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 62c82a28cd5db3..becd1b881e62dc 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2945,7 +2945,8 @@ bool iommu_default_passthrough(void)
 }
 EXPORT_SYMBOL_GPL(iommu_default_passthrough);
 
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
+static const struct iommu_ops *
+iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 {
 	const struct iommu_ops *ops = NULL;
 	struct iommu_device *iommu;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 27e4605d498850..37948eee8d7394 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -701,7 +701,6 @@ static inline void iommu_fwspec_free(struct device *dev)
 	dev->iommu->fwspec = NULL;
 }
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
 int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids, int num_ids);
 
 static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
@@ -1044,11 +1043,6 @@ static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
 }
 
 static inline
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
-{
-	return NULL;
-}
-
 static inline int
 iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features feat)
 {
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 13/17] iommu: Remove dev_iommu_fwspec_set()
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:44   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is only used internally to iommu.c now, get rid of it to discourage
things outside iommu.c from trying to manipulate dev->iommu->fwspec.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 2 +-
 include/linux/iommu.h | 6 ------
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index becd1b881e62dc..d14438ffb0feb7 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3068,7 +3068,7 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		return ret;
 	}
 
-	dev_iommu_fwspec_set(dev, fwspec);
+	dev->iommu->fwspec = fwspec;
 	return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_init);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 37948eee8d7394..5e1f9222bde856 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -711,12 +711,6 @@ static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
 		return NULL;
 }
 
-static inline void dev_iommu_fwspec_set(struct device *dev,
-					struct iommu_fwspec *fwspec)
-{
-	dev->iommu->fwspec = fwspec;
-}
-
 static inline void *dev_iommu_priv_get(struct device *dev)
 {
 	if (dev->iommu)
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 13/17] iommu: Remove dev_iommu_fwspec_set()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is only used internally to iommu.c now, get rid of it to discourage
things outside iommu.c from trying to manipulate dev->iommu->fwspec.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 2 +-
 include/linux/iommu.h | 6 ------
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index becd1b881e62dc..d14438ffb0feb7 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3068,7 +3068,7 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		return ret;
 	}
 
-	dev_iommu_fwspec_set(dev, fwspec);
+	dev->iommu->fwspec = fwspec;
 	return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_init);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 37948eee8d7394..5e1f9222bde856 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -711,12 +711,6 @@ static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
 		return NULL;
 }
 
-static inline void dev_iommu_fwspec_set(struct device *dev,
-					struct iommu_fwspec *fwspec)
-{
-	dev->iommu->fwspec = fwspec;
-}
-
 static inline void *dev_iommu_priv_get(struct device *dev)
 {
 	if (dev->iommu)
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 13/17] iommu: Remove dev_iommu_fwspec_set()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is only used internally to iommu.c now, get rid of it to discourage
things outside iommu.c from trying to manipulate dev->iommu->fwspec.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 2 +-
 include/linux/iommu.h | 6 ------
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index becd1b881e62dc..d14438ffb0feb7 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3068,7 +3068,7 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		return ret;
 	}
 
-	dev_iommu_fwspec_set(dev, fwspec);
+	dev->iommu->fwspec = fwspec;
 	return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_init);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 37948eee8d7394..5e1f9222bde856 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -711,12 +711,6 @@ static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
 		return NULL;
 }
 
-static inline void dev_iommu_fwspec_set(struct device *dev,
-					struct iommu_fwspec *fwspec)
-{
-	dev->iommu->fwspec = fwspec;
-}
-
 static inline void *dev_iommu_priv_get(struct device *dev)
 {
 	if (dev->iommu)
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 13/17] iommu: Remove dev_iommu_fwspec_set()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is only used internally to iommu.c now, get rid of it to discourage
things outside iommu.c from trying to manipulate dev->iommu->fwspec.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 2 +-
 include/linux/iommu.h | 6 ------
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index becd1b881e62dc..d14438ffb0feb7 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3068,7 +3068,7 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		return ret;
 	}
 
-	dev_iommu_fwspec_set(dev, fwspec);
+	dev->iommu->fwspec = fwspec;
 	return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_init);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 37948eee8d7394..5e1f9222bde856 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -711,12 +711,6 @@ static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
 		return NULL;
 }
 
-static inline void dev_iommu_fwspec_set(struct device *dev,
-					struct iommu_fwspec *fwspec)
-{
-	dev->iommu->fwspec = fwspec;
-}
-
 static inline void *dev_iommu_priv_get(struct device *dev)
 {
 	if (dev->iommu)
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 13/17] iommu: Remove dev_iommu_fwspec_set()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

This is only used internally to iommu.c now, get rid of it to discourage
things outside iommu.c from trying to manipulate dev->iommu->fwspec.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 2 +-
 include/linux/iommu.h | 6 ------
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index becd1b881e62dc..d14438ffb0feb7 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3068,7 +3068,7 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		return ret;
 	}
 
-	dev_iommu_fwspec_set(dev, fwspec);
+	dev->iommu->fwspec = fwspec;
 	return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_init);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 37948eee8d7394..5e1f9222bde856 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -711,12 +711,6 @@ static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
 		return NULL;
 }
 
-static inline void dev_iommu_fwspec_set(struct device *dev,
-					struct iommu_fwspec *fwspec)
-{
-	dev->iommu->fwspec = fwspec;
-}
-
 static inline void *dev_iommu_priv_get(struct device *dev)
 {
 	if (dev->iommu)
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 14/17] iommu: Remove pointless iommu_fwspec_free()
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:44   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

These days the core code will free the fwspec if probe fails, no reason
for any driver to call this on a probe failure path.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 14 +++++---------
 drivers/iommu/tegra-smmu.c            |  1 -
 2 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index d6d1a2a55cc069..854efcb1b84ddf 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1348,6 +1348,8 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 	if (using_legacy_binding) {
 		ret = arm_smmu_register_legacy_master(dev, &smmu);
+		if (ret)
+			return ERR_PTR(ret);
 
 		/*
 		 * If dev->iommu_fwspec is initally NULL, arm_smmu_register_legacy_master()
@@ -1355,15 +1357,12 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 		 * later use.
 		 */
 		fwspec = dev_iommu_fwspec_get(dev);
-		if (ret)
-			goto out_free;
 	} else if (fwspec && fwspec->ops == &arm_smmu_ops) {
 		smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
 	} else {
 		return ERR_PTR(-ENODEV);
 	}
 
-	ret = -EINVAL;
 	for (i = 0; i < fwspec->num_ids; i++) {
 		u16 sid = FIELD_GET(ARM_SMMU_SMR_ID, fwspec->ids[i]);
 		u16 mask = FIELD_GET(ARM_SMMU_SMR_MASK, fwspec->ids[i]);
@@ -1371,20 +1370,19 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 		if (sid & ~smmu->streamid_mask) {
 			dev_err(dev, "stream ID 0x%x out of range for SMMU (0x%x)\n",
 				sid, smmu->streamid_mask);
-			goto out_free;
+			return ERR_PTR(-EINVAL);
 		}
 		if (mask & ~smmu->smr_mask_mask) {
 			dev_err(dev, "SMR mask 0x%x out of range for SMMU (0x%x)\n",
 				mask, smmu->smr_mask_mask);
-			goto out_free;
+			return ERR_PTR(-EINVAL);
 		}
 	}
 
-	ret = -ENOMEM;
 	cfg = kzalloc(offsetof(struct arm_smmu_master_cfg, smendx[i]),
 		      GFP_KERNEL);
 	if (!cfg)
-		goto out_free;
+		return ERR_PTR(-ENOMEM);
 
 	cfg->smmu = smmu;
 	dev_iommu_priv_set(dev, cfg);
@@ -1408,8 +1406,6 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 out_cfg_free:
 	kfree(cfg);
-out_free:
-	iommu_fwspec_free(dev);
 	return ERR_PTR(ret);
 }
 
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 310871728ab4b6..e3101aa2f35689 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -844,7 +844,6 @@ static int tegra_smmu_configure(struct tegra_smmu *smmu, struct device *dev,
 	err = ops->of_xlate(dev, args);
 	if (err < 0) {
 		dev_err(dev, "failed to parse SW group ID: %d\n", err);
-		iommu_fwspec_free(dev);
 		return err;
 	}
 
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 14/17] iommu: Remove pointless iommu_fwspec_free()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

These days the core code will free the fwspec if probe fails, no reason
for any driver to call this on a probe failure path.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 14 +++++---------
 drivers/iommu/tegra-smmu.c            |  1 -
 2 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index d6d1a2a55cc069..854efcb1b84ddf 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1348,6 +1348,8 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 	if (using_legacy_binding) {
 		ret = arm_smmu_register_legacy_master(dev, &smmu);
+		if (ret)
+			return ERR_PTR(ret);
 
 		/*
 		 * If dev->iommu_fwspec is initally NULL, arm_smmu_register_legacy_master()
@@ -1355,15 +1357,12 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 		 * later use.
 		 */
 		fwspec = dev_iommu_fwspec_get(dev);
-		if (ret)
-			goto out_free;
 	} else if (fwspec && fwspec->ops == &arm_smmu_ops) {
 		smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
 	} else {
 		return ERR_PTR(-ENODEV);
 	}
 
-	ret = -EINVAL;
 	for (i = 0; i < fwspec->num_ids; i++) {
 		u16 sid = FIELD_GET(ARM_SMMU_SMR_ID, fwspec->ids[i]);
 		u16 mask = FIELD_GET(ARM_SMMU_SMR_MASK, fwspec->ids[i]);
@@ -1371,20 +1370,19 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 		if (sid & ~smmu->streamid_mask) {
 			dev_err(dev, "stream ID 0x%x out of range for SMMU (0x%x)\n",
 				sid, smmu->streamid_mask);
-			goto out_free;
+			return ERR_PTR(-EINVAL);
 		}
 		if (mask & ~smmu->smr_mask_mask) {
 			dev_err(dev, "SMR mask 0x%x out of range for SMMU (0x%x)\n",
 				mask, smmu->smr_mask_mask);
-			goto out_free;
+			return ERR_PTR(-EINVAL);
 		}
 	}
 
-	ret = -ENOMEM;
 	cfg = kzalloc(offsetof(struct arm_smmu_master_cfg, smendx[i]),
 		      GFP_KERNEL);
 	if (!cfg)
-		goto out_free;
+		return ERR_PTR(-ENOMEM);
 
 	cfg->smmu = smmu;
 	dev_iommu_priv_set(dev, cfg);
@@ -1408,8 +1406,6 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 out_cfg_free:
 	kfree(cfg);
-out_free:
-	iommu_fwspec_free(dev);
 	return ERR_PTR(ret);
 }
 
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 310871728ab4b6..e3101aa2f35689 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -844,7 +844,6 @@ static int tegra_smmu_configure(struct tegra_smmu *smmu, struct device *dev,
 	err = ops->of_xlate(dev, args);
 	if (err < 0) {
 		dev_err(dev, "failed to parse SW group ID: %d\n", err);
-		iommu_fwspec_free(dev);
 		return err;
 	}
 
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 14/17] iommu: Remove pointless iommu_fwspec_free()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

These days the core code will free the fwspec if probe fails, no reason
for any driver to call this on a probe failure path.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 14 +++++---------
 drivers/iommu/tegra-smmu.c            |  1 -
 2 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index d6d1a2a55cc069..854efcb1b84ddf 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1348,6 +1348,8 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 	if (using_legacy_binding) {
 		ret = arm_smmu_register_legacy_master(dev, &smmu);
+		if (ret)
+			return ERR_PTR(ret);
 
 		/*
 		 * If dev->iommu_fwspec is initally NULL, arm_smmu_register_legacy_master()
@@ -1355,15 +1357,12 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 		 * later use.
 		 */
 		fwspec = dev_iommu_fwspec_get(dev);
-		if (ret)
-			goto out_free;
 	} else if (fwspec && fwspec->ops == &arm_smmu_ops) {
 		smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
 	} else {
 		return ERR_PTR(-ENODEV);
 	}
 
-	ret = -EINVAL;
 	for (i = 0; i < fwspec->num_ids; i++) {
 		u16 sid = FIELD_GET(ARM_SMMU_SMR_ID, fwspec->ids[i]);
 		u16 mask = FIELD_GET(ARM_SMMU_SMR_MASK, fwspec->ids[i]);
@@ -1371,20 +1370,19 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 		if (sid & ~smmu->streamid_mask) {
 			dev_err(dev, "stream ID 0x%x out of range for SMMU (0x%x)\n",
 				sid, smmu->streamid_mask);
-			goto out_free;
+			return ERR_PTR(-EINVAL);
 		}
 		if (mask & ~smmu->smr_mask_mask) {
 			dev_err(dev, "SMR mask 0x%x out of range for SMMU (0x%x)\n",
 				mask, smmu->smr_mask_mask);
-			goto out_free;
+			return ERR_PTR(-EINVAL);
 		}
 	}
 
-	ret = -ENOMEM;
 	cfg = kzalloc(offsetof(struct arm_smmu_master_cfg, smendx[i]),
 		      GFP_KERNEL);
 	if (!cfg)
-		goto out_free;
+		return ERR_PTR(-ENOMEM);
 
 	cfg->smmu = smmu;
 	dev_iommu_priv_set(dev, cfg);
@@ -1408,8 +1406,6 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 out_cfg_free:
 	kfree(cfg);
-out_free:
-	iommu_fwspec_free(dev);
 	return ERR_PTR(ret);
 }
 
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 310871728ab4b6..e3101aa2f35689 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -844,7 +844,6 @@ static int tegra_smmu_configure(struct tegra_smmu *smmu, struct device *dev,
 	err = ops->of_xlate(dev, args);
 	if (err < 0) {
 		dev_err(dev, "failed to parse SW group ID: %d\n", err);
-		iommu_fwspec_free(dev);
 		return err;
 	}
 
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 14/17] iommu: Remove pointless iommu_fwspec_free()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

These days the core code will free the fwspec if probe fails, no reason
for any driver to call this on a probe failure path.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 14 +++++---------
 drivers/iommu/tegra-smmu.c            |  1 -
 2 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index d6d1a2a55cc069..854efcb1b84ddf 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1348,6 +1348,8 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 	if (using_legacy_binding) {
 		ret = arm_smmu_register_legacy_master(dev, &smmu);
+		if (ret)
+			return ERR_PTR(ret);
 
 		/*
 		 * If dev->iommu_fwspec is initally NULL, arm_smmu_register_legacy_master()
@@ -1355,15 +1357,12 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 		 * later use.
 		 */
 		fwspec = dev_iommu_fwspec_get(dev);
-		if (ret)
-			goto out_free;
 	} else if (fwspec && fwspec->ops == &arm_smmu_ops) {
 		smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
 	} else {
 		return ERR_PTR(-ENODEV);
 	}
 
-	ret = -EINVAL;
 	for (i = 0; i < fwspec->num_ids; i++) {
 		u16 sid = FIELD_GET(ARM_SMMU_SMR_ID, fwspec->ids[i]);
 		u16 mask = FIELD_GET(ARM_SMMU_SMR_MASK, fwspec->ids[i]);
@@ -1371,20 +1370,19 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 		if (sid & ~smmu->streamid_mask) {
 			dev_err(dev, "stream ID 0x%x out of range for SMMU (0x%x)\n",
 				sid, smmu->streamid_mask);
-			goto out_free;
+			return ERR_PTR(-EINVAL);
 		}
 		if (mask & ~smmu->smr_mask_mask) {
 			dev_err(dev, "SMR mask 0x%x out of range for SMMU (0x%x)\n",
 				mask, smmu->smr_mask_mask);
-			goto out_free;
+			return ERR_PTR(-EINVAL);
 		}
 	}
 
-	ret = -ENOMEM;
 	cfg = kzalloc(offsetof(struct arm_smmu_master_cfg, smendx[i]),
 		      GFP_KERNEL);
 	if (!cfg)
-		goto out_free;
+		return ERR_PTR(-ENOMEM);
 
 	cfg->smmu = smmu;
 	dev_iommu_priv_set(dev, cfg);
@@ -1408,8 +1406,6 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 out_cfg_free:
 	kfree(cfg);
-out_free:
-	iommu_fwspec_free(dev);
 	return ERR_PTR(ret);
 }
 
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 310871728ab4b6..e3101aa2f35689 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -844,7 +844,6 @@ static int tegra_smmu_configure(struct tegra_smmu *smmu, struct device *dev,
 	err = ops->of_xlate(dev, args);
 	if (err < 0) {
 		dev_err(dev, "failed to parse SW group ID: %d\n", err);
-		iommu_fwspec_free(dev);
 		return err;
 	}
 
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 14/17] iommu: Remove pointless iommu_fwspec_free()
@ 2023-11-03 16:44   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:44 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

These days the core code will free the fwspec if probe fails, no reason
for any driver to call this on a probe failure path.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 14 +++++---------
 drivers/iommu/tegra-smmu.c            |  1 -
 2 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index d6d1a2a55cc069..854efcb1b84ddf 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1348,6 +1348,8 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 	if (using_legacy_binding) {
 		ret = arm_smmu_register_legacy_master(dev, &smmu);
+		if (ret)
+			return ERR_PTR(ret);
 
 		/*
 		 * If dev->iommu_fwspec is initally NULL, arm_smmu_register_legacy_master()
@@ -1355,15 +1357,12 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 		 * later use.
 		 */
 		fwspec = dev_iommu_fwspec_get(dev);
-		if (ret)
-			goto out_free;
 	} else if (fwspec && fwspec->ops == &arm_smmu_ops) {
 		smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
 	} else {
 		return ERR_PTR(-ENODEV);
 	}
 
-	ret = -EINVAL;
 	for (i = 0; i < fwspec->num_ids; i++) {
 		u16 sid = FIELD_GET(ARM_SMMU_SMR_ID, fwspec->ids[i]);
 		u16 mask = FIELD_GET(ARM_SMMU_SMR_MASK, fwspec->ids[i]);
@@ -1371,20 +1370,19 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 		if (sid & ~smmu->streamid_mask) {
 			dev_err(dev, "stream ID 0x%x out of range for SMMU (0x%x)\n",
 				sid, smmu->streamid_mask);
-			goto out_free;
+			return ERR_PTR(-EINVAL);
 		}
 		if (mask & ~smmu->smr_mask_mask) {
 			dev_err(dev, "SMR mask 0x%x out of range for SMMU (0x%x)\n",
 				mask, smmu->smr_mask_mask);
-			goto out_free;
+			return ERR_PTR(-EINVAL);
 		}
 	}
 
-	ret = -ENOMEM;
 	cfg = kzalloc(offsetof(struct arm_smmu_master_cfg, smendx[i]),
 		      GFP_KERNEL);
 	if (!cfg)
-		goto out_free;
+		return ERR_PTR(-ENOMEM);
 
 	cfg->smmu = smmu;
 	dev_iommu_priv_set(dev, cfg);
@@ -1408,8 +1406,6 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 out_cfg_free:
 	kfree(cfg);
-out_free:
-	iommu_fwspec_free(dev);
 	return ERR_PTR(ret);
 }
 
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 310871728ab4b6..e3101aa2f35689 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -844,7 +844,6 @@ static int tegra_smmu_configure(struct tegra_smmu *smmu, struct device *dev,
 	err = ops->of_xlate(dev, args);
 	if (err < 0) {
 		dev_err(dev, "failed to parse SW group ID: %d\n", err);
-		iommu_fwspec_free(dev);
 		return err;
 	}
 
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 15/17] iommu: Add ops->of_xlate_fwspec()
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:45   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:45 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

The new callback takes in the fwspec instead of retrieving it from the
dev->iommu. Provide iommu_fwspec_append_ids() to work directly on the
fwspec.

Convert SMMU, SMMUv3, and virtio to use iommu_fwspec_append_ids() and the
new entry point.

This avoids having to touch dev->iommu at all, and doesn't require the
iommu_probe_device_lock.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 +++++---
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 8 +++++---
 drivers/iommu/iommu.c                       | 3 +++
 drivers/iommu/virtio-iommu.c                | 8 +++++---
 include/linux/iommu.h                       | 3 +++
 5 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 7445454c2af244..b1309f04ebc0d9 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2748,9 +2748,11 @@ static int arm_smmu_enable_nesting(struct iommu_domain *domain)
 	return ret;
 }
 
-static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int arm_smmu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+				    struct device *dev,
+				    struct of_phandle_args *args)
 {
-	return iommu_fwspec_add_ids(dev, args->args, 1);
+	return iommu_fwspec_append_ids(fwspec, args->args, 1);
 }
 
 static void arm_smmu_get_resv_regions(struct device *dev,
@@ -2858,7 +2860,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.probe_device		= arm_smmu_probe_device,
 	.release_device		= arm_smmu_release_device,
 	.device_group		= arm_smmu_device_group,
-	.of_xlate		= arm_smmu_of_xlate,
+	.of_xlate_fwspec	= arm_smmu_of_xlate_fwspec,
 	.get_resv_regions	= arm_smmu_get_resv_regions,
 	.remove_dev_pasid	= arm_smmu_remove_dev_pasid,
 	.dev_enable_feat	= arm_smmu_dev_enable_feature,
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 854efcb1b84ddf..8c4a60d8e5d522 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1510,7 +1510,9 @@ static int arm_smmu_set_pgtable_quirks(struct iommu_domain *domain,
 	return ret;
 }
 
-static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int arm_smmu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+				    struct device *dev,
+				    struct of_phandle_args *args)
 {
 	u32 mask, fwid = 0;
 
@@ -1522,7 +1524,7 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
 	else if (!of_property_read_u32(args->np, "stream-match-mask", &mask))
 		fwid |= FIELD_PREP(ARM_SMMU_SMR_MASK, mask);
 
-	return iommu_fwspec_add_ids(dev, &fwid, 1);
+	return iommu_fwspec_append_ids(fwspec, &fwid, 1);
 }
 
 static void arm_smmu_get_resv_regions(struct device *dev,
@@ -1562,7 +1564,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.release_device		= arm_smmu_release_device,
 	.probe_finalize		= arm_smmu_probe_finalize,
 	.device_group		= arm_smmu_device_group,
-	.of_xlate		= arm_smmu_of_xlate,
+	.of_xlate_fwspec	= arm_smmu_of_xlate_fwspec,
 	.get_resv_regions	= arm_smmu_get_resv_regions,
 	.def_domain_type	= arm_smmu_def_domain_type,
 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d14438ffb0feb7..9f23e113f46bc7 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3000,6 +3000,9 @@ int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 	if (ret)
 		return ret;
 
+	if (fwspec->ops->of_xlate_fwspec)
+		return fwspec->ops->of_xlate_fwspec(fwspec, dev, iommu_spec);
+
 	if (!fwspec->ops->of_xlate)
 		return -ENODEV;
 
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 379ebe03efb6d4..2283f1d1155981 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -1027,9 +1027,11 @@ static struct iommu_group *viommu_device_group(struct device *dev)
 		return generic_device_group(dev);
 }
 
-static int viommu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int viommu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+				  struct device *dev,
+				  struct of_phandle_args *args)
 {
-	return iommu_fwspec_add_ids(dev, args->args, 1);
+	return iommu_fwspec_append_ids(fwspec, args->args, 1);
 }
 
 static bool viommu_capable(struct device *dev, enum iommu_cap cap)
@@ -1050,7 +1052,7 @@ static struct iommu_ops viommu_ops = {
 	.release_device		= viommu_release_device,
 	.device_group		= viommu_device_group,
 	.get_resv_regions	= viommu_get_resv_regions,
-	.of_xlate		= viommu_of_xlate,
+	.of_xlate_fwspec	= viommu_of_xlate_fwspec,
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev		= viommu_attach_dev,
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 5e1f9222bde856..2fac54a942af54 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -41,6 +41,7 @@ struct notifier_block;
 struct iommu_sva;
 struct iommu_fault_event;
 struct iommu_dma_cookie;
+struct iommu_fwspec;
 
 /* iommu fault flags */
 #define IOMMU_FAULT_READ	0x0
@@ -287,6 +288,8 @@ struct iommu_ops {
 	/* Request/Free a list of reserved regions for a device */
 	void (*get_resv_regions)(struct device *dev, struct list_head *list);
 
+	int (*of_xlate_fwspec)(struct iommu_fwspec *fwspec, struct device *dev,
+			       struct of_phandle_args *args);
 	int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
 	bool (*is_attach_deferred)(struct device *dev);
 
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 15/17] iommu: Add ops->of_xlate_fwspec()
@ 2023-11-03 16:45   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:45 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

The new callback takes in the fwspec instead of retrieving it from the
dev->iommu. Provide iommu_fwspec_append_ids() to work directly on the
fwspec.

Convert SMMU, SMMUv3, and virtio to use iommu_fwspec_append_ids() and the
new entry point.

This avoids having to touch dev->iommu at all, and doesn't require the
iommu_probe_device_lock.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 +++++---
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 8 +++++---
 drivers/iommu/iommu.c                       | 3 +++
 drivers/iommu/virtio-iommu.c                | 8 +++++---
 include/linux/iommu.h                       | 3 +++
 5 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 7445454c2af244..b1309f04ebc0d9 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2748,9 +2748,11 @@ static int arm_smmu_enable_nesting(struct iommu_domain *domain)
 	return ret;
 }
 
-static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int arm_smmu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+				    struct device *dev,
+				    struct of_phandle_args *args)
 {
-	return iommu_fwspec_add_ids(dev, args->args, 1);
+	return iommu_fwspec_append_ids(fwspec, args->args, 1);
 }
 
 static void arm_smmu_get_resv_regions(struct device *dev,
@@ -2858,7 +2860,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.probe_device		= arm_smmu_probe_device,
 	.release_device		= arm_smmu_release_device,
 	.device_group		= arm_smmu_device_group,
-	.of_xlate		= arm_smmu_of_xlate,
+	.of_xlate_fwspec	= arm_smmu_of_xlate_fwspec,
 	.get_resv_regions	= arm_smmu_get_resv_regions,
 	.remove_dev_pasid	= arm_smmu_remove_dev_pasid,
 	.dev_enable_feat	= arm_smmu_dev_enable_feature,
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 854efcb1b84ddf..8c4a60d8e5d522 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1510,7 +1510,9 @@ static int arm_smmu_set_pgtable_quirks(struct iommu_domain *domain,
 	return ret;
 }
 
-static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int arm_smmu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+				    struct device *dev,
+				    struct of_phandle_args *args)
 {
 	u32 mask, fwid = 0;
 
@@ -1522,7 +1524,7 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
 	else if (!of_property_read_u32(args->np, "stream-match-mask", &mask))
 		fwid |= FIELD_PREP(ARM_SMMU_SMR_MASK, mask);
 
-	return iommu_fwspec_add_ids(dev, &fwid, 1);
+	return iommu_fwspec_append_ids(fwspec, &fwid, 1);
 }
 
 static void arm_smmu_get_resv_regions(struct device *dev,
@@ -1562,7 +1564,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.release_device		= arm_smmu_release_device,
 	.probe_finalize		= arm_smmu_probe_finalize,
 	.device_group		= arm_smmu_device_group,
-	.of_xlate		= arm_smmu_of_xlate,
+	.of_xlate_fwspec	= arm_smmu_of_xlate_fwspec,
 	.get_resv_regions	= arm_smmu_get_resv_regions,
 	.def_domain_type	= arm_smmu_def_domain_type,
 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d14438ffb0feb7..9f23e113f46bc7 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3000,6 +3000,9 @@ int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 	if (ret)
 		return ret;
 
+	if (fwspec->ops->of_xlate_fwspec)
+		return fwspec->ops->of_xlate_fwspec(fwspec, dev, iommu_spec);
+
 	if (!fwspec->ops->of_xlate)
 		return -ENODEV;
 
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 379ebe03efb6d4..2283f1d1155981 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -1027,9 +1027,11 @@ static struct iommu_group *viommu_device_group(struct device *dev)
 		return generic_device_group(dev);
 }
 
-static int viommu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int viommu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+				  struct device *dev,
+				  struct of_phandle_args *args)
 {
-	return iommu_fwspec_add_ids(dev, args->args, 1);
+	return iommu_fwspec_append_ids(fwspec, args->args, 1);
 }
 
 static bool viommu_capable(struct device *dev, enum iommu_cap cap)
@@ -1050,7 +1052,7 @@ static struct iommu_ops viommu_ops = {
 	.release_device		= viommu_release_device,
 	.device_group		= viommu_device_group,
 	.get_resv_regions	= viommu_get_resv_regions,
-	.of_xlate		= viommu_of_xlate,
+	.of_xlate_fwspec	= viommu_of_xlate_fwspec,
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev		= viommu_attach_dev,
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 5e1f9222bde856..2fac54a942af54 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -41,6 +41,7 @@ struct notifier_block;
 struct iommu_sva;
 struct iommu_fault_event;
 struct iommu_dma_cookie;
+struct iommu_fwspec;
 
 /* iommu fault flags */
 #define IOMMU_FAULT_READ	0x0
@@ -287,6 +288,8 @@ struct iommu_ops {
 	/* Request/Free a list of reserved regions for a device */
 	void (*get_resv_regions)(struct device *dev, struct list_head *list);
 
+	int (*of_xlate_fwspec)(struct iommu_fwspec *fwspec, struct device *dev,
+			       struct of_phandle_args *args);
 	int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
 	bool (*is_attach_deferred)(struct device *dev);
 
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 15/17] iommu: Add ops->of_xlate_fwspec()
@ 2023-11-03 16:45   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:45 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

The new callback takes in the fwspec instead of retrieving it from the
dev->iommu. Provide iommu_fwspec_append_ids() to work directly on the
fwspec.

Convert SMMU, SMMUv3, and virtio to use iommu_fwspec_append_ids() and the
new entry point.

This avoids having to touch dev->iommu at all, and doesn't require the
iommu_probe_device_lock.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 +++++---
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 8 +++++---
 drivers/iommu/iommu.c                       | 3 +++
 drivers/iommu/virtio-iommu.c                | 8 +++++---
 include/linux/iommu.h                       | 3 +++
 5 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 7445454c2af244..b1309f04ebc0d9 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2748,9 +2748,11 @@ static int arm_smmu_enable_nesting(struct iommu_domain *domain)
 	return ret;
 }
 
-static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int arm_smmu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+				    struct device *dev,
+				    struct of_phandle_args *args)
 {
-	return iommu_fwspec_add_ids(dev, args->args, 1);
+	return iommu_fwspec_append_ids(fwspec, args->args, 1);
 }
 
 static void arm_smmu_get_resv_regions(struct device *dev,
@@ -2858,7 +2860,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.probe_device		= arm_smmu_probe_device,
 	.release_device		= arm_smmu_release_device,
 	.device_group		= arm_smmu_device_group,
-	.of_xlate		= arm_smmu_of_xlate,
+	.of_xlate_fwspec	= arm_smmu_of_xlate_fwspec,
 	.get_resv_regions	= arm_smmu_get_resv_regions,
 	.remove_dev_pasid	= arm_smmu_remove_dev_pasid,
 	.dev_enable_feat	= arm_smmu_dev_enable_feature,
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 854efcb1b84ddf..8c4a60d8e5d522 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1510,7 +1510,9 @@ static int arm_smmu_set_pgtable_quirks(struct iommu_domain *domain,
 	return ret;
 }
 
-static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int arm_smmu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+				    struct device *dev,
+				    struct of_phandle_args *args)
 {
 	u32 mask, fwid = 0;
 
@@ -1522,7 +1524,7 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
 	else if (!of_property_read_u32(args->np, "stream-match-mask", &mask))
 		fwid |= FIELD_PREP(ARM_SMMU_SMR_MASK, mask);
 
-	return iommu_fwspec_add_ids(dev, &fwid, 1);
+	return iommu_fwspec_append_ids(fwspec, &fwid, 1);
 }
 
 static void arm_smmu_get_resv_regions(struct device *dev,
@@ -1562,7 +1564,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.release_device		= arm_smmu_release_device,
 	.probe_finalize		= arm_smmu_probe_finalize,
 	.device_group		= arm_smmu_device_group,
-	.of_xlate		= arm_smmu_of_xlate,
+	.of_xlate_fwspec	= arm_smmu_of_xlate_fwspec,
 	.get_resv_regions	= arm_smmu_get_resv_regions,
 	.def_domain_type	= arm_smmu_def_domain_type,
 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d14438ffb0feb7..9f23e113f46bc7 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3000,6 +3000,9 @@ int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 	if (ret)
 		return ret;
 
+	if (fwspec->ops->of_xlate_fwspec)
+		return fwspec->ops->of_xlate_fwspec(fwspec, dev, iommu_spec);
+
 	if (!fwspec->ops->of_xlate)
 		return -ENODEV;
 
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 379ebe03efb6d4..2283f1d1155981 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -1027,9 +1027,11 @@ static struct iommu_group *viommu_device_group(struct device *dev)
 		return generic_device_group(dev);
 }
 
-static int viommu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int viommu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+				  struct device *dev,
+				  struct of_phandle_args *args)
 {
-	return iommu_fwspec_add_ids(dev, args->args, 1);
+	return iommu_fwspec_append_ids(fwspec, args->args, 1);
 }
 
 static bool viommu_capable(struct device *dev, enum iommu_cap cap)
@@ -1050,7 +1052,7 @@ static struct iommu_ops viommu_ops = {
 	.release_device		= viommu_release_device,
 	.device_group		= viommu_device_group,
 	.get_resv_regions	= viommu_get_resv_regions,
-	.of_xlate		= viommu_of_xlate,
+	.of_xlate_fwspec	= viommu_of_xlate_fwspec,
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev		= viommu_attach_dev,
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 5e1f9222bde856..2fac54a942af54 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -41,6 +41,7 @@ struct notifier_block;
 struct iommu_sva;
 struct iommu_fault_event;
 struct iommu_dma_cookie;
+struct iommu_fwspec;
 
 /* iommu fault flags */
 #define IOMMU_FAULT_READ	0x0
@@ -287,6 +288,8 @@ struct iommu_ops {
 	/* Request/Free a list of reserved regions for a device */
 	void (*get_resv_regions)(struct device *dev, struct list_head *list);
 
+	int (*of_xlate_fwspec)(struct iommu_fwspec *fwspec, struct device *dev,
+			       struct of_phandle_args *args);
 	int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
 	bool (*is_attach_deferred)(struct device *dev);
 
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 15/17] iommu: Add ops->of_xlate_fwspec()
@ 2023-11-03 16:45   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:45 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

The new callback takes in the fwspec instead of retrieving it from the
dev->iommu. Provide iommu_fwspec_append_ids() to work directly on the
fwspec.

Convert SMMU, SMMUv3, and virtio to use iommu_fwspec_append_ids() and the
new entry point.

This avoids having to touch dev->iommu at all, and doesn't require the
iommu_probe_device_lock.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 +++++---
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 8 +++++---
 drivers/iommu/iommu.c                       | 3 +++
 drivers/iommu/virtio-iommu.c                | 8 +++++---
 include/linux/iommu.h                       | 3 +++
 5 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 7445454c2af244..b1309f04ebc0d9 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2748,9 +2748,11 @@ static int arm_smmu_enable_nesting(struct iommu_domain *domain)
 	return ret;
 }
 
-static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int arm_smmu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+				    struct device *dev,
+				    struct of_phandle_args *args)
 {
-	return iommu_fwspec_add_ids(dev, args->args, 1);
+	return iommu_fwspec_append_ids(fwspec, args->args, 1);
 }
 
 static void arm_smmu_get_resv_regions(struct device *dev,
@@ -2858,7 +2860,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.probe_device		= arm_smmu_probe_device,
 	.release_device		= arm_smmu_release_device,
 	.device_group		= arm_smmu_device_group,
-	.of_xlate		= arm_smmu_of_xlate,
+	.of_xlate_fwspec	= arm_smmu_of_xlate_fwspec,
 	.get_resv_regions	= arm_smmu_get_resv_regions,
 	.remove_dev_pasid	= arm_smmu_remove_dev_pasid,
 	.dev_enable_feat	= arm_smmu_dev_enable_feature,
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 854efcb1b84ddf..8c4a60d8e5d522 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1510,7 +1510,9 @@ static int arm_smmu_set_pgtable_quirks(struct iommu_domain *domain,
 	return ret;
 }
 
-static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int arm_smmu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+				    struct device *dev,
+				    struct of_phandle_args *args)
 {
 	u32 mask, fwid = 0;
 
@@ -1522,7 +1524,7 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
 	else if (!of_property_read_u32(args->np, "stream-match-mask", &mask))
 		fwid |= FIELD_PREP(ARM_SMMU_SMR_MASK, mask);
 
-	return iommu_fwspec_add_ids(dev, &fwid, 1);
+	return iommu_fwspec_append_ids(fwspec, &fwid, 1);
 }
 
 static void arm_smmu_get_resv_regions(struct device *dev,
@@ -1562,7 +1564,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.release_device		= arm_smmu_release_device,
 	.probe_finalize		= arm_smmu_probe_finalize,
 	.device_group		= arm_smmu_device_group,
-	.of_xlate		= arm_smmu_of_xlate,
+	.of_xlate_fwspec	= arm_smmu_of_xlate_fwspec,
 	.get_resv_regions	= arm_smmu_get_resv_regions,
 	.def_domain_type	= arm_smmu_def_domain_type,
 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d14438ffb0feb7..9f23e113f46bc7 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3000,6 +3000,9 @@ int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 	if (ret)
 		return ret;
 
+	if (fwspec->ops->of_xlate_fwspec)
+		return fwspec->ops->of_xlate_fwspec(fwspec, dev, iommu_spec);
+
 	if (!fwspec->ops->of_xlate)
 		return -ENODEV;
 
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 379ebe03efb6d4..2283f1d1155981 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -1027,9 +1027,11 @@ static struct iommu_group *viommu_device_group(struct device *dev)
 		return generic_device_group(dev);
 }
 
-static int viommu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int viommu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+				  struct device *dev,
+				  struct of_phandle_args *args)
 {
-	return iommu_fwspec_add_ids(dev, args->args, 1);
+	return iommu_fwspec_append_ids(fwspec, args->args, 1);
 }
 
 static bool viommu_capable(struct device *dev, enum iommu_cap cap)
@@ -1050,7 +1052,7 @@ static struct iommu_ops viommu_ops = {
 	.release_device		= viommu_release_device,
 	.device_group		= viommu_device_group,
 	.get_resv_regions	= viommu_get_resv_regions,
-	.of_xlate		= viommu_of_xlate,
+	.of_xlate_fwspec	= viommu_of_xlate_fwspec,
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev		= viommu_attach_dev,
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 5e1f9222bde856..2fac54a942af54 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -41,6 +41,7 @@ struct notifier_block;
 struct iommu_sva;
 struct iommu_fault_event;
 struct iommu_dma_cookie;
+struct iommu_fwspec;
 
 /* iommu fault flags */
 #define IOMMU_FAULT_READ	0x0
@@ -287,6 +288,8 @@ struct iommu_ops {
 	/* Request/Free a list of reserved regions for a device */
 	void (*get_resv_regions)(struct device *dev, struct list_head *list);
 
+	int (*of_xlate_fwspec)(struct iommu_fwspec *fwspec, struct device *dev,
+			       struct of_phandle_args *args);
 	int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
 	bool (*is_attach_deferred)(struct device *dev);
 
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 15/17] iommu: Add ops->of_xlate_fwspec()
@ 2023-11-03 16:45   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:45 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

The new callback takes in the fwspec instead of retrieving it from the
dev->iommu. Provide iommu_fwspec_append_ids() to work directly on the
fwspec.

Convert SMMU, SMMUv3, and virtio to use iommu_fwspec_append_ids() and the
new entry point.

This avoids having to touch dev->iommu at all, and doesn't require the
iommu_probe_device_lock.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 +++++---
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 8 +++++---
 drivers/iommu/iommu.c                       | 3 +++
 drivers/iommu/virtio-iommu.c                | 8 +++++---
 include/linux/iommu.h                       | 3 +++
 5 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 7445454c2af244..b1309f04ebc0d9 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2748,9 +2748,11 @@ static int arm_smmu_enable_nesting(struct iommu_domain *domain)
 	return ret;
 }
 
-static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int arm_smmu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+				    struct device *dev,
+				    struct of_phandle_args *args)
 {
-	return iommu_fwspec_add_ids(dev, args->args, 1);
+	return iommu_fwspec_append_ids(fwspec, args->args, 1);
 }
 
 static void arm_smmu_get_resv_regions(struct device *dev,
@@ -2858,7 +2860,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.probe_device		= arm_smmu_probe_device,
 	.release_device		= arm_smmu_release_device,
 	.device_group		= arm_smmu_device_group,
-	.of_xlate		= arm_smmu_of_xlate,
+	.of_xlate_fwspec	= arm_smmu_of_xlate_fwspec,
 	.get_resv_regions	= arm_smmu_get_resv_regions,
 	.remove_dev_pasid	= arm_smmu_remove_dev_pasid,
 	.dev_enable_feat	= arm_smmu_dev_enable_feature,
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 854efcb1b84ddf..8c4a60d8e5d522 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1510,7 +1510,9 @@ static int arm_smmu_set_pgtable_quirks(struct iommu_domain *domain,
 	return ret;
 }
 
-static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int arm_smmu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+				    struct device *dev,
+				    struct of_phandle_args *args)
 {
 	u32 mask, fwid = 0;
 
@@ -1522,7 +1524,7 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
 	else if (!of_property_read_u32(args->np, "stream-match-mask", &mask))
 		fwid |= FIELD_PREP(ARM_SMMU_SMR_MASK, mask);
 
-	return iommu_fwspec_add_ids(dev, &fwid, 1);
+	return iommu_fwspec_append_ids(fwspec, &fwid, 1);
 }
 
 static void arm_smmu_get_resv_regions(struct device *dev,
@@ -1562,7 +1564,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.release_device		= arm_smmu_release_device,
 	.probe_finalize		= arm_smmu_probe_finalize,
 	.device_group		= arm_smmu_device_group,
-	.of_xlate		= arm_smmu_of_xlate,
+	.of_xlate_fwspec	= arm_smmu_of_xlate_fwspec,
 	.get_resv_regions	= arm_smmu_get_resv_regions,
 	.def_domain_type	= arm_smmu_def_domain_type,
 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d14438ffb0feb7..9f23e113f46bc7 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3000,6 +3000,9 @@ int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
 	if (ret)
 		return ret;
 
+	if (fwspec->ops->of_xlate_fwspec)
+		return fwspec->ops->of_xlate_fwspec(fwspec, dev, iommu_spec);
+
 	if (!fwspec->ops->of_xlate)
 		return -ENODEV;
 
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 379ebe03efb6d4..2283f1d1155981 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -1027,9 +1027,11 @@ static struct iommu_group *viommu_device_group(struct device *dev)
 		return generic_device_group(dev);
 }
 
-static int viommu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int viommu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+				  struct device *dev,
+				  struct of_phandle_args *args)
 {
-	return iommu_fwspec_add_ids(dev, args->args, 1);
+	return iommu_fwspec_append_ids(fwspec, args->args, 1);
 }
 
 static bool viommu_capable(struct device *dev, enum iommu_cap cap)
@@ -1050,7 +1052,7 @@ static struct iommu_ops viommu_ops = {
 	.release_device		= viommu_release_device,
 	.device_group		= viommu_device_group,
 	.get_resv_regions	= viommu_get_resv_regions,
-	.of_xlate		= viommu_of_xlate,
+	.of_xlate_fwspec	= viommu_of_xlate_fwspec,
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev		= viommu_attach_dev,
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 5e1f9222bde856..2fac54a942af54 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -41,6 +41,7 @@ struct notifier_block;
 struct iommu_sva;
 struct iommu_fault_event;
 struct iommu_dma_cookie;
+struct iommu_fwspec;
 
 /* iommu fault flags */
 #define IOMMU_FAULT_READ	0x0
@@ -287,6 +288,8 @@ struct iommu_ops {
 	/* Request/Free a list of reserved regions for a device */
 	void (*get_resv_regions)(struct device *dev, struct list_head *list);
 
+	int (*of_xlate_fwspec)(struct iommu_fwspec *fwspec, struct device *dev,
+			       struct of_phandle_args *args);
 	int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
 	bool (*is_attach_deferred)(struct device *dev);
 
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 16/17] iommu: Mark dev_iommu_get() with lockdep
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:45   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:45 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Allocation of dev->iommu must be done under the
iommu_probe_device_lock. Mark this with lockdep to discourage future
mistakes.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9f23e113f46bc7..1cf9f62c047c7d 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -345,6 +345,8 @@ static struct dev_iommu *dev_iommu_get(struct device *dev)
 {
 	struct dev_iommu *param = dev->iommu;
 
+	lockdep_assert_held(&iommu_probe_device_lock);
+
 	if (param)
 		return param;
 
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 16/17] iommu: Mark dev_iommu_get() with lockdep
@ 2023-11-03 16:45   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:45 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Allocation of dev->iommu must be done under the
iommu_probe_device_lock. Mark this with lockdep to discourage future
mistakes.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9f23e113f46bc7..1cf9f62c047c7d 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -345,6 +345,8 @@ static struct dev_iommu *dev_iommu_get(struct device *dev)
 {
 	struct dev_iommu *param = dev->iommu;
 
+	lockdep_assert_held(&iommu_probe_device_lock);
+
 	if (param)
 		return param;
 
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 16/17] iommu: Mark dev_iommu_get() with lockdep
@ 2023-11-03 16:45   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:45 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Allocation of dev->iommu must be done under the
iommu_probe_device_lock. Mark this with lockdep to discourage future
mistakes.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9f23e113f46bc7..1cf9f62c047c7d 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -345,6 +345,8 @@ static struct dev_iommu *dev_iommu_get(struct device *dev)
 {
 	struct dev_iommu *param = dev->iommu;
 
+	lockdep_assert_held(&iommu_probe_device_lock);
+
 	if (param)
 		return param;
 
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 16/17] iommu: Mark dev_iommu_get() with lockdep
@ 2023-11-03 16:45   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:45 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Allocation of dev->iommu must be done under the
iommu_probe_device_lock. Mark this with lockdep to discourage future
mistakes.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9f23e113f46bc7..1cf9f62c047c7d 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -345,6 +345,8 @@ static struct dev_iommu *dev_iommu_get(struct device *dev)
 {
 	struct dev_iommu *param = dev->iommu;
 
+	lockdep_assert_held(&iommu_probe_device_lock);
+
 	if (param)
 		return param;
 
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 16/17] iommu: Mark dev_iommu_get() with lockdep
@ 2023-11-03 16:45   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:45 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Allocation of dev->iommu must be done under the
iommu_probe_device_lock. Mark this with lockdep to discourage future
mistakes.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9f23e113f46bc7..1cf9f62c047c7d 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -345,6 +345,8 @@ static struct dev_iommu *dev_iommu_get(struct device *dev)
 {
 	struct dev_iommu *param = dev->iommu;
 
+	lockdep_assert_held(&iommu_probe_device_lock);
+
 	if (param)
 		return param;
 
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 17/17] iommu: Mark dev_iommu_priv_set() with a lockdep
  2023-11-03 16:44 ` Jason Gunthorpe
                     ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 16:45   ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:45 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

A perfect driver would only call dev_iommu_priv_set() from its probe
callback. We've made it functionally correct to call it from the of_xlate
by adding a lock around that call.

lockdep assert that iommu_probe_device_lock is held to discourage misuse.

Exclude PPC kernels with CONFIG_FSL_PAMU turned on because FSL_PAMU uses a
global static for its priv and abuses priv for its domain.

Remove the pointless stores of NULL, all these are on paths where the core
code will free dev->iommu after the op returns.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/amd/iommu.c                   | 2 --
 drivers/iommu/apple-dart.c                  | 1 -
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 -
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 1 -
 drivers/iommu/intel/iommu.c                 | 2 --
 drivers/iommu/iommu.c                       | 9 +++++++++
 drivers/iommu/omap-iommu.c                  | 1 -
 include/linux/iommu.h                       | 5 +----
 8 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 089886485895bc..604056eb0f5f8a 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -549,8 +549,6 @@ static void amd_iommu_uninit_device(struct device *dev)
 	if (dev_data->domain)
 		detach_device(dev);
 
-	dev_iommu_priv_set(dev, NULL);
-
 	/*
 	 * We keep dev_data around for unplugged devices and reuse it when the
 	 * device is re-plugged - not doing so would introduce a ton of races.
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index ee05f4824bfad1..56cfc33042e0b5 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -740,7 +740,6 @@ static void apple_dart_release_device(struct device *dev)
 {
 	struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev);
 
-	dev_iommu_priv_set(dev, NULL);
 	kfree(cfg);
 }
 
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index b1309f04ebc0d9..df81fcd25a75b0 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2698,7 +2698,6 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 err_free_master:
 	kfree(master);
-	dev_iommu_priv_set(dev, NULL);
 	return ERR_PTR(ret);
 }
 
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 8c4a60d8e5d522..6fc040a4168aa3 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1423,7 +1423,6 @@ static void arm_smmu_release_device(struct device *dev)
 
 	arm_smmu_rpm_put(cfg->smmu);
 
-	dev_iommu_priv_set(dev, NULL);
 	kfree(cfg);
 }
 
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index d5d191a71fe0d5..890c2cc9759b51 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4401,7 +4401,6 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev)
 		ret = intel_pasid_alloc_table(dev);
 		if (ret) {
 			dev_err(dev, "PASID table allocation failed\n");
-			dev_iommu_priv_set(dev, NULL);
 			kfree(info);
 			return ERR_PTR(ret);
 		}
@@ -4419,7 +4418,6 @@ static void intel_iommu_release_device(struct device *dev)
 	dmar_remove_one_dev_info(dev);
 	intel_pasid_free_table(dev);
 	intel_iommu_debugfs_remove_dev(info);
-	dev_iommu_priv_set(dev, NULL);
 	kfree(info);
 	set_dma_ops(dev, NULL);
 }
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 1cf9f62c047c7d..254cde45bc5c1c 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -387,6 +387,15 @@ static u32 dev_iommu_get_max_pasids(struct device *dev)
 	return min_t(u32, max_pasids, dev->iommu->iommu_dev->max_pasids);
 }
 
+void dev_iommu_priv_set(struct device *dev, void *priv)
+{
+	/* FSL_PAMU does something weird */
+	if (!IS_ENABLED(CONFIG_FSL_PAMU))
+		lockdep_assert_held(&iommu_probe_device_lock);
+	dev->iommu->priv = priv;
+}
+EXPORT_SYMBOL_GPL(dev_iommu_priv_set);
+
 /*
  * Init the dev->iommu and dev->iommu_group in the struct device and get the
  * driver probed. Take ownership of fwspec, it always freed on error
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index c66b070841dd41..c9528065a59afa 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1719,7 +1719,6 @@ static void omap_iommu_release_device(struct device *dev)
 	if (!dev->of_node || !arch_data)
 		return;
 
-	dev_iommu_priv_set(dev, NULL);
 	kfree(arch_data);
 
 }
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 2fac54a942af54..de52217ee4f4c0 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -722,10 +722,7 @@ static inline void *dev_iommu_priv_get(struct device *dev)
 		return NULL;
 }
 
-static inline void dev_iommu_priv_set(struct device *dev, void *priv)
-{
-	dev->iommu->priv = priv;
-}
+void dev_iommu_priv_set(struct device *dev, void *priv);
 
 int iommu_probe_device_fwspec(struct device *dev, struct iommu_fwspec *fwspec);
 static inline int iommu_probe_device(struct device *dev)
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 17/17] iommu: Mark dev_iommu_priv_set() with a lockdep
@ 2023-11-03 16:45   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:45 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

A perfect driver would only call dev_iommu_priv_set() from its probe
callback. We've made it functionally correct to call it from the of_xlate
by adding a lock around that call.

lockdep assert that iommu_probe_device_lock is held to discourage misuse.

Exclude PPC kernels with CONFIG_FSL_PAMU turned on because FSL_PAMU uses a
global static for its priv and abuses priv for its domain.

Remove the pointless stores of NULL, all these are on paths where the core
code will free dev->iommu after the op returns.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/amd/iommu.c                   | 2 --
 drivers/iommu/apple-dart.c                  | 1 -
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 -
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 1 -
 drivers/iommu/intel/iommu.c                 | 2 --
 drivers/iommu/iommu.c                       | 9 +++++++++
 drivers/iommu/omap-iommu.c                  | 1 -
 include/linux/iommu.h                       | 5 +----
 8 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 089886485895bc..604056eb0f5f8a 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -549,8 +549,6 @@ static void amd_iommu_uninit_device(struct device *dev)
 	if (dev_data->domain)
 		detach_device(dev);
 
-	dev_iommu_priv_set(dev, NULL);
-
 	/*
 	 * We keep dev_data around for unplugged devices and reuse it when the
 	 * device is re-plugged - not doing so would introduce a ton of races.
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index ee05f4824bfad1..56cfc33042e0b5 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -740,7 +740,6 @@ static void apple_dart_release_device(struct device *dev)
 {
 	struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev);
 
-	dev_iommu_priv_set(dev, NULL);
 	kfree(cfg);
 }
 
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index b1309f04ebc0d9..df81fcd25a75b0 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2698,7 +2698,6 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 err_free_master:
 	kfree(master);
-	dev_iommu_priv_set(dev, NULL);
 	return ERR_PTR(ret);
 }
 
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 8c4a60d8e5d522..6fc040a4168aa3 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1423,7 +1423,6 @@ static void arm_smmu_release_device(struct device *dev)
 
 	arm_smmu_rpm_put(cfg->smmu);
 
-	dev_iommu_priv_set(dev, NULL);
 	kfree(cfg);
 }
 
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index d5d191a71fe0d5..890c2cc9759b51 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4401,7 +4401,6 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev)
 		ret = intel_pasid_alloc_table(dev);
 		if (ret) {
 			dev_err(dev, "PASID table allocation failed\n");
-			dev_iommu_priv_set(dev, NULL);
 			kfree(info);
 			return ERR_PTR(ret);
 		}
@@ -4419,7 +4418,6 @@ static void intel_iommu_release_device(struct device *dev)
 	dmar_remove_one_dev_info(dev);
 	intel_pasid_free_table(dev);
 	intel_iommu_debugfs_remove_dev(info);
-	dev_iommu_priv_set(dev, NULL);
 	kfree(info);
 	set_dma_ops(dev, NULL);
 }
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 1cf9f62c047c7d..254cde45bc5c1c 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -387,6 +387,15 @@ static u32 dev_iommu_get_max_pasids(struct device *dev)
 	return min_t(u32, max_pasids, dev->iommu->iommu_dev->max_pasids);
 }
 
+void dev_iommu_priv_set(struct device *dev, void *priv)
+{
+	/* FSL_PAMU does something weird */
+	if (!IS_ENABLED(CONFIG_FSL_PAMU))
+		lockdep_assert_held(&iommu_probe_device_lock);
+	dev->iommu->priv = priv;
+}
+EXPORT_SYMBOL_GPL(dev_iommu_priv_set);
+
 /*
  * Init the dev->iommu and dev->iommu_group in the struct device and get the
  * driver probed. Take ownership of fwspec, it always freed on error
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index c66b070841dd41..c9528065a59afa 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1719,7 +1719,6 @@ static void omap_iommu_release_device(struct device *dev)
 	if (!dev->of_node || !arch_data)
 		return;
 
-	dev_iommu_priv_set(dev, NULL);
 	kfree(arch_data);
 
 }
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 2fac54a942af54..de52217ee4f4c0 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -722,10 +722,7 @@ static inline void *dev_iommu_priv_get(struct device *dev)
 		return NULL;
 }
 
-static inline void dev_iommu_priv_set(struct device *dev, void *priv)
-{
-	dev->iommu->priv = priv;
-}
+void dev_iommu_priv_set(struct device *dev, void *priv);
 
 int iommu_probe_device_fwspec(struct device *dev, struct iommu_fwspec *fwspec);
 static inline int iommu_probe_device(struct device *dev)
-- 
2.42.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 17/17] iommu: Mark dev_iommu_priv_set() with a lockdep
@ 2023-11-03 16:45   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:45 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

A perfect driver would only call dev_iommu_priv_set() from its probe
callback. We've made it functionally correct to call it from the of_xlate
by adding a lock around that call.

lockdep assert that iommu_probe_device_lock is held to discourage misuse.

Exclude PPC kernels with CONFIG_FSL_PAMU turned on because FSL_PAMU uses a
global static for its priv and abuses priv for its domain.

Remove the pointless stores of NULL, all these are on paths where the core
code will free dev->iommu after the op returns.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/amd/iommu.c                   | 2 --
 drivers/iommu/apple-dart.c                  | 1 -
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 -
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 1 -
 drivers/iommu/intel/iommu.c                 | 2 --
 drivers/iommu/iommu.c                       | 9 +++++++++
 drivers/iommu/omap-iommu.c                  | 1 -
 include/linux/iommu.h                       | 5 +----
 8 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 089886485895bc..604056eb0f5f8a 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -549,8 +549,6 @@ static void amd_iommu_uninit_device(struct device *dev)
 	if (dev_data->domain)
 		detach_device(dev);
 
-	dev_iommu_priv_set(dev, NULL);
-
 	/*
 	 * We keep dev_data around for unplugged devices and reuse it when the
 	 * device is re-plugged - not doing so would introduce a ton of races.
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index ee05f4824bfad1..56cfc33042e0b5 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -740,7 +740,6 @@ static void apple_dart_release_device(struct device *dev)
 {
 	struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev);
 
-	dev_iommu_priv_set(dev, NULL);
 	kfree(cfg);
 }
 
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index b1309f04ebc0d9..df81fcd25a75b0 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2698,7 +2698,6 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 err_free_master:
 	kfree(master);
-	dev_iommu_priv_set(dev, NULL);
 	return ERR_PTR(ret);
 }
 
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 8c4a60d8e5d522..6fc040a4168aa3 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1423,7 +1423,6 @@ static void arm_smmu_release_device(struct device *dev)
 
 	arm_smmu_rpm_put(cfg->smmu);
 
-	dev_iommu_priv_set(dev, NULL);
 	kfree(cfg);
 }
 
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index d5d191a71fe0d5..890c2cc9759b51 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4401,7 +4401,6 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev)
 		ret = intel_pasid_alloc_table(dev);
 		if (ret) {
 			dev_err(dev, "PASID table allocation failed\n");
-			dev_iommu_priv_set(dev, NULL);
 			kfree(info);
 			return ERR_PTR(ret);
 		}
@@ -4419,7 +4418,6 @@ static void intel_iommu_release_device(struct device *dev)
 	dmar_remove_one_dev_info(dev);
 	intel_pasid_free_table(dev);
 	intel_iommu_debugfs_remove_dev(info);
-	dev_iommu_priv_set(dev, NULL);
 	kfree(info);
 	set_dma_ops(dev, NULL);
 }
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 1cf9f62c047c7d..254cde45bc5c1c 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -387,6 +387,15 @@ static u32 dev_iommu_get_max_pasids(struct device *dev)
 	return min_t(u32, max_pasids, dev->iommu->iommu_dev->max_pasids);
 }
 
+void dev_iommu_priv_set(struct device *dev, void *priv)
+{
+	/* FSL_PAMU does something weird */
+	if (!IS_ENABLED(CONFIG_FSL_PAMU))
+		lockdep_assert_held(&iommu_probe_device_lock);
+	dev->iommu->priv = priv;
+}
+EXPORT_SYMBOL_GPL(dev_iommu_priv_set);
+
 /*
  * Init the dev->iommu and dev->iommu_group in the struct device and get the
  * driver probed. Take ownership of fwspec, it always freed on error
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index c66b070841dd41..c9528065a59afa 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1719,7 +1719,6 @@ static void omap_iommu_release_device(struct device *dev)
 	if (!dev->of_node || !arch_data)
 		return;
 
-	dev_iommu_priv_set(dev, NULL);
 	kfree(arch_data);
 
 }
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 2fac54a942af54..de52217ee4f4c0 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -722,10 +722,7 @@ static inline void *dev_iommu_priv_get(struct device *dev)
 		return NULL;
 }
 
-static inline void dev_iommu_priv_set(struct device *dev, void *priv)
-{
-	dev->iommu->priv = priv;
-}
+void dev_iommu_priv_set(struct device *dev, void *priv);
 
 int iommu_probe_device_fwspec(struct device *dev, struct iommu_fwspec *fwspec);
 static inline int iommu_probe_device(struct device *dev)
-- 
2.42.0


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [PATCH RFC 17/17] iommu: Mark dev_iommu_priv_set() with a lockdep
@ 2023-11-03 16:45   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:45 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

A perfect driver would only call dev_iommu_priv_set() from its probe
callback. We've made it functionally correct to call it from the of_xlate
by adding a lock around that call.

lockdep assert that iommu_probe_device_lock is held to discourage misuse.

Exclude PPC kernels with CONFIG_FSL_PAMU turned on because FSL_PAMU uses a
global static for its priv and abuses priv for its domain.

Remove the pointless stores of NULL, all these are on paths where the core
code will free dev->iommu after the op returns.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/amd/iommu.c                   | 2 --
 drivers/iommu/apple-dart.c                  | 1 -
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 -
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 1 -
 drivers/iommu/intel/iommu.c                 | 2 --
 drivers/iommu/iommu.c                       | 9 +++++++++
 drivers/iommu/omap-iommu.c                  | 1 -
 include/linux/iommu.h                       | 5 +----
 8 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 089886485895bc..604056eb0f5f8a 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -549,8 +549,6 @@ static void amd_iommu_uninit_device(struct device *dev)
 	if (dev_data->domain)
 		detach_device(dev);
 
-	dev_iommu_priv_set(dev, NULL);
-
 	/*
 	 * We keep dev_data around for unplugged devices and reuse it when the
 	 * device is re-plugged - not doing so would introduce a ton of races.
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index ee05f4824bfad1..56cfc33042e0b5 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -740,7 +740,6 @@ static void apple_dart_release_device(struct device *dev)
 {
 	struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev);
 
-	dev_iommu_priv_set(dev, NULL);
 	kfree(cfg);
 }
 
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index b1309f04ebc0d9..df81fcd25a75b0 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2698,7 +2698,6 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 err_free_master:
 	kfree(master);
-	dev_iommu_priv_set(dev, NULL);
 	return ERR_PTR(ret);
 }
 
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 8c4a60d8e5d522..6fc040a4168aa3 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1423,7 +1423,6 @@ static void arm_smmu_release_device(struct device *dev)
 
 	arm_smmu_rpm_put(cfg->smmu);
 
-	dev_iommu_priv_set(dev, NULL);
 	kfree(cfg);
 }
 
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index d5d191a71fe0d5..890c2cc9759b51 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4401,7 +4401,6 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev)
 		ret = intel_pasid_alloc_table(dev);
 		if (ret) {
 			dev_err(dev, "PASID table allocation failed\n");
-			dev_iommu_priv_set(dev, NULL);
 			kfree(info);
 			return ERR_PTR(ret);
 		}
@@ -4419,7 +4418,6 @@ static void intel_iommu_release_device(struct device *dev)
 	dmar_remove_one_dev_info(dev);
 	intel_pasid_free_table(dev);
 	intel_iommu_debugfs_remove_dev(info);
-	dev_iommu_priv_set(dev, NULL);
 	kfree(info);
 	set_dma_ops(dev, NULL);
 }
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 1cf9f62c047c7d..254cde45bc5c1c 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -387,6 +387,15 @@ static u32 dev_iommu_get_max_pasids(struct device *dev)
 	return min_t(u32, max_pasids, dev->iommu->iommu_dev->max_pasids);
 }
 
+void dev_iommu_priv_set(struct device *dev, void *priv)
+{
+	/* FSL_PAMU does something weird */
+	if (!IS_ENABLED(CONFIG_FSL_PAMU))
+		lockdep_assert_held(&iommu_probe_device_lock);
+	dev->iommu->priv = priv;
+}
+EXPORT_SYMBOL_GPL(dev_iommu_priv_set);
+
 /*
  * Init the dev->iommu and dev->iommu_group in the struct device and get the
  * driver probed. Take ownership of fwspec, it always freed on error
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index c66b070841dd41..c9528065a59afa 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1719,7 +1719,6 @@ static void omap_iommu_release_device(struct device *dev)
 	if (!dev->of_node || !arch_data)
 		return;
 
-	dev_iommu_priv_set(dev, NULL);
 	kfree(arch_data);
 
 }
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 2fac54a942af54..de52217ee4f4c0 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -722,10 +722,7 @@ static inline void *dev_iommu_priv_get(struct device *dev)
 		return NULL;
 }
 
-static inline void dev_iommu_priv_set(struct device *dev, void *priv)
-{
-	dev->iommu->priv = priv;
-}
+void dev_iommu_priv_set(struct device *dev, void *priv);
 
 int iommu_probe_device_fwspec(struct device *dev, struct iommu_fwspec *fwspec);
 static inline int iommu_probe_device(struct device *dev)
-- 
2.42.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* [Acpica-devel] [PATCH RFC 17/17] iommu: Mark dev_iommu_priv_set() with a lockdep
@ 2023-11-03 16:45   ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-03 16:45 UTC (permalink / raw)
  To: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

A perfect driver would only call dev_iommu_priv_set() from its probe
callback. We've made it functionally correct to call it from the of_xlate
by adding a lock around that call.

lockdep assert that iommu_probe_device_lock is held to discourage misuse.

Exclude PPC kernels with CONFIG_FSL_PAMU turned on because FSL_PAMU uses a
global static for its priv and abuses priv for its domain.

Remove the pointless stores of NULL, all these are on paths where the core
code will free dev->iommu after the op returns.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/amd/iommu.c                   | 2 --
 drivers/iommu/apple-dart.c                  | 1 -
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 -
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 1 -
 drivers/iommu/intel/iommu.c                 | 2 --
 drivers/iommu/iommu.c                       | 9 +++++++++
 drivers/iommu/omap-iommu.c                  | 1 -
 include/linux/iommu.h                       | 5 +----
 8 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 089886485895bc..604056eb0f5f8a 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -549,8 +549,6 @@ static void amd_iommu_uninit_device(struct device *dev)
 	if (dev_data->domain)
 		detach_device(dev);
 
-	dev_iommu_priv_set(dev, NULL);
-
 	/*
 	 * We keep dev_data around for unplugged devices and reuse it when the
 	 * device is re-plugged - not doing so would introduce a ton of races.
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index ee05f4824bfad1..56cfc33042e0b5 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -740,7 +740,6 @@ static void apple_dart_release_device(struct device *dev)
 {
 	struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev);
 
-	dev_iommu_priv_set(dev, NULL);
 	kfree(cfg);
 }
 
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index b1309f04ebc0d9..df81fcd25a75b0 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2698,7 +2698,6 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 err_free_master:
 	kfree(master);
-	dev_iommu_priv_set(dev, NULL);
 	return ERR_PTR(ret);
 }
 
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 8c4a60d8e5d522..6fc040a4168aa3 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1423,7 +1423,6 @@ static void arm_smmu_release_device(struct device *dev)
 
 	arm_smmu_rpm_put(cfg->smmu);
 
-	dev_iommu_priv_set(dev, NULL);
 	kfree(cfg);
 }
 
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index d5d191a71fe0d5..890c2cc9759b51 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4401,7 +4401,6 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev)
 		ret = intel_pasid_alloc_table(dev);
 		if (ret) {
 			dev_err(dev, "PASID table allocation failed\n");
-			dev_iommu_priv_set(dev, NULL);
 			kfree(info);
 			return ERR_PTR(ret);
 		}
@@ -4419,7 +4418,6 @@ static void intel_iommu_release_device(struct device *dev)
 	dmar_remove_one_dev_info(dev);
 	intel_pasid_free_table(dev);
 	intel_iommu_debugfs_remove_dev(info);
-	dev_iommu_priv_set(dev, NULL);
 	kfree(info);
 	set_dma_ops(dev, NULL);
 }
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 1cf9f62c047c7d..254cde45bc5c1c 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -387,6 +387,15 @@ static u32 dev_iommu_get_max_pasids(struct device *dev)
 	return min_t(u32, max_pasids, dev->iommu->iommu_dev->max_pasids);
 }
 
+void dev_iommu_priv_set(struct device *dev, void *priv)
+{
+	/* FSL_PAMU does something weird */
+	if (!IS_ENABLED(CONFIG_FSL_PAMU))
+		lockdep_assert_held(&iommu_probe_device_lock);
+	dev->iommu->priv = priv;
+}
+EXPORT_SYMBOL_GPL(dev_iommu_priv_set);
+
 /*
  * Init the dev->iommu and dev->iommu_group in the struct device and get the
  * driver probed. Take ownership of fwspec, it always freed on error
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index c66b070841dd41..c9528065a59afa 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1719,7 +1719,6 @@ static void omap_iommu_release_device(struct device *dev)
 	if (!dev->of_node || !arch_data)
 		return;
 
-	dev_iommu_priv_set(dev, NULL);
 	kfree(arch_data);
 
 }
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 2fac54a942af54..de52217ee4f4c0 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -722,10 +722,7 @@ static inline void *dev_iommu_priv_get(struct device *dev)
 		return NULL;
 }
 
-static inline void dev_iommu_priv_set(struct device *dev, void *priv)
-{
-	dev->iommu->priv = priv;
-}
+void dev_iommu_priv_set(struct device *dev, void *priv);
 
 int iommu_probe_device_fwspec(struct device *dev, struct iommu_fwspec *fwspec);
 static inline int iommu_probe_device(struct device *dev)
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
  2023-11-03 16:44   ` Jason Gunthorpe
                       ` (2 preceding siblings ...)
  (?)
@ 2023-11-03 20:04     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 20:04 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang



Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-03 20:04     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 20:04 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang



Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-03 20:04     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 20:04 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang



Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-03 20:04     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 20:04 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang



Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [Acpica-devel] [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-03 20:04     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 20:04 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: linux-hyperv, Catalin Marinas, Lorenzo Pieralisi, Robert Moore,
	Thierry Reding, Hanjun Guo, acpica-devel, K. Y. Srinivasan,
	Frank Rowand, Christoph Hellwig, Alyssa Rosenzweig,
	Marek Szyprowski, Jean-Philippe Brucker, Wei Liu, Will Deacon,
	Joerg Roedel, Dexuan Cui, Russell King, linux-riscv,
	Jonathan Hunter, linux-acpi, iommu, Vineet Gupta, linux-snps-arc,
	Len Brown, devicetree, Albert Ou, Sven Peter, Haiyang Zhang,
	Krishna Reddy, Rob Herring, Paul Walmsley, linux-tegra,
	virtualization, linux-arm-kernel, Thomas Bogendoerfer,
	Robin Murphy, Zhenhua Huang, Hector Martin, linux-mips,
	Palmer Dabbelt, asahi, Suravee Suthikulpanit, Sudeep Holla,
	David Woodhouse, Lu Baolu



Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-03 21:42     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 21:42 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:47PM -0300, Jason Gunthorpe wrote:
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
>  drivers/of/device.c      | 22 +++++++++++++++-------
>  include/linux/of_iommu.h | 13 ++++++-------
>  3 files changed, 39 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 157b286e36bf3a..e2fa29c16dd758 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
>  		      of_iommu_configure_dev(master_np, dev);
>  }
>  
> -const struct iommu_ops *of_iommu_configure(struct device *dev,
> -					   struct device_node *master_np,
> -					   const u32 *id)
> +/*
> + * Returns:
> + *  0 on success, an iommu was configured
> + *  -ENODEV if the device does not have any IOMMU
> + *  -EPROBEDEFER if probing should be tried again
> + *  -errno fatal errors

It looks to me like it will only return 0, -ENODEV, or -EPROBEDEFER
with other -errno getting boiled down to -ENODEV.

> + */
> +int of_iommu_configure(struct device *dev, struct device_node *master_np,
> +		       const u32 *id)
>  {
>  	const struct iommu_ops *ops = NULL;
>  	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
>  	int err = NO_IOMMU;
>  
>  	if (!master_np)
> -		return NULL;
> +		return -ENODEV;
>  
>  	if (fwspec) {
>  		if (fwspec->ops)
> -			return fwspec->ops;
> +			return 0;
>  
>  		/* In the deferred case, start again from scratch */
>  		iommu_fwspec_free(dev);
> @@ -163,14 +169,15 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
>  		err = iommu_probe_device(dev);
>  
>  	/* Ignore all other errors apart from EPROBE_DEFER */
> -	if (err == -EPROBE_DEFER) {
> -		ops = ERR_PTR(err);
> -	} else if (err < 0) {
> +	if (err < 0) {
> +		if (err == -EPROBE_DEFER)
> +			return err;
>  		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);

minor thing, but should this use %pe and ERR_PTR(err) like is done
in of_dma_configure_id?

> -		ops = NULL;
> +		return -ENODEV;
>  	}
> -
> -	return ops;
> +	if (!ops)
> +		return -ENODEV;
> +	return 0;
>  }
>  
>  static enum iommu_resv_type __maybe_unused
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index 65c71be71a8d45..873d933e8e6d1d 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -93,12 +93,12 @@ of_dma_set_restricted_buffer(struct device *dev, struct device_node *np)
>  int of_dma_configure_id(struct device *dev, struct device_node *np,
>  			bool force_dma, const u32 *id)
>  {
> -	const struct iommu_ops *iommu;
>  	const struct bus_dma_region *map = NULL;
>  	struct device_node *bus_np;
>  	u64 dma_start = 0;
>  	u64 mask, end, size = 0;
>  	bool coherent;
> +	int iommu_ret;
>  	int ret;
>  
>  	if (np == dev->of_node)
> @@ -181,21 +181,29 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
>  	dev_dbg(dev, "device is%sdma coherent\n",
>  		coherent ? " " : " not ");
>  
> -	iommu = of_iommu_configure(dev, np, id);
> -	if (PTR_ERR(iommu) == -EPROBE_DEFER) {
> +	iommu_ret = of_iommu_configure(dev, np, id);
> +	if (iommu_ret == -EPROBE_DEFER) {
>  		/* Don't touch range map if it wasn't set from a valid dma-ranges */
>  		if (!ret)
>  			dev->dma_range_map = NULL;
>  		kfree(map);
>  		return -EPROBE_DEFER;
> -	}
> +	} else if (iommu_ret == -ENODEV) {
> +		dev_dbg(dev, "device is not behind an iommu\n");
> +	} else if (iommu_ret) {
> +		dev_err(dev, "iommu configuration for device failed with %pe\n",
> +			ERR_PTR(iommu_ret));
>  
> -	dev_dbg(dev, "device is%sbehind an iommu\n",
> -		iommu ? " " : " not ");
> +		/*
> +		 * Historically this routine doesn't fail driver probing
> +		 * due to errors in of_iommu_configure()
> +		 */
> +	} else
> +		dev_dbg(dev, "device is behind an iommu\n");
>  
>  	arch_setup_dma_ops(dev, dma_start, size, coherent);
>  
> -	if (!iommu)
> +	if (iommu_ret)
>  		of_dma_set_restricted_buffer(dev, np);
>  
>  	return 0;
> diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
> index 9a5e6b410dd2fb..e61cbbe12dac6f 100644
> --- a/include/linux/of_iommu.h
> +++ b/include/linux/of_iommu.h
> @@ -8,20 +8,19 @@ struct iommu_ops;
>  
>  #ifdef CONFIG_OF_IOMMU
>  
> -extern const struct iommu_ops *of_iommu_configure(struct device *dev,
> -					struct device_node *master_np,
> -					const u32 *id);
> +extern int of_iommu_configure(struct device *dev, struct device_node *master_np,
> +			      const u32 *id);
>  
>  extern void of_iommu_get_resv_regions(struct device *dev,
>  				      struct list_head *list);
>  
>  #else
>  
> -static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
> -					 struct device_node *master_np,
> -					 const u32 *id)
> +static inline int of_iommu_configure(struct device *dev,
> +				     struct device_node *master_np,
> +				     const u32 *id)
>  {
> -	return NULL;
> +	return -ENODEV;
>  }
>  
>  static inline void of_iommu_get_resv_regions(struct device *dev,
> -- 
> 2.42.0
> 


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
@ 2023-11-03 21:42     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 21:42 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:47PM -0300, Jason Gunthorpe wrote:
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
>  drivers/of/device.c      | 22 +++++++++++++++-------
>  include/linux/of_iommu.h | 13 ++++++-------
>  3 files changed, 39 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 157b286e36bf3a..e2fa29c16dd758 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
>  		      of_iommu_configure_dev(master_np, dev);
>  }
>  
> -const struct iommu_ops *of_iommu_configure(struct device *dev,
> -					   struct device_node *master_np,
> -					   const u32 *id)
> +/*
> + * Returns:
> + *  0 on success, an iommu was configured
> + *  -ENODEV if the device does not have any IOMMU
> + *  -EPROBEDEFER if probing should be tried again
> + *  -errno fatal errors

It looks to me like it will only return 0, -ENODEV, or -EPROBEDEFER
with other -errno getting boiled down to -ENODEV.

> + */
> +int of_iommu_configure(struct device *dev, struct device_node *master_np,
> +		       const u32 *id)
>  {
>  	const struct iommu_ops *ops = NULL;
>  	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
>  	int err = NO_IOMMU;
>  
>  	if (!master_np)
> -		return NULL;
> +		return -ENODEV;
>  
>  	if (fwspec) {
>  		if (fwspec->ops)
> -			return fwspec->ops;
> +			return 0;
>  
>  		/* In the deferred case, start again from scratch */
>  		iommu_fwspec_free(dev);
> @@ -163,14 +169,15 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
>  		err = iommu_probe_device(dev);
>  
>  	/* Ignore all other errors apart from EPROBE_DEFER */
> -	if (err == -EPROBE_DEFER) {
> -		ops = ERR_PTR(err);
> -	} else if (err < 0) {
> +	if (err < 0) {
> +		if (err == -EPROBE_DEFER)
> +			return err;
>  		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);

minor thing, but should this use %pe and ERR_PTR(err) like is done
in of_dma_configure_id?

> -		ops = NULL;
> +		return -ENODEV;
>  	}
> -
> -	return ops;
> +	if (!ops)
> +		return -ENODEV;
> +	return 0;
>  }
>  
>  static enum iommu_resv_type __maybe_unused
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index 65c71be71a8d45..873d933e8e6d1d 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -93,12 +93,12 @@ of_dma_set_restricted_buffer(struct device *dev, struct device_node *np)
>  int of_dma_configure_id(struct device *dev, struct device_node *np,
>  			bool force_dma, const u32 *id)
>  {
> -	const struct iommu_ops *iommu;
>  	const struct bus_dma_region *map = NULL;
>  	struct device_node *bus_np;
>  	u64 dma_start = 0;
>  	u64 mask, end, size = 0;
>  	bool coherent;
> +	int iommu_ret;
>  	int ret;
>  
>  	if (np == dev->of_node)
> @@ -181,21 +181,29 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
>  	dev_dbg(dev, "device is%sdma coherent\n",
>  		coherent ? " " : " not ");
>  
> -	iommu = of_iommu_configure(dev, np, id);
> -	if (PTR_ERR(iommu) == -EPROBE_DEFER) {
> +	iommu_ret = of_iommu_configure(dev, np, id);
> +	if (iommu_ret == -EPROBE_DEFER) {
>  		/* Don't touch range map if it wasn't set from a valid dma-ranges */
>  		if (!ret)
>  			dev->dma_range_map = NULL;
>  		kfree(map);
>  		return -EPROBE_DEFER;
> -	}
> +	} else if (iommu_ret == -ENODEV) {
> +		dev_dbg(dev, "device is not behind an iommu\n");
> +	} else if (iommu_ret) {
> +		dev_err(dev, "iommu configuration for device failed with %pe\n",
> +			ERR_PTR(iommu_ret));
>  
> -	dev_dbg(dev, "device is%sbehind an iommu\n",
> -		iommu ? " " : " not ");
> +		/*
> +		 * Historically this routine doesn't fail driver probing
> +		 * due to errors in of_iommu_configure()
> +		 */
> +	} else
> +		dev_dbg(dev, "device is behind an iommu\n");
>  
>  	arch_setup_dma_ops(dev, dma_start, size, coherent);
>  
> -	if (!iommu)
> +	if (iommu_ret)
>  		of_dma_set_restricted_buffer(dev, np);
>  
>  	return 0;
> diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
> index 9a5e6b410dd2fb..e61cbbe12dac6f 100644
> --- a/include/linux/of_iommu.h
> +++ b/include/linux/of_iommu.h
> @@ -8,20 +8,19 @@ struct iommu_ops;
>  
>  #ifdef CONFIG_OF_IOMMU
>  
> -extern const struct iommu_ops *of_iommu_configure(struct device *dev,
> -					struct device_node *master_np,
> -					const u32 *id);
> +extern int of_iommu_configure(struct device *dev, struct device_node *master_np,
> +			      const u32 *id);
>  
>  extern void of_iommu_get_resv_regions(struct device *dev,
>  				      struct list_head *list);
>  
>  #else
>  
> -static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
> -					 struct device_node *master_np,
> -					 const u32 *id)
> +static inline int of_iommu_configure(struct device *dev,
> +				     struct device_node *master_np,
> +				     const u32 *id)
>  {
> -	return NULL;
> +	return -ENODEV;
>  }
>  
>  static inline void of_iommu_get_resv_regions(struct device *dev,
> -- 
> 2.42.0
> 


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
@ 2023-11-03 21:42     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 21:42 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:47PM -0300, Jason Gunthorpe wrote:
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
>  drivers/of/device.c      | 22 +++++++++++++++-------
>  include/linux/of_iommu.h | 13 ++++++-------
>  3 files changed, 39 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 157b286e36bf3a..e2fa29c16dd758 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
>  		      of_iommu_configure_dev(master_np, dev);
>  }
>  
> -const struct iommu_ops *of_iommu_configure(struct device *dev,
> -					   struct device_node *master_np,
> -					   const u32 *id)
> +/*
> + * Returns:
> + *  0 on success, an iommu was configured
> + *  -ENODEV if the device does not have any IOMMU
> + *  -EPROBEDEFER if probing should be tried again
> + *  -errno fatal errors

It looks to me like it will only return 0, -ENODEV, or -EPROBEDEFER
with other -errno getting boiled down to -ENODEV.

> + */
> +int of_iommu_configure(struct device *dev, struct device_node *master_np,
> +		       const u32 *id)
>  {
>  	const struct iommu_ops *ops = NULL;
>  	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
>  	int err = NO_IOMMU;
>  
>  	if (!master_np)
> -		return NULL;
> +		return -ENODEV;
>  
>  	if (fwspec) {
>  		if (fwspec->ops)
> -			return fwspec->ops;
> +			return 0;
>  
>  		/* In the deferred case, start again from scratch */
>  		iommu_fwspec_free(dev);
> @@ -163,14 +169,15 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
>  		err = iommu_probe_device(dev);
>  
>  	/* Ignore all other errors apart from EPROBE_DEFER */
> -	if (err == -EPROBE_DEFER) {
> -		ops = ERR_PTR(err);
> -	} else if (err < 0) {
> +	if (err < 0) {
> +		if (err == -EPROBE_DEFER)
> +			return err;
>  		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);

minor thing, but should this use %pe and ERR_PTR(err) like is done
in of_dma_configure_id?

> -		ops = NULL;
> +		return -ENODEV;
>  	}
> -
> -	return ops;
> +	if (!ops)
> +		return -ENODEV;
> +	return 0;
>  }
>  
>  static enum iommu_resv_type __maybe_unused
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index 65c71be71a8d45..873d933e8e6d1d 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -93,12 +93,12 @@ of_dma_set_restricted_buffer(struct device *dev, struct device_node *np)
>  int of_dma_configure_id(struct device *dev, struct device_node *np,
>  			bool force_dma, const u32 *id)
>  {
> -	const struct iommu_ops *iommu;
>  	const struct bus_dma_region *map = NULL;
>  	struct device_node *bus_np;
>  	u64 dma_start = 0;
>  	u64 mask, end, size = 0;
>  	bool coherent;
> +	int iommu_ret;
>  	int ret;
>  
>  	if (np == dev->of_node)
> @@ -181,21 +181,29 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
>  	dev_dbg(dev, "device is%sdma coherent\n",
>  		coherent ? " " : " not ");
>  
> -	iommu = of_iommu_configure(dev, np, id);
> -	if (PTR_ERR(iommu) == -EPROBE_DEFER) {
> +	iommu_ret = of_iommu_configure(dev, np, id);
> +	if (iommu_ret == -EPROBE_DEFER) {
>  		/* Don't touch range map if it wasn't set from a valid dma-ranges */
>  		if (!ret)
>  			dev->dma_range_map = NULL;
>  		kfree(map);
>  		return -EPROBE_DEFER;
> -	}
> +	} else if (iommu_ret == -ENODEV) {
> +		dev_dbg(dev, "device is not behind an iommu\n");
> +	} else if (iommu_ret) {
> +		dev_err(dev, "iommu configuration for device failed with %pe\n",
> +			ERR_PTR(iommu_ret));
>  
> -	dev_dbg(dev, "device is%sbehind an iommu\n",
> -		iommu ? " " : " not ");
> +		/*
> +		 * Historically this routine doesn't fail driver probing
> +		 * due to errors in of_iommu_configure()
> +		 */
> +	} else
> +		dev_dbg(dev, "device is behind an iommu\n");
>  
>  	arch_setup_dma_ops(dev, dma_start, size, coherent);
>  
> -	if (!iommu)
> +	if (iommu_ret)
>  		of_dma_set_restricted_buffer(dev, np);
>  
>  	return 0;
> diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
> index 9a5e6b410dd2fb..e61cbbe12dac6f 100644
> --- a/include/linux/of_iommu.h
> +++ b/include/linux/of_iommu.h
> @@ -8,20 +8,19 @@ struct iommu_ops;
>  
>  #ifdef CONFIG_OF_IOMMU
>  
> -extern const struct iommu_ops *of_iommu_configure(struct device *dev,
> -					struct device_node *master_np,
> -					const u32 *id);
> +extern int of_iommu_configure(struct device *dev, struct device_node *master_np,
> +			      const u32 *id);
>  
>  extern void of_iommu_get_resv_regions(struct device *dev,
>  				      struct list_head *list);
>  
>  #else
>  
> -static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
> -					 struct device_node *master_np,
> -					 const u32 *id)
> +static inline int of_iommu_configure(struct device *dev,
> +				     struct device_node *master_np,
> +				     const u32 *id)
>  {
> -	return NULL;
> +	return -ENODEV;
>  }
>  
>  static inline void of_iommu_get_resv_regions(struct device *dev,
> -- 
> 2.42.0
> 


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
@ 2023-11-03 21:42     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 21:42 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:47PM -0300, Jason Gunthorpe wrote:
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
>  drivers/of/device.c      | 22 +++++++++++++++-------
>  include/linux/of_iommu.h | 13 ++++++-------
>  3 files changed, 39 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 157b286e36bf3a..e2fa29c16dd758 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
>  		      of_iommu_configure_dev(master_np, dev);
>  }
>  
> -const struct iommu_ops *of_iommu_configure(struct device *dev,
> -					   struct device_node *master_np,
> -					   const u32 *id)
> +/*
> + * Returns:
> + *  0 on success, an iommu was configured
> + *  -ENODEV if the device does not have any IOMMU
> + *  -EPROBEDEFER if probing should be tried again
> + *  -errno fatal errors

It looks to me like it will only return 0, -ENODEV, or -EPROBEDEFER
with other -errno getting boiled down to -ENODEV.

> + */
> +int of_iommu_configure(struct device *dev, struct device_node *master_np,
> +		       const u32 *id)
>  {
>  	const struct iommu_ops *ops = NULL;
>  	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
>  	int err = NO_IOMMU;
>  
>  	if (!master_np)
> -		return NULL;
> +		return -ENODEV;
>  
>  	if (fwspec) {
>  		if (fwspec->ops)
> -			return fwspec->ops;
> +			return 0;
>  
>  		/* In the deferred case, start again from scratch */
>  		iommu_fwspec_free(dev);
> @@ -163,14 +169,15 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
>  		err = iommu_probe_device(dev);
>  
>  	/* Ignore all other errors apart from EPROBE_DEFER */
> -	if (err == -EPROBE_DEFER) {
> -		ops = ERR_PTR(err);
> -	} else if (err < 0) {
> +	if (err < 0) {
> +		if (err == -EPROBE_DEFER)
> +			return err;
>  		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);

minor thing, but should this use %pe and ERR_PTR(err) like is done
in of_dma_configure_id?

> -		ops = NULL;
> +		return -ENODEV;
>  	}
> -
> -	return ops;
> +	if (!ops)
> +		return -ENODEV;
> +	return 0;
>  }
>  
>  static enum iommu_resv_type __maybe_unused
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index 65c71be71a8d45..873d933e8e6d1d 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -93,12 +93,12 @@ of_dma_set_restricted_buffer(struct device *dev, struct device_node *np)
>  int of_dma_configure_id(struct device *dev, struct device_node *np,
>  			bool force_dma, const u32 *id)
>  {
> -	const struct iommu_ops *iommu;
>  	const struct bus_dma_region *map = NULL;
>  	struct device_node *bus_np;
>  	u64 dma_start = 0;
>  	u64 mask, end, size = 0;
>  	bool coherent;
> +	int iommu_ret;
>  	int ret;
>  
>  	if (np == dev->of_node)
> @@ -181,21 +181,29 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
>  	dev_dbg(dev, "device is%sdma coherent\n",
>  		coherent ? " " : " not ");
>  
> -	iommu = of_iommu_configure(dev, np, id);
> -	if (PTR_ERR(iommu) == -EPROBE_DEFER) {
> +	iommu_ret = of_iommu_configure(dev, np, id);
> +	if (iommu_ret == -EPROBE_DEFER) {
>  		/* Don't touch range map if it wasn't set from a valid dma-ranges */
>  		if (!ret)
>  			dev->dma_range_map = NULL;
>  		kfree(map);
>  		return -EPROBE_DEFER;
> -	}
> +	} else if (iommu_ret == -ENODEV) {
> +		dev_dbg(dev, "device is not behind an iommu\n");
> +	} else if (iommu_ret) {
> +		dev_err(dev, "iommu configuration for device failed with %pe\n",
> +			ERR_PTR(iommu_ret));
>  
> -	dev_dbg(dev, "device is%sbehind an iommu\n",
> -		iommu ? " " : " not ");
> +		/*
> +		 * Historically this routine doesn't fail driver probing
> +		 * due to errors in of_iommu_configure()
> +		 */
> +	} else
> +		dev_dbg(dev, "device is behind an iommu\n");
>  
>  	arch_setup_dma_ops(dev, dma_start, size, coherent);
>  
> -	if (!iommu)
> +	if (iommu_ret)
>  		of_dma_set_restricted_buffer(dev, np);
>  
>  	return 0;
> diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
> index 9a5e6b410dd2fb..e61cbbe12dac6f 100644
> --- a/include/linux/of_iommu.h
> +++ b/include/linux/of_iommu.h
> @@ -8,20 +8,19 @@ struct iommu_ops;
>  
>  #ifdef CONFIG_OF_IOMMU
>  
> -extern const struct iommu_ops *of_iommu_configure(struct device *dev,
> -					struct device_node *master_np,
> -					const u32 *id);
> +extern int of_iommu_configure(struct device *dev, struct device_node *master_np,
> +			      const u32 *id);
>  
>  extern void of_iommu_get_resv_regions(struct device *dev,
>  				      struct list_head *list);
>  
>  #else
>  
> -static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
> -					 struct device_node *master_np,
> -					 const u32 *id)
> +static inline int of_iommu_configure(struct device *dev,
> +				     struct device_node *master_np,
> +				     const u32 *id)
>  {
> -	return NULL;
> +	return -ENODEV;
>  }
>  
>  static inline void of_iommu_get_resv_regions(struct device *dev,
> -- 
> 2.42.0
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
  2023-11-03 21:42     ` Jerry Snitselaar
  (?)
  (?)
@ 2023-11-03 21:47       ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 21:47 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 02:42:01PM -0700, Jerry Snitselaar wrote:
> On Fri, Nov 03, 2023 at 01:44:47PM -0300, Jason Gunthorpe wrote:
> > Nothing needs this pointer. Return a normal error code with the usual
> > IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> > 
> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> > ---
> >  drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
> >  drivers/of/device.c      | 22 +++++++++++++++-------
> >  include/linux/of_iommu.h | 13 ++++++-------
> >  3 files changed, 39 insertions(+), 25 deletions(-)
> > 
> > diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> > index 157b286e36bf3a..e2fa29c16dd758 100644
> > --- a/drivers/iommu/of_iommu.c
> > +++ b/drivers/iommu/of_iommu.c
> > @@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
> >  		      of_iommu_configure_dev(master_np, dev);
> >  }
> >  
> > -const struct iommu_ops *of_iommu_configure(struct device *dev,
> > -					   struct device_node *master_np,
> > -					   const u32 *id)
> > +/*
> > + * Returns:
> > + *  0 on success, an iommu was configured
> > + *  -ENODEV if the device does not have any IOMMU
> > + *  -EPROBEDEFER if probing should be tried again
> > + *  -errno fatal errors
> 
> It looks to me like it will only return 0, -ENODEV, or -EPROBEDEFER
> with other -errno getting boiled down to -ENODEV.
> 

Ah, I should've looked at the next patch first. So, never mind on this
and the question about the dev_dbg.


Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
@ 2023-11-03 21:47       ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 21:47 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 02:42:01PM -0700, Jerry Snitselaar wrote:
> On Fri, Nov 03, 2023 at 01:44:47PM -0300, Jason Gunthorpe wrote:
> > Nothing needs this pointer. Return a normal error code with the usual
> > IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> > 
> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> > ---
> >  drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
> >  drivers/of/device.c      | 22 +++++++++++++++-------
> >  include/linux/of_iommu.h | 13 ++++++-------
> >  3 files changed, 39 insertions(+), 25 deletions(-)
> > 
> > diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> > index 157b286e36bf3a..e2fa29c16dd758 100644
> > --- a/drivers/iommu/of_iommu.c
> > +++ b/drivers/iommu/of_iommu.c
> > @@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
> >  		      of_iommu_configure_dev(master_np, dev);
> >  }
> >  
> > -const struct iommu_ops *of_iommu_configure(struct device *dev,
> > -					   struct device_node *master_np,
> > -					   const u32 *id)
> > +/*
> > + * Returns:
> > + *  0 on success, an iommu was configured
> > + *  -ENODEV if the device does not have any IOMMU
> > + *  -EPROBEDEFER if probing should be tried again
> > + *  -errno fatal errors
> 
> It looks to me like it will only return 0, -ENODEV, or -EPROBEDEFER
> with other -errno getting boiled down to -ENODEV.
> 

Ah, I should've looked at the next patch first. So, never mind on this
and the question about the dev_dbg.


Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
@ 2023-11-03 21:47       ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 21:47 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 02:42:01PM -0700, Jerry Snitselaar wrote:
> On Fri, Nov 03, 2023 at 01:44:47PM -0300, Jason Gunthorpe wrote:
> > Nothing needs this pointer. Return a normal error code with the usual
> > IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> > 
> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> > ---
> >  drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
> >  drivers/of/device.c      | 22 +++++++++++++++-------
> >  include/linux/of_iommu.h | 13 ++++++-------
> >  3 files changed, 39 insertions(+), 25 deletions(-)
> > 
> > diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> > index 157b286e36bf3a..e2fa29c16dd758 100644
> > --- a/drivers/iommu/of_iommu.c
> > +++ b/drivers/iommu/of_iommu.c
> > @@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
> >  		      of_iommu_configure_dev(master_np, dev);
> >  }
> >  
> > -const struct iommu_ops *of_iommu_configure(struct device *dev,
> > -					   struct device_node *master_np,
> > -					   const u32 *id)
> > +/*
> > + * Returns:
> > + *  0 on success, an iommu was configured
> > + *  -ENODEV if the device does not have any IOMMU
> > + *  -EPROBEDEFER if probing should be tried again
> > + *  -errno fatal errors
> 
> It looks to me like it will only return 0, -ENODEV, or -EPROBEDEFER
> with other -errno getting boiled down to -ENODEV.
> 

Ah, I should've looked at the next patch first. So, never mind on this
and the question about the dev_dbg.


Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
@ 2023-11-03 21:47       ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 21:47 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 02:42:01PM -0700, Jerry Snitselaar wrote:
> On Fri, Nov 03, 2023 at 01:44:47PM -0300, Jason Gunthorpe wrote:
> > Nothing needs this pointer. Return a normal error code with the usual
> > IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> > 
> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> > ---
> >  drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
> >  drivers/of/device.c      | 22 +++++++++++++++-------
> >  include/linux/of_iommu.h | 13 ++++++-------
> >  3 files changed, 39 insertions(+), 25 deletions(-)
> > 
> > diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> > index 157b286e36bf3a..e2fa29c16dd758 100644
> > --- a/drivers/iommu/of_iommu.c
> > +++ b/drivers/iommu/of_iommu.c
> > @@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
> >  		      of_iommu_configure_dev(master_np, dev);
> >  }
> >  
> > -const struct iommu_ops *of_iommu_configure(struct device *dev,
> > -					   struct device_node *master_np,
> > -					   const u32 *id)
> > +/*
> > + * Returns:
> > + *  0 on success, an iommu was configured
> > + *  -ENODEV if the device does not have any IOMMU
> > + *  -EPROBEDEFER if probing should be tried again
> > + *  -errno fatal errors
> 
> It looks to me like it will only return 0, -ENODEV, or -EPROBEDEFER
> with other -errno getting boiled down to -ENODEV.
> 

Ah, I should've looked at the next patch first. So, never mind on this
and the question about the dev_dbg.


Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-03 22:03     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 22:03 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:48PM -0300, Jason Gunthorpe wrote:
> Instead of returning 1 and trying to handle positive error codes just
> stick to the convention of returning -ENODEV. Remove references to ops
> from of_iommu_configure(), a NULL ops will already generate an error code.
> 
> There is no reason to check dev->bus, if err=0 at this point then the
> called configure functions thought there was an iommu and we should try to
> probe it. Remove it.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/of_iommu.c | 42 +++++++++++++---------------------------
>  1 file changed, 13 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index e2fa29c16dd758..4f77495a2543ea 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -17,7 +17,7 @@
>  #include <linux/slab.h>
>  #include <linux/fsl/mc.h>
>  
> -#define NO_IOMMU	1
> +#define NO_IOMMU	-ENODEV
>  

With this the following can be simplified in of_iommu_configure_dev_id:

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 4f77495a2543..b9b995712029 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -61,7 +61,7 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
 			 "iommu-map-mask", &iommu_spec.np,
 			 iommu_spec.args);
 	if (err)
-		return err == -ENODEV ? NO_IOMMU : err;
+		return err;
 
 	err = of_iommu_xlate(dev, &iommu_spec);
 	of_node_put(iommu_spec.np);



^ permalink raw reply related	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
@ 2023-11-03 22:03     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 22:03 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:48PM -0300, Jason Gunthorpe wrote:
> Instead of returning 1 and trying to handle positive error codes just
> stick to the convention of returning -ENODEV. Remove references to ops
> from of_iommu_configure(), a NULL ops will already generate an error code.
> 
> There is no reason to check dev->bus, if err=0 at this point then the
> called configure functions thought there was an iommu and we should try to
> probe it. Remove it.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/of_iommu.c | 42 +++++++++++++---------------------------
>  1 file changed, 13 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index e2fa29c16dd758..4f77495a2543ea 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -17,7 +17,7 @@
>  #include <linux/slab.h>
>  #include <linux/fsl/mc.h>
>  
> -#define NO_IOMMU	1
> +#define NO_IOMMU	-ENODEV
>  

With this the following can be simplified in of_iommu_configure_dev_id:

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 4f77495a2543..b9b995712029 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -61,7 +61,7 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
 			 "iommu-map-mask", &iommu_spec.np,
 			 iommu_spec.args);
 	if (err)
-		return err == -ENODEV ? NO_IOMMU : err;
+		return err;
 
 	err = of_iommu_xlate(dev, &iommu_spec);
 	of_node_put(iommu_spec.np);



_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
@ 2023-11-03 22:03     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 22:03 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:48PM -0300, Jason Gunthorpe wrote:
> Instead of returning 1 and trying to handle positive error codes just
> stick to the convention of returning -ENODEV. Remove references to ops
> from of_iommu_configure(), a NULL ops will already generate an error code.
> 
> There is no reason to check dev->bus, if err=0 at this point then the
> called configure functions thought there was an iommu and we should try to
> probe it. Remove it.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/of_iommu.c | 42 +++++++++++++---------------------------
>  1 file changed, 13 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index e2fa29c16dd758..4f77495a2543ea 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -17,7 +17,7 @@
>  #include <linux/slab.h>
>  #include <linux/fsl/mc.h>
>  
> -#define NO_IOMMU	1
> +#define NO_IOMMU	-ENODEV
>  

With this the following can be simplified in of_iommu_configure_dev_id:

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 4f77495a2543..b9b995712029 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -61,7 +61,7 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
 			 "iommu-map-mask", &iommu_spec.np,
 			 iommu_spec.args);
 	if (err)
-		return err == -ENODEV ? NO_IOMMU : err;
+		return err;
 
 	err = of_iommu_xlate(dev, &iommu_spec);
 	of_node_put(iommu_spec.np);



_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
@ 2023-11-03 22:03     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-03 22:03 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:48PM -0300, Jason Gunthorpe wrote:
> Instead of returning 1 and trying to handle positive error codes just
> stick to the convention of returning -ENODEV. Remove references to ops
> from of_iommu_configure(), a NULL ops will already generate an error code.
> 
> There is no reason to check dev->bus, if err=0 at this point then the
> called configure functions thought there was an iommu and we should try to
> probe it. Remove it.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/of_iommu.c | 42 +++++++++++++---------------------------
>  1 file changed, 13 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index e2fa29c16dd758..4f77495a2543ea 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -17,7 +17,7 @@
>  #include <linux/slab.h>
>  #include <linux/fsl/mc.h>
>  
> -#define NO_IOMMU	1
> +#define NO_IOMMU	-ENODEV
>  

With this the following can be simplified in of_iommu_configure_dev_id:

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 4f77495a2543..b9b995712029 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -61,7 +61,7 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
 			 "iommu-map-mask", &iommu_spec.np,
 			 iommu_spec.args);
 	if (err)
-		return err == -ENODEV ? NO_IOMMU : err;
+		return err;
 
 	err = of_iommu_xlate(dev, &iommu_spec);
 	of_node_put(iommu_spec.np);



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-04  0:48     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-04  0:48 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:49PM -0300, Jason Gunthorpe wrote:
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/acpi/scan.c | 24 +++++++++++++++---------
>  1 file changed, 15 insertions(+), 9 deletions(-)
> 

...

>  #else /* !CONFIG_IOMMU_API */
> @@ -1623,7 +1624,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>  			  const u32 *input_id)
>  {
> -	const struct iommu_ops *iommu;
> +	int ret;
>  
>  	if (attr == DEV_DMA_NOT_SUPPORTED) {
>  		set_dma_ops(dev, &dma_dummy_ops);
> @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>  
>  	acpi_arch_dma_setup(dev);
>  
> -	iommu = acpi_iommu_configure_id(dev, input_id);
> -	if (PTR_ERR(iommu) == -EPROBE_DEFER)
> +	ret = acpi_iommu_configure_id(dev, input_id);
> +	if (ret == -EPROBE_DEFER)
>  		return -EPROBE_DEFER;
>  
                return ret; ?

> +	/*
> +	 * Historically this routine doesn't fail driver probing due to errors
> +	 * in acpi_iommu_configure()

              acpi_iommu_configure_id()

> +	 */
> +
>  	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
>  
>  	return 0;
> -- 
> 2.42.0
> 


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-04  0:48     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-04  0:48 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:49PM -0300, Jason Gunthorpe wrote:
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/acpi/scan.c | 24 +++++++++++++++---------
>  1 file changed, 15 insertions(+), 9 deletions(-)
> 

...

>  #else /* !CONFIG_IOMMU_API */
> @@ -1623,7 +1624,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>  			  const u32 *input_id)
>  {
> -	const struct iommu_ops *iommu;
> +	int ret;
>  
>  	if (attr == DEV_DMA_NOT_SUPPORTED) {
>  		set_dma_ops(dev, &dma_dummy_ops);
> @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>  
>  	acpi_arch_dma_setup(dev);
>  
> -	iommu = acpi_iommu_configure_id(dev, input_id);
> -	if (PTR_ERR(iommu) == -EPROBE_DEFER)
> +	ret = acpi_iommu_configure_id(dev, input_id);
> +	if (ret == -EPROBE_DEFER)
>  		return -EPROBE_DEFER;
>  
                return ret; ?

> +	/*
> +	 * Historically this routine doesn't fail driver probing due to errors
> +	 * in acpi_iommu_configure()

              acpi_iommu_configure_id()

> +	 */
> +
>  	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
>  
>  	return 0;
> -- 
> 2.42.0
> 


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-04  0:48     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-04  0:48 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:49PM -0300, Jason Gunthorpe wrote:
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/acpi/scan.c | 24 +++++++++++++++---------
>  1 file changed, 15 insertions(+), 9 deletions(-)
> 

...

>  #else /* !CONFIG_IOMMU_API */
> @@ -1623,7 +1624,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>  			  const u32 *input_id)
>  {
> -	const struct iommu_ops *iommu;
> +	int ret;
>  
>  	if (attr == DEV_DMA_NOT_SUPPORTED) {
>  		set_dma_ops(dev, &dma_dummy_ops);
> @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>  
>  	acpi_arch_dma_setup(dev);
>  
> -	iommu = acpi_iommu_configure_id(dev, input_id);
> -	if (PTR_ERR(iommu) == -EPROBE_DEFER)
> +	ret = acpi_iommu_configure_id(dev, input_id);
> +	if (ret == -EPROBE_DEFER)
>  		return -EPROBE_DEFER;
>  
                return ret; ?

> +	/*
> +	 * Historically this routine doesn't fail driver probing due to errors
> +	 * in acpi_iommu_configure()

              acpi_iommu_configure_id()

> +	 */
> +
>  	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
>  
>  	return 0;
> -- 
> 2.42.0
> 


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-04  0:48     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-04  0:48 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:49PM -0300, Jason Gunthorpe wrote:
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/acpi/scan.c | 24 +++++++++++++++---------
>  1 file changed, 15 insertions(+), 9 deletions(-)
> 

...

>  #else /* !CONFIG_IOMMU_API */
> @@ -1623,7 +1624,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>  			  const u32 *input_id)
>  {
> -	const struct iommu_ops *iommu;
> +	int ret;
>  
>  	if (attr == DEV_DMA_NOT_SUPPORTED) {
>  		set_dma_ops(dev, &dma_dummy_ops);
> @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>  
>  	acpi_arch_dma_setup(dev);
>  
> -	iommu = acpi_iommu_configure_id(dev, input_id);
> -	if (PTR_ERR(iommu) == -EPROBE_DEFER)
> +	ret = acpi_iommu_configure_id(dev, input_id);
> +	if (ret == -EPROBE_DEFER)
>  		return -EPROBE_DEFER;
>  
                return ret; ?

> +	/*
> +	 * Historically this routine doesn't fail driver probing due to errors
> +	 * in acpi_iommu_configure()

              acpi_iommu_configure_id()

> +	 */
> +
>  	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
>  
>  	return 0;
> -- 
> 2.42.0
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
  2023-11-04  0:48     ` Jerry Snitselaar
  (?)
  (?)
@ 2023-11-05 13:24       ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-05 13:24 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 05:48:01PM -0700, Jerry Snitselaar wrote:
> > @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
> >  
> >  	acpi_arch_dma_setup(dev);
> >  
> > -	iommu = acpi_iommu_configure_id(dev, input_id);
> > -	if (PTR_ERR(iommu) == -EPROBE_DEFER)
> > +	ret = acpi_iommu_configure_id(dev, input_id);
> > +	if (ret == -EPROBE_DEFER)
> >  		return -EPROBE_DEFER;
> >  
>                 return ret; ?

Maybe? Like this seemed to be a pattern in this code so I left it

> > +	/*
> > +	 * Historically this routine doesn't fail driver probing due to errors
> > +	 * in acpi_iommu_configure()
> 
>               acpi_iommu_configure_id()

Thanks

Jason

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-05 13:24       ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-05 13:24 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 05:48:01PM -0700, Jerry Snitselaar wrote:
> > @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
> >  
> >  	acpi_arch_dma_setup(dev);
> >  
> > -	iommu = acpi_iommu_configure_id(dev, input_id);
> > -	if (PTR_ERR(iommu) == -EPROBE_DEFER)
> > +	ret = acpi_iommu_configure_id(dev, input_id);
> > +	if (ret == -EPROBE_DEFER)
> >  		return -EPROBE_DEFER;
> >  
>                 return ret; ?

Maybe? Like this seemed to be a pattern in this code so I left it

> > +	/*
> > +	 * Historically this routine doesn't fail driver probing due to errors
> > +	 * in acpi_iommu_configure()
> 
>               acpi_iommu_configure_id()

Thanks

Jason

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-05 13:24       ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-05 13:24 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 05:48:01PM -0700, Jerry Snitselaar wrote:
> > @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
> >  
> >  	acpi_arch_dma_setup(dev);
> >  
> > -	iommu = acpi_iommu_configure_id(dev, input_id);
> > -	if (PTR_ERR(iommu) == -EPROBE_DEFER)
> > +	ret = acpi_iommu_configure_id(dev, input_id);
> > +	if (ret == -EPROBE_DEFER)
> >  		return -EPROBE_DEFER;
> >  
>                 return ret; ?

Maybe? Like this seemed to be a pattern in this code so I left it

> > +	/*
> > +	 * Historically this routine doesn't fail driver probing due to errors
> > +	 * in acpi_iommu_configure()
> 
>               acpi_iommu_configure_id()

Thanks

Jason

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-05 13:24       ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-05 13:24 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 05:48:01PM -0700, Jerry Snitselaar wrote:
> > @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
> >  
> >  	acpi_arch_dma_setup(dev);
> >  
> > -	iommu = acpi_iommu_configure_id(dev, input_id);
> > -	if (PTR_ERR(iommu) == -EPROBE_DEFER)
> > +	ret = acpi_iommu_configure_id(dev, input_id);
> > +	if (ret == -EPROBE_DEFER)
> >  		return -EPROBE_DEFER;
> >  
>                 return ret; ?

Maybe? Like this seemed to be a pattern in this code so I left it

> > +	/*
> > +	 * Historically this routine doesn't fail driver probing due to errors
> > +	 * in acpi_iommu_configure()
> 
>               acpi_iommu_configure_id()

Thanks

Jason

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
  2023-11-03 22:03     ` Jerry Snitselaar
  (?)
  (?)
@ 2023-11-05 13:26       ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-05 13:26 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 03:03:53PM -0700, Jerry Snitselaar wrote:
> With this the following can be simplified in of_iommu_configure_dev_id:
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 4f77495a2543..b9b995712029 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -61,7 +61,7 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
>  			 "iommu-map-mask", &iommu_spec.np,
>  			 iommu_spec.args);
>  	if (err)
> -		return err == -ENODEV ? NO_IOMMU : err;
> +		return err;

Yeah, at this point it just makes sense to erase the whole thing:

-#define NO_IOMMU       -ENODEV
-
 static int of_iommu_xlate(struct device *dev,
                          struct of_phandle_args *iommu_spec)
 {
@@ -29,7 +27,7 @@ static int of_iommu_xlate(struct device *dev,
        ops = iommu_ops_from_fwnode(fwnode);
        if ((ops && !ops->of_xlate) ||
            !of_device_is_available(iommu_spec->np))
-               return NO_IOMMU;
+               return -ENODEV;
 
        ret = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
        if (ret)
@@ -61,7 +59,7 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
                         "iommu-map-mask", &iommu_spec.np,
                         iommu_spec.args);
        if (err)
-               return err == -ENODEV ? NO_IOMMU : err;
+               return err;
 
        err = of_iommu_xlate(dev, &iommu_spec);
        of_node_put(iommu_spec.np);
@@ -72,7 +70,7 @@ static int of_iommu_configure_dev(struct device_node *master_np,
                                  struct device *dev)
 {
        struct of_phandle_args iommu_spec;
-       int err = NO_IOMMU, idx = 0;
+       int err = -ENODEV, idx = 0;
 
        while (!of_parse_phandle_with_args(master_np, "iommus",
                                           "#iommu-cells",

Thanks,
Jason

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
@ 2023-11-05 13:26       ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-05 13:26 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 03:03:53PM -0700, Jerry Snitselaar wrote:
> With this the following can be simplified in of_iommu_configure_dev_id:
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 4f77495a2543..b9b995712029 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -61,7 +61,7 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
>  			 "iommu-map-mask", &iommu_spec.np,
>  			 iommu_spec.args);
>  	if (err)
> -		return err == -ENODEV ? NO_IOMMU : err;
> +		return err;

Yeah, at this point it just makes sense to erase the whole thing:

-#define NO_IOMMU       -ENODEV
-
 static int of_iommu_xlate(struct device *dev,
                          struct of_phandle_args *iommu_spec)
 {
@@ -29,7 +27,7 @@ static int of_iommu_xlate(struct device *dev,
        ops = iommu_ops_from_fwnode(fwnode);
        if ((ops && !ops->of_xlate) ||
            !of_device_is_available(iommu_spec->np))
-               return NO_IOMMU;
+               return -ENODEV;
 
        ret = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
        if (ret)
@@ -61,7 +59,7 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
                         "iommu-map-mask", &iommu_spec.np,
                         iommu_spec.args);
        if (err)
-               return err == -ENODEV ? NO_IOMMU : err;
+               return err;
 
        err = of_iommu_xlate(dev, &iommu_spec);
        of_node_put(iommu_spec.np);
@@ -72,7 +70,7 @@ static int of_iommu_configure_dev(struct device_node *master_np,
                                  struct device *dev)
 {
        struct of_phandle_args iommu_spec;
-       int err = NO_IOMMU, idx = 0;
+       int err = -ENODEV, idx = 0;
 
        while (!of_parse_phandle_with_args(master_np, "iommus",
                                           "#iommu-cells",

Thanks,
Jason

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
@ 2023-11-05 13:26       ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-05 13:26 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 03:03:53PM -0700, Jerry Snitselaar wrote:
> With this the following can be simplified in of_iommu_configure_dev_id:
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 4f77495a2543..b9b995712029 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -61,7 +61,7 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
>  			 "iommu-map-mask", &iommu_spec.np,
>  			 iommu_spec.args);
>  	if (err)
> -		return err == -ENODEV ? NO_IOMMU : err;
> +		return err;

Yeah, at this point it just makes sense to erase the whole thing:

-#define NO_IOMMU       -ENODEV
-
 static int of_iommu_xlate(struct device *dev,
                          struct of_phandle_args *iommu_spec)
 {
@@ -29,7 +27,7 @@ static int of_iommu_xlate(struct device *dev,
        ops = iommu_ops_from_fwnode(fwnode);
        if ((ops && !ops->of_xlate) ||
            !of_device_is_available(iommu_spec->np))
-               return NO_IOMMU;
+               return -ENODEV;
 
        ret = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
        if (ret)
@@ -61,7 +59,7 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
                         "iommu-map-mask", &iommu_spec.np,
                         iommu_spec.args);
        if (err)
-               return err == -ENODEV ? NO_IOMMU : err;
+               return err;
 
        err = of_iommu_xlate(dev, &iommu_spec);
        of_node_put(iommu_spec.np);
@@ -72,7 +70,7 @@ static int of_iommu_configure_dev(struct device_node *master_np,
                                  struct device *dev)
 {
        struct of_phandle_args iommu_spec;
-       int err = NO_IOMMU, idx = 0;
+       int err = -ENODEV, idx = 0;
 
        while (!of_parse_phandle_with_args(master_np, "iommus",
                                           "#iommu-cells",

Thanks,
Jason

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
@ 2023-11-05 13:26       ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-05 13:26 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 03:03:53PM -0700, Jerry Snitselaar wrote:
> With this the following can be simplified in of_iommu_configure_dev_id:
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 4f77495a2543..b9b995712029 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -61,7 +61,7 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
>  			 "iommu-map-mask", &iommu_spec.np,
>  			 iommu_spec.args);
>  	if (err)
> -		return err == -ENODEV ? NO_IOMMU : err;
> +		return err;

Yeah, at this point it just makes sense to erase the whole thing:

-#define NO_IOMMU       -ENODEV
-
 static int of_iommu_xlate(struct device *dev,
                          struct of_phandle_args *iommu_spec)
 {
@@ -29,7 +27,7 @@ static int of_iommu_xlate(struct device *dev,
        ops = iommu_ops_from_fwnode(fwnode);
        if ((ops && !ops->of_xlate) ||
            !of_device_is_available(iommu_spec->np))
-               return NO_IOMMU;
+               return -ENODEV;
 
        ret = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
        if (ret)
@@ -61,7 +59,7 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
                         "iommu-map-mask", &iommu_spec.np,
                         iommu_spec.args);
        if (err)
-               return err == -ENODEV ? NO_IOMMU : err;
+               return err;
 
        err = of_iommu_xlate(dev, &iommu_spec);
        of_node_put(iommu_spec.np);
@@ -72,7 +70,7 @@ static int of_iommu_configure_dev(struct device_node *master_np,
                                  struct device *dev)
 {
        struct of_phandle_args iommu_spec;
-       int err = NO_IOMMU, idx = 0;
+       int err = -ENODEV, idx = 0;
 
        while (!of_parse_phandle_with_args(master_np, "iommus",
                                           "#iommu-cells",

Thanks,
Jason

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
  2023-11-03 21:42     ` Jerry Snitselaar
  (?)
  (?)
@ 2023-11-05 13:31       ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-05 13:31 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 02:42:01PM -0700, Jerry Snitselaar wrote:
> On Fri, Nov 03, 2023 at 01:44:47PM -0300, Jason Gunthorpe wrote:
> > Nothing needs this pointer. Return a normal error code with the usual
> > IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> > 
> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> > ---
> >  drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
> >  drivers/of/device.c      | 22 +++++++++++++++-------
> >  include/linux/of_iommu.h | 13 ++++++-------
> >  3 files changed, 39 insertions(+), 25 deletions(-)
> > 
> > diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> > index 157b286e36bf3a..e2fa29c16dd758 100644
> > --- a/drivers/iommu/of_iommu.c
> > +++ b/drivers/iommu/of_iommu.c
> > @@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
> >  		      of_iommu_configure_dev(master_np, dev);
> >  }
> >  
> > -const struct iommu_ops *of_iommu_configure(struct device *dev,
> > -					   struct device_node *master_np,
> > -					   const u32 *id)
> > +/*
> > + * Returns:
> > + *  0 on success, an iommu was configured
> > + *  -ENODEV if the device does not have any IOMMU
> > + *  -EPROBEDEFER if probing should be tried again
> > + *  -errno fatal errors
> 
> It looks to me like it will only return 0, -ENODEV, or -EPROBEDEFER
> with other -errno getting boiled down to -ENODEV.

Yeah, that next patch sorts it out, it is sort of a typo here:

@@ -173,7 +173,7 @@ int of_iommu_configure(struct device *dev, struct device_node *master_np,
                if (err == -EPROBE_DEFER)
                        return err;
                dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-               return -ENODEV;
+               return err;
        }
        if (!ops)
                return -ENODEV;

> > @@ -163,14 +169,15 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
> >  		err = iommu_probe_device(dev);
> >  
> >  	/* Ignore all other errors apart from EPROBE_DEFER */
> > -	if (err == -EPROBE_DEFER) {
> > -		ops = ERR_PTR(err);
> > -	} else if (err < 0) {
> > +	if (err < 0) {
> > +		if (err == -EPROBE_DEFER)
> > +			return err;
> >  		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> 
> minor thing, but should this use %pe and ERR_PTR(err) like is done
> in of_dma_configure_id?

Sure

Thanks,
Jason

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
@ 2023-11-05 13:31       ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-05 13:31 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 02:42:01PM -0700, Jerry Snitselaar wrote:
> On Fri, Nov 03, 2023 at 01:44:47PM -0300, Jason Gunthorpe wrote:
> > Nothing needs this pointer. Return a normal error code with the usual
> > IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> > 
> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> > ---
> >  drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
> >  drivers/of/device.c      | 22 +++++++++++++++-------
> >  include/linux/of_iommu.h | 13 ++++++-------
> >  3 files changed, 39 insertions(+), 25 deletions(-)
> > 
> > diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> > index 157b286e36bf3a..e2fa29c16dd758 100644
> > --- a/drivers/iommu/of_iommu.c
> > +++ b/drivers/iommu/of_iommu.c
> > @@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
> >  		      of_iommu_configure_dev(master_np, dev);
> >  }
> >  
> > -const struct iommu_ops *of_iommu_configure(struct device *dev,
> > -					   struct device_node *master_np,
> > -					   const u32 *id)
> > +/*
> > + * Returns:
> > + *  0 on success, an iommu was configured
> > + *  -ENODEV if the device does not have any IOMMU
> > + *  -EPROBEDEFER if probing should be tried again
> > + *  -errno fatal errors
> 
> It looks to me like it will only return 0, -ENODEV, or -EPROBEDEFER
> with other -errno getting boiled down to -ENODEV.

Yeah, that next patch sorts it out, it is sort of a typo here:

@@ -173,7 +173,7 @@ int of_iommu_configure(struct device *dev, struct device_node *master_np,
                if (err == -EPROBE_DEFER)
                        return err;
                dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-               return -ENODEV;
+               return err;
        }
        if (!ops)
                return -ENODEV;

> > @@ -163,14 +169,15 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
> >  		err = iommu_probe_device(dev);
> >  
> >  	/* Ignore all other errors apart from EPROBE_DEFER */
> > -	if (err == -EPROBE_DEFER) {
> > -		ops = ERR_PTR(err);
> > -	} else if (err < 0) {
> > +	if (err < 0) {
> > +		if (err == -EPROBE_DEFER)
> > +			return err;
> >  		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> 
> minor thing, but should this use %pe and ERR_PTR(err) like is done
> in of_dma_configure_id?

Sure

Thanks,
Jason

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
@ 2023-11-05 13:31       ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-05 13:31 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 02:42:01PM -0700, Jerry Snitselaar wrote:
> On Fri, Nov 03, 2023 at 01:44:47PM -0300, Jason Gunthorpe wrote:
> > Nothing needs this pointer. Return a normal error code with the usual
> > IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> > 
> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> > ---
> >  drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
> >  drivers/of/device.c      | 22 +++++++++++++++-------
> >  include/linux/of_iommu.h | 13 ++++++-------
> >  3 files changed, 39 insertions(+), 25 deletions(-)
> > 
> > diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> > index 157b286e36bf3a..e2fa29c16dd758 100644
> > --- a/drivers/iommu/of_iommu.c
> > +++ b/drivers/iommu/of_iommu.c
> > @@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
> >  		      of_iommu_configure_dev(master_np, dev);
> >  }
> >  
> > -const struct iommu_ops *of_iommu_configure(struct device *dev,
> > -					   struct device_node *master_np,
> > -					   const u32 *id)
> > +/*
> > + * Returns:
> > + *  0 on success, an iommu was configured
> > + *  -ENODEV if the device does not have any IOMMU
> > + *  -EPROBEDEFER if probing should be tried again
> > + *  -errno fatal errors
> 
> It looks to me like it will only return 0, -ENODEV, or -EPROBEDEFER
> with other -errno getting boiled down to -ENODEV.

Yeah, that next patch sorts it out, it is sort of a typo here:

@@ -173,7 +173,7 @@ int of_iommu_configure(struct device *dev, struct device_node *master_np,
                if (err == -EPROBE_DEFER)
                        return err;
                dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-               return -ENODEV;
+               return err;
        }
        if (!ops)
                return -ENODEV;

> > @@ -163,14 +169,15 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
> >  		err = iommu_probe_device(dev);
> >  
> >  	/* Ignore all other errors apart from EPROBE_DEFER */
> > -	if (err == -EPROBE_DEFER) {
> > -		ops = ERR_PTR(err);
> > -	} else if (err < 0) {
> > +	if (err < 0) {
> > +		if (err == -EPROBE_DEFER)
> > +			return err;
> >  		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> 
> minor thing, but should this use %pe and ERR_PTR(err) like is done
> in of_dma_configure_id?

Sure

Thanks,
Jason

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
@ 2023-11-05 13:31       ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-05 13:31 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 02:42:01PM -0700, Jerry Snitselaar wrote:
> On Fri, Nov 03, 2023 at 01:44:47PM -0300, Jason Gunthorpe wrote:
> > Nothing needs this pointer. Return a normal error code with the usual
> > IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> > 
> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> > ---
> >  drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
> >  drivers/of/device.c      | 22 +++++++++++++++-------
> >  include/linux/of_iommu.h | 13 ++++++-------
> >  3 files changed, 39 insertions(+), 25 deletions(-)
> > 
> > diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> > index 157b286e36bf3a..e2fa29c16dd758 100644
> > --- a/drivers/iommu/of_iommu.c
> > +++ b/drivers/iommu/of_iommu.c
> > @@ -107,20 +107,26 @@ static int of_iommu_configure_device(struct device_node *master_np,
> >  		      of_iommu_configure_dev(master_np, dev);
> >  }
> >  
> > -const struct iommu_ops *of_iommu_configure(struct device *dev,
> > -					   struct device_node *master_np,
> > -					   const u32 *id)
> > +/*
> > + * Returns:
> > + *  0 on success, an iommu was configured
> > + *  -ENODEV if the device does not have any IOMMU
> > + *  -EPROBEDEFER if probing should be tried again
> > + *  -errno fatal errors
> 
> It looks to me like it will only return 0, -ENODEV, or -EPROBEDEFER
> with other -errno getting boiled down to -ENODEV.

Yeah, that next patch sorts it out, it is sort of a typo here:

@@ -173,7 +173,7 @@ int of_iommu_configure(struct device *dev, struct device_node *master_np,
                if (err == -EPROBE_DEFER)
                        return err;
                dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-               return -ENODEV;
+               return err;
        }
        if (!ops)
                return -ENODEV;

> > @@ -163,14 +169,15 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
> >  		err = iommu_probe_device(dev);
> >  
> >  	/* Ignore all other errors apart from EPROBE_DEFER */
> > -	if (err == -EPROBE_DEFER) {
> > -		ops = ERR_PTR(err);
> > -	} else if (err < 0) {
> > +	if (err < 0) {
> > +		if (err == -EPROBE_DEFER)
> > +			return err;
> >  		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> 
> minor thing, but should this use %pe and ERR_PTR(err) like is done
> in of_dma_configure_id?

Sure

Thanks,
Jason

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
  2023-11-05 13:24       ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-05 17:55         ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-05 17:55 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Sun, Nov 05, 2023 at 09:24:09AM -0400, Jason Gunthorpe wrote:
> On Fri, Nov 03, 2023 at 05:48:01PM -0700, Jerry Snitselaar wrote:
> > > @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
> > >  
> > >  	acpi_arch_dma_setup(dev);
> > >  
> > > -	iommu = acpi_iommu_configure_id(dev, input_id);
> > > -	if (PTR_ERR(iommu) == -EPROBE_DEFER)
> > > +	ret = acpi_iommu_configure_id(dev, input_id);
> > > +	if (ret == -EPROBE_DEFER)
> > >  		return -EPROBE_DEFER;
> > >  
> >                 return ret; ?
> 
> Maybe? Like this seemed to be a pattern in this code so I left it

Yeah, it is fine. I think it just caught my eye, because of this earlier
bit in the patch:

        if (err == -EPROBE_DEFER) {
-               return ERR_PTR(err);
+               return err;

which needed to get rid of the ERR_PTR.

Regards,
Jerry

> 
> > > +	/*
> > > +	 * Historically this routine doesn't fail driver probing due to errors
> > > +	 * in acpi_iommu_configure()
> > 
> >               acpi_iommu_configure_id()
> 
> Thanks
> 
> Jason


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-05 17:55         ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-05 17:55 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Sun, Nov 05, 2023 at 09:24:09AM -0400, Jason Gunthorpe wrote:
> On Fri, Nov 03, 2023 at 05:48:01PM -0700, Jerry Snitselaar wrote:
> > > @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
> > >  
> > >  	acpi_arch_dma_setup(dev);
> > >  
> > > -	iommu = acpi_iommu_configure_id(dev, input_id);
> > > -	if (PTR_ERR(iommu) == -EPROBE_DEFER)
> > > +	ret = acpi_iommu_configure_id(dev, input_id);
> > > +	if (ret == -EPROBE_DEFER)
> > >  		return -EPROBE_DEFER;
> > >  
> >                 return ret; ?
> 
> Maybe? Like this seemed to be a pattern in this code so I left it

Yeah, it is fine. I think it just caught my eye, because of this earlier
bit in the patch:

        if (err == -EPROBE_DEFER) {
-               return ERR_PTR(err);
+               return err;

which needed to get rid of the ERR_PTR.

Regards,
Jerry

> 
> > > +	/*
> > > +	 * Historically this routine doesn't fail driver probing due to errors
> > > +	 * in acpi_iommu_configure()
> > 
> >               acpi_iommu_configure_id()
> 
> Thanks
> 
> Jason


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-05 17:55         ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-05 17:55 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Sun, Nov 05, 2023 at 09:24:09AM -0400, Jason Gunthorpe wrote:
> On Fri, Nov 03, 2023 at 05:48:01PM -0700, Jerry Snitselaar wrote:
> > > @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
> > >  
> > >  	acpi_arch_dma_setup(dev);
> > >  
> > > -	iommu = acpi_iommu_configure_id(dev, input_id);
> > > -	if (PTR_ERR(iommu) == -EPROBE_DEFER)
> > > +	ret = acpi_iommu_configure_id(dev, input_id);
> > > +	if (ret == -EPROBE_DEFER)
> > >  		return -EPROBE_DEFER;
> > >  
> >                 return ret; ?
> 
> Maybe? Like this seemed to be a pattern in this code so I left it

Yeah, it is fine. I think it just caught my eye, because of this earlier
bit in the patch:

        if (err == -EPROBE_DEFER) {
-               return ERR_PTR(err);
+               return err;

which needed to get rid of the ERR_PTR.

Regards,
Jerry

> 
> > > +	/*
> > > +	 * Historically this routine doesn't fail driver probing due to errors
> > > +	 * in acpi_iommu_configure()
> > 
> >               acpi_iommu_configure_id()
> 
> Thanks
> 
> Jason


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-05 17:55         ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-05 17:55 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Sun, Nov 05, 2023 at 09:24:09AM -0400, Jason Gunthorpe wrote:
> On Fri, Nov 03, 2023 at 05:48:01PM -0700, Jerry Snitselaar wrote:
> > > @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
> > >  
> > >  	acpi_arch_dma_setup(dev);
> > >  
> > > -	iommu = acpi_iommu_configure_id(dev, input_id);
> > > -	if (PTR_ERR(iommu) == -EPROBE_DEFER)
> > > +	ret = acpi_iommu_configure_id(dev, input_id);
> > > +	if (ret == -EPROBE_DEFER)
> > >  		return -EPROBE_DEFER;
> > >  
> >                 return ret; ?
> 
> Maybe? Like this seemed to be a pattern in this code so I left it

Yeah, it is fine. I think it just caught my eye, because of this earlier
bit in the patch:

        if (err == -EPROBE_DEFER) {
-               return ERR_PTR(err);
+               return err;

which needed to get rid of the ERR_PTR.

Regards,
Jerry

> 
> > > +	/*
> > > +	 * Historically this routine doesn't fail driver probing due to errors
> > > +	 * in acpi_iommu_configure()
> > 
> >               acpi_iommu_configure_id()
> 
> Thanks
> 
> Jason


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
  2023-11-03 16:44   ` Jason Gunthorpe
                       ` (2 preceding siblings ...)
  (?)
@ 2023-11-06  7:17     ` Christoph Hellwig
  -1 siblings, 0 replies; 242+ messages in thread
From: Christoph Hellwig @ 2023-11-06  7:17 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:46PM -0300, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.

Yes, that's much better than exposing the iommu ops to a place that
should not care about them:

Acked-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-06  7:17     ` Christoph Hellwig
  0 siblings, 0 replies; 242+ messages in thread
From: Christoph Hellwig @ 2023-11-06  7:17 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:46PM -0300, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.

Yes, that's much better than exposing the iommu ops to a place that
should not care about them:

Acked-by: Christoph Hellwig <hch@lst.de>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-06  7:17     ` Christoph Hellwig
  0 siblings, 0 replies; 242+ messages in thread
From: Christoph Hellwig @ 2023-11-06  7:17 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:46PM -0300, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.

Yes, that's much better than exposing the iommu ops to a place that
should not care about them:

Acked-by: Christoph Hellwig <hch@lst.de>

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-06  7:17     ` Christoph Hellwig
  0 siblings, 0 replies; 242+ messages in thread
From: Christoph Hellwig @ 2023-11-06  7:17 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:46PM -0300, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.

Yes, that's much better than exposing the iommu ops to a place that
should not care about them:

Acked-by: Christoph Hellwig <hch@lst.de>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-06  7:17     ` Christoph Hellwig
  0 siblings, 0 replies; 242+ messages in thread
From: Christoph Hellwig @ 2023-11-06  7:17 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: linux-hyperv, Rafael J. Wysocki, Catalin Marinas,
	Lorenzo Pieralisi, Robert Moore, Thierry Reding, Hanjun Guo,
	acpica-devel, Christoph Hellwig, Alyssa Rosenzweig,
	Marek Szyprowski, Jean-Philippe Brucker, Wei Liu, Will Deacon,
	Joerg Roedel, Dexuan Cui, Russell King, linux-riscv,
	Jonathan Hunter, linux-acpi, iommu, Vineet Gupta, linux-snps-arc,
	Len Brown, devicetree, Albert Ou, Sven Peter, Haiyang Zhang,
	Krishna Reddy, Rob Herring, Paul Walmsley, linux-tegra,
	virtualization, linux-arm-kernel, Thomas Bogendoerfer,
	Robin Murphy, Zhenhua Huang, Hector Martin, linux-mips,
	Palmer Dabbelt, asahi, Suravee Suthikulpanit, Sudeep Holla,
	David Woodhouse, Lu Baolu

On Fri, Nov 03, 2023 at 01:44:46PM -0300, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.

Yes, that's much better than exposing the iommu ops to a place that
should not care about them:

Acked-by: Christoph Hellwig <hch@lst.de>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
  2023-11-03 16:44   ` Jason Gunthorpe
                       ` (2 preceding siblings ...)
  (?)
@ 2023-11-06 14:32     ` Rafael J. Wysocki
  -1 siblings, 0 replies; 242+ messages in thread
From: Rafael J. Wysocki @ 2023-11-06 14:32 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 3, 2023 at 5:45 PM Jason Gunthorpe <jgg@nvidia.com> wrote:
>
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/acpi/scan.c | 24 +++++++++++++++---------
>  1 file changed, 15 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index a6891ad0ceee2c..fbabde001a23a2 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1562,8 +1562,7 @@ static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
>         return fwspec ? fwspec->ops : NULL;
>  }
>
> -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> -                                                      const u32 *id_in)
> +static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
>         int err;
>         const struct iommu_ops *ops;
> @@ -1574,7 +1573,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>          */
>         ops = acpi_iommu_fwspec_ops(dev);
>         if (ops)
> -               return ops;
> +               return 0;
>
>         err = iort_iommu_configure_id(dev, id_in);
>         if (err && err != -EPROBE_DEFER)
> @@ -1589,12 +1588,14 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>
>         /* Ignore all other errors apart from EPROBE_DEFER */
>         if (err == -EPROBE_DEFER) {
> -               return ERR_PTR(err);
> +               return err;
>         } else if (err) {
>                 dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> -               return NULL;
> +               return -ENODEV;
>         }
> -       return acpi_iommu_fwspec_ops(dev);
> +       if (!acpi_iommu_fwspec_ops(dev))
> +               return -ENODEV;
> +       return 0;
>  }
>
>  #else /* !CONFIG_IOMMU_API */
> @@ -1623,7 +1624,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>                           const u32 *input_id)
>  {
> -       const struct iommu_ops *iommu;
> +       int ret;
>
>         if (attr == DEV_DMA_NOT_SUPPORTED) {
>                 set_dma_ops(dev, &dma_dummy_ops);
> @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>
>         acpi_arch_dma_setup(dev);
>
> -       iommu = acpi_iommu_configure_id(dev, input_id);
> -       if (PTR_ERR(iommu) == -EPROBE_DEFER)
> +       ret = acpi_iommu_configure_id(dev, input_id);
> +       if (ret == -EPROBE_DEFER)
>                 return -EPROBE_DEFER;
>
> +       /*
> +        * Historically this routine doesn't fail driver probing due to errors
> +        * in acpi_iommu_configure()
> +        */
> +
>         arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
>
>         return 0;
> --
> 2.42.0
>

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-06 14:32     ` Rafael J. Wysocki
  0 siblings, 0 replies; 242+ messages in thread
From: Rafael J. Wysocki @ 2023-11-06 14:32 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 3, 2023 at 5:45 PM Jason Gunthorpe <jgg@nvidia.com> wrote:
>
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/acpi/scan.c | 24 +++++++++++++++---------
>  1 file changed, 15 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index a6891ad0ceee2c..fbabde001a23a2 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1562,8 +1562,7 @@ static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
>         return fwspec ? fwspec->ops : NULL;
>  }
>
> -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> -                                                      const u32 *id_in)
> +static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
>         int err;
>         const struct iommu_ops *ops;
> @@ -1574,7 +1573,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>          */
>         ops = acpi_iommu_fwspec_ops(dev);
>         if (ops)
> -               return ops;
> +               return 0;
>
>         err = iort_iommu_configure_id(dev, id_in);
>         if (err && err != -EPROBE_DEFER)
> @@ -1589,12 +1588,14 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>
>         /* Ignore all other errors apart from EPROBE_DEFER */
>         if (err == -EPROBE_DEFER) {
> -               return ERR_PTR(err);
> +               return err;
>         } else if (err) {
>                 dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> -               return NULL;
> +               return -ENODEV;
>         }
> -       return acpi_iommu_fwspec_ops(dev);
> +       if (!acpi_iommu_fwspec_ops(dev))
> +               return -ENODEV;
> +       return 0;
>  }
>
>  #else /* !CONFIG_IOMMU_API */
> @@ -1623,7 +1624,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>                           const u32 *input_id)
>  {
> -       const struct iommu_ops *iommu;
> +       int ret;
>
>         if (attr == DEV_DMA_NOT_SUPPORTED) {
>                 set_dma_ops(dev, &dma_dummy_ops);
> @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>
>         acpi_arch_dma_setup(dev);
>
> -       iommu = acpi_iommu_configure_id(dev, input_id);
> -       if (PTR_ERR(iommu) == -EPROBE_DEFER)
> +       ret = acpi_iommu_configure_id(dev, input_id);
> +       if (ret == -EPROBE_DEFER)
>                 return -EPROBE_DEFER;
>
> +       /*
> +        * Historically this routine doesn't fail driver probing due to errors
> +        * in acpi_iommu_configure()
> +        */
> +
>         arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
>
>         return 0;
> --
> 2.42.0
>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-06 14:32     ` Rafael J. Wysocki
  0 siblings, 0 replies; 242+ messages in thread
From: Rafael J. Wysocki @ 2023-11-06 14:32 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 3, 2023 at 5:45 PM Jason Gunthorpe <jgg@nvidia.com> wrote:
>
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/acpi/scan.c | 24 +++++++++++++++---------
>  1 file changed, 15 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index a6891ad0ceee2c..fbabde001a23a2 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1562,8 +1562,7 @@ static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
>         return fwspec ? fwspec->ops : NULL;
>  }
>
> -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> -                                                      const u32 *id_in)
> +static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
>         int err;
>         const struct iommu_ops *ops;
> @@ -1574,7 +1573,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>          */
>         ops = acpi_iommu_fwspec_ops(dev);
>         if (ops)
> -               return ops;
> +               return 0;
>
>         err = iort_iommu_configure_id(dev, id_in);
>         if (err && err != -EPROBE_DEFER)
> @@ -1589,12 +1588,14 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>
>         /* Ignore all other errors apart from EPROBE_DEFER */
>         if (err == -EPROBE_DEFER) {
> -               return ERR_PTR(err);
> +               return err;
>         } else if (err) {
>                 dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> -               return NULL;
> +               return -ENODEV;
>         }
> -       return acpi_iommu_fwspec_ops(dev);
> +       if (!acpi_iommu_fwspec_ops(dev))
> +               return -ENODEV;
> +       return 0;
>  }
>
>  #else /* !CONFIG_IOMMU_API */
> @@ -1623,7 +1624,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>                           const u32 *input_id)
>  {
> -       const struct iommu_ops *iommu;
> +       int ret;
>
>         if (attr == DEV_DMA_NOT_SUPPORTED) {
>                 set_dma_ops(dev, &dma_dummy_ops);
> @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>
>         acpi_arch_dma_setup(dev);
>
> -       iommu = acpi_iommu_configure_id(dev, input_id);
> -       if (PTR_ERR(iommu) == -EPROBE_DEFER)
> +       ret = acpi_iommu_configure_id(dev, input_id);
> +       if (ret == -EPROBE_DEFER)
>                 return -EPROBE_DEFER;
>
> +       /*
> +        * Historically this routine doesn't fail driver probing due to errors
> +        * in acpi_iommu_configure()
> +        */
> +
>         arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
>
>         return 0;
> --
> 2.42.0
>

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-06 14:32     ` Rafael J. Wysocki
  0 siblings, 0 replies; 242+ messages in thread
From: Rafael J. Wysocki @ 2023-11-06 14:32 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: linux-hyperv, Rafael J. Wysocki, Catalin Marinas,
	Lorenzo Pieralisi, Robert Moore, Thierry Reding, Hanjun Guo,
	acpica-devel, Christoph Hellwig, Alyssa Rosenzweig,
	Marek Szyprowski, Jean-Philippe Brucker, Wei Liu, Will Deacon,
	Joerg Roedel, Dexuan Cui, Russell King, linux-riscv,
	Jonathan Hunter, linux-acpi, iommu, Vineet Gupta, linux-snps-arc,
	Len Brown, devicetree, Albert Ou, Sven Peter, Haiyang Zhang,
	Krishna Reddy, Rob Herring, Paul Walmsley, linux-tegra,
	virtualization, linux-arm-kernel, Thomas Bogendoerfer,
	Robin Murphy, Zhenhua Huang, Hector Martin, linux-mips,
	Palmer Dabbelt, asahi, Suravee Suthikulpanit, Sudeep Holla,
	David Woodhouse, Lu Baolu

On Fri, Nov 3, 2023 at 5:45 PM Jason Gunthorpe <jgg@nvidia.com> wrote:
>
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/acpi/scan.c | 24 +++++++++++++++---------
>  1 file changed, 15 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index a6891ad0ceee2c..fbabde001a23a2 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1562,8 +1562,7 @@ static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
>         return fwspec ? fwspec->ops : NULL;
>  }
>
> -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> -                                                      const u32 *id_in)
> +static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
>         int err;
>         const struct iommu_ops *ops;
> @@ -1574,7 +1573,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>          */
>         ops = acpi_iommu_fwspec_ops(dev);
>         if (ops)
> -               return ops;
> +               return 0;
>
>         err = iort_iommu_configure_id(dev, id_in);
>         if (err && err != -EPROBE_DEFER)
> @@ -1589,12 +1588,14 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>
>         /* Ignore all other errors apart from EPROBE_DEFER */
>         if (err == -EPROBE_DEFER) {
> -               return ERR_PTR(err);
> +               return err;
>         } else if (err) {
>                 dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> -               return NULL;
> +               return -ENODEV;
>         }
> -       return acpi_iommu_fwspec_ops(dev);
> +       if (!acpi_iommu_fwspec_ops(dev))
> +               return -ENODEV;
> +       return 0;
>  }
>
>  #else /* !CONFIG_IOMMU_API */
> @@ -1623,7 +1624,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>                           const u32 *input_id)
>  {
> -       const struct iommu_ops *iommu;
> +       int ret;
>
>         if (attr == DEV_DMA_NOT_SUPPORTED) {
>                 set_dma_ops(dev, &dma_dummy_ops);
> @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>
>         acpi_arch_dma_setup(dev);
>
> -       iommu = acpi_iommu_configure_id(dev, input_id);
> -       if (PTR_ERR(iommu) == -EPROBE_DEFER)
> +       ret = acpi_iommu_configure_id(dev, input_id);
> +       if (ret == -EPROBE_DEFER)
>                 return -EPROBE_DEFER;
>
> +       /*
> +        * Historically this routine doesn't fail driver probing due to errors
> +        * in acpi_iommu_configure()
> +        */
> +
>         arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
>
>         return 0;
> --
> 2.42.0
>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id()
@ 2023-11-06 14:32     ` Rafael J. Wysocki
  0 siblings, 0 replies; 242+ messages in thread
From: Rafael J. Wysocki @ 2023-11-06 14:32 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 3, 2023 at 5:45 PM Jason Gunthorpe <jgg@nvidia.com> wrote:
>
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/acpi/scan.c | 24 +++++++++++++++---------
>  1 file changed, 15 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index a6891ad0ceee2c..fbabde001a23a2 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1562,8 +1562,7 @@ static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
>         return fwspec ? fwspec->ops : NULL;
>  }
>
> -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> -                                                      const u32 *id_in)
> +static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
>         int err;
>         const struct iommu_ops *ops;
> @@ -1574,7 +1573,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>          */
>         ops = acpi_iommu_fwspec_ops(dev);
>         if (ops)
> -               return ops;
> +               return 0;
>
>         err = iort_iommu_configure_id(dev, id_in);
>         if (err && err != -EPROBE_DEFER)
> @@ -1589,12 +1588,14 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>
>         /* Ignore all other errors apart from EPROBE_DEFER */
>         if (err == -EPROBE_DEFER) {
> -               return ERR_PTR(err);
> +               return err;
>         } else if (err) {
>                 dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> -               return NULL;
> +               return -ENODEV;
>         }
> -       return acpi_iommu_fwspec_ops(dev);
> +       if (!acpi_iommu_fwspec_ops(dev))
> +               return -ENODEV;
> +       return 0;
>  }
>
>  #else /* !CONFIG_IOMMU_API */
> @@ -1623,7 +1624,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>                           const u32 *input_id)
>  {
> -       const struct iommu_ops *iommu;
> +       int ret;
>
>         if (attr == DEV_DMA_NOT_SUPPORTED) {
>                 set_dma_ops(dev, &dma_dummy_ops);
> @@ -1632,10 +1633,15 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>
>         acpi_arch_dma_setup(dev);
>
> -       iommu = acpi_iommu_configure_id(dev, input_id);
> -       if (PTR_ERR(iommu) == -EPROBE_DEFER)
> +       ret = acpi_iommu_configure_id(dev, input_id);
> +       if (ret == -EPROBE_DEFER)
>                 return -EPROBE_DEFER;
>
> +       /*
> +        * Historically this routine doesn't fail driver probing due to errors
> +        * in acpi_iommu_configure()
> +        */
> +
>         arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
>
>         return 0;
> --
> 2.42.0
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
  2023-11-03 16:44   ` Jason Gunthorpe
                       ` (2 preceding siblings ...)
  (?)
@ 2023-11-06 14:36     ` Rafael J. Wysocki
  -1 siblings, 0 replies; 242+ messages in thread
From: Rafael J. Wysocki @ 2023-11-06 14:36 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 3, 2023 at 5:45 PM Jason Gunthorpe <jgg@nvidia.com> wrote:
>
> This call chain is using dev->iommu->fwspec to pass around the fwspec
> between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
> iommu_probe_device()).
>
> However there is no locking around the accesses to dev->iommu, so this is
> all racy.
>
> Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
> pass it through all functions on the stack to fill it with data, and
> finally pass it into iommu_probe_device_fwspec() which will load it into
> dev->iommu under a lock.
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/acpi/arm64/iort.c | 39 ++++++++---------
>  drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
>  drivers/acpi/viot.c       | 44 ++++++++++---------
>  drivers/iommu/iommu.c     |  5 +--
>  include/acpi/acpi_bus.h   |  8 ++--
>  include/linux/acpi_iort.h |  3 +-
>  include/linux/acpi_viot.h |  5 ++-
>  include/linux/iommu.h     |  2 +
>  8 files changed, 97 insertions(+), 98 deletions(-)
>
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 6496ff5a6ba20d..accd01dcfe93f5 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
>         return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
>  }
>
> -static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> -                           u32 streamid)
> +static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> +                           struct acpi_iort_node *node, u32 streamid)
>  {
> -       const struct iommu_ops *ops;
>         struct fwnode_handle *iort_fwnode;
>
>         if (!node)
> @@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
>          * in the kernel or not, defer the IOMMU configuration
>          * or just abort it.
>          */
> -       ops = iommu_ops_from_fwnode(iort_fwnode);
> -       if (!ops)
> -               return iort_iommu_driver_enabled(node->type) ?
> -                      -EPROBE_DEFER : -ENODEV;
> -
> -       return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
> +       return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
> +                                     iort_iommu_driver_enabled(node->type));
>  }
>
>  struct iort_pci_alias_info {
>         struct device *dev;
>         struct acpi_iort_node *node;
> +       struct iommu_fwspec *fwspec;
>  };
>
>  static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> @@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
>
>         parent = iort_node_map_id(info->node, alias, &streamid,
>                                   IORT_IOMMU_TYPE);
> -       return iort_iommu_xlate(info->dev, parent, streamid);
> +       return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
>  }
>
>  static void iort_named_component_init(struct device *dev,
> @@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
>                 dev_warn(dev, "Could not add device properties\n");
>  }
>
> -static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> +static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
> +                            struct acpi_iort_node *node)
>  {
>         struct acpi_iort_node *parent;
>         int err = -ENODEV, i = 0;
> @@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
>                                                    i++);
>
>                 if (parent)
> -                       err = iort_iommu_xlate(dev, parent, streamid);
> +                       err = iort_iommu_xlate(fwspec, dev, parent, streamid);
>         } while (parent && !err);
>
>         return err;
>  }
>
> -static int iort_nc_iommu_map_id(struct device *dev,
> +static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
>                                 struct acpi_iort_node *node,
>                                 const u32 *in_id)
>  {
> @@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
>
>         parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
>         if (parent)
> -               return iort_iommu_xlate(dev, parent, streamid);
> +               return iort_iommu_xlate(fwspec, dev, parent, streamid);
>
>         return -ENODEV;
>  }
> @@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
>   *
>   * Returns: 0 on success, <0 on failure
>   */
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +                           const u32 *id_in)
>  {
>         struct acpi_iort_node *node;
>         int err = -ENODEV;
>
>         if (dev_is_pci(dev)) {
> -               struct iommu_fwspec *fwspec;
>                 struct pci_bus *bus = to_pci_dev(dev)->bus;
> -               struct iort_pci_alias_info info = { .dev = dev };
> +               struct iort_pci_alias_info info = { .dev = dev,
> +                                                   .fwspec = fwspec };
>
>                 node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
>                                       iort_match_node_callback, &bus->dev);
> @@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>                 err = pci_for_each_dma_alias(to_pci_dev(dev),
>                                              iort_pci_iommu_init, &info);
>
> -               fwspec = dev_iommu_fwspec_get(dev);
> -               if (fwspec && iort_pci_rc_supports_ats(node))
> +               if (iort_pci_rc_supports_ats(node))
>                         fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
>         } else {
>                 node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> @@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>                 if (!node)
>                         return -ENODEV;
>
> -               err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
> -                             iort_nc_iommu_map(dev, node);
> +               err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
> +                             iort_nc_iommu_map(fwspec, dev, node);
>
>                 if (!err)
>                         iort_named_component_init(dev, node);
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index fbabde001a23a2..1e01a8e0316867 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
>  }
>
>  #ifdef CONFIG_IOMMU_API
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -                          struct fwnode_handle *fwnode,
> -                          const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                          u32 id, struct fwnode_handle *fwnode,
> +                          bool iommu_driver_available)
>  {
> -       int ret = iommu_fwspec_init(dev, fwnode, ops);
> +       int ret;
>
> -       if (!ret)
> -               ret = iommu_fwspec_add_ids(dev, &id, 1);
> -
> -       return ret;
> -}
> -
> -static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
> -{
> -       struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> -
> -       return fwspec ? fwspec->ops : NULL;
> +       ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
> +       if (ret) {
> +               if (ret == -EPROBE_DEFER && !iommu_driver_available)
> +                       return -ENODEV;
> +               return ret;
> +       }
> +       return iommu_fwspec_append_ids(fwspec, &id, 1);
>  }
>
>  static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
>         int err;
> -       const struct iommu_ops *ops;
> +       struct iommu_fwspec *fwspec;
>
> -       /*
> -        * If we already translated the fwspec there is nothing left to do,
> -        * return the iommu_ops.
> -        */
> -       ops = acpi_iommu_fwspec_ops(dev);
> -       if (ops)
> -               return 0;
> +       fwspec = iommu_fwspec_alloc();
> +       if (IS_ERR(fwspec))
> +               return PTR_ERR(fwspec);
>
> -       err = iort_iommu_configure_id(dev, id_in);
> -       if (err && err != -EPROBE_DEFER)
> -               err = viot_iommu_configure(dev);
> +       err = iort_iommu_configure_id(fwspec, dev, id_in);
> +       if (err == -ENODEV)
> +               err = viot_iommu_configure(fwspec, dev);
> +       if (err == -ENODEV || err == -EPROBE_DEFER)
> +               goto err_free;
> +       if (err)
> +               goto err_log;
>
> -       /*
> -        * If we have reason to believe the IOMMU driver missed the initial
> -        * iommu_probe_device() call for dev, replay it to get things in order.
> -        */
> -       if (!err && dev->bus)
> -               err = iommu_probe_device(dev);
> -
> -       /* Ignore all other errors apart from EPROBE_DEFER */
> -       if (err == -EPROBE_DEFER) {
> -               return err;
> -       } else if (err) {
> -               dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> -               return -ENODEV;
> +       err = iommu_probe_device_fwspec(dev, fwspec);
> +       if (err) {
> +               /*
> +                * Ownership for fwspec always passes into
> +                * iommu_probe_device_fwspec()
> +                */
> +               fwspec = NULL;
> +               goto err_log;
>         }
> -       if (!acpi_iommu_fwspec_ops(dev))
> -               return -ENODEV;
> -       return 0;
> +
> +err_log:
> +       dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> +err_free:
> +       iommu_fwspec_dealloc(fwspec);
> +       return err;
>  }
>
>  #else /* !CONFIG_IOMMU_API */
>
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -                          struct fwnode_handle *fwnode,
> -                          const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                          u32 id, struct fwnode_handle *fwnode,
> +                          bool iommu_driver_available)
>  {
>         return -ENODEV;
>  }
>
> -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> -                                                      const u32 *id_in)
> +static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
> -       return NULL;
> +       return -ENODEV;
>  }
>
>  #endif /* !CONFIG_IOMMU_API */
> diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
> index c8025921c129b2..33b511dd202d15 100644
> --- a/drivers/acpi/viot.c
> +++ b/drivers/acpi/viot.c
> @@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
>         acpi_put_table(hdr);
>  }
>
> -static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> -                              u32 epid)
> +static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                              struct viot_iommu *viommu, u32 epid)
>  {
> -       const struct iommu_ops *ops;
> -
>         if (!viommu)
>                 return -ENODEV;
>
> @@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
>         if (device_match_fwnode(dev, viommu->fwnode))
>                 return -EINVAL;
>
> -       ops = iommu_ops_from_fwnode(viommu->fwnode);
> -       if (!ops)
> -               return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
> -                       -EPROBE_DEFER : -ENODEV;
> -
> -       return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
> +       return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
> +                                     IS_ENABLED(CONFIG_VIRTIO_IOMMU));
>  }
>
> +struct viot_pci_alias_info {
> +       struct device *dev;
> +       struct iommu_fwspec *fwspec;
> +};
> +
>  static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>  {
>         u32 epid;
>         struct viot_endpoint *ep;
> -       struct device *aliased_dev = data;
> +       struct viot_pci_alias_info *info = data;
>         u32 domain_nr = pci_domain_nr(pdev->bus);
>
>         list_for_each_entry(ep, &viot_pci_ranges, list) {
> @@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>                         epid = ((domain_nr - ep->segment_start) << 16) +
>                                 dev_id - ep->bdf_start + ep->endpoint_id;
>
> -                       return viot_dev_iommu_init(aliased_dev, ep->viommu,
> -                                                  epid);
> +                       return viot_dev_iommu_init(info->fwspec, info->dev,
> +                                                  ep->viommu, epid);
>                 }
>         }
>         return -ENODEV;
>  }
>
> -static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> +static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
> +                                   struct platform_device *pdev)
>  {
>         struct resource *mem;
>         struct viot_endpoint *ep;
> @@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>
>         list_for_each_entry(ep, &viot_mmio_endpoints, list) {
>                 if (ep->address == mem->start)
> -                       return viot_dev_iommu_init(&pdev->dev, ep->viommu,
> -                                                  ep->endpoint_id);
> +                       return viot_dev_iommu_init(fwspec, &pdev->dev,
> +                                                  ep->viommu, ep->endpoint_id);
>         }
>         return -ENODEV;
>  }
> @@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>   *
>   * Return: 0 on success, <0 on failure
>   */
> -int viot_iommu_configure(struct device *dev)
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
>  {
> -       if (dev_is_pci(dev))
> +       if (dev_is_pci(dev)) {
> +               struct viot_pci_alias_info info = { .dev = dev,
> +                                                   .fwspec = fwspec };
>                 return pci_for_each_dma_alias(to_pci_dev(dev),
> -                                             viot_pci_dev_iommu_init, dev);
> +                                             viot_pci_dev_iommu_init, &info);
> +       }
>         else if (dev_is_platform(dev))
> -               return viot_mmio_dev_iommu_init(to_platform_device(dev));
> +               return viot_mmio_dev_iommu_init(fwspec,
> +                                               to_platform_device(dev));
>         return -ENODEV;
>  }
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 15dbe2d9eb24c2..9cfba9d12d1400 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
>         return ops;
>  }
>
> -static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
> -                                    struct device *dev,
> -                                    struct fwnode_handle *iommu_fwnode)
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +                             struct fwnode_handle *iommu_fwnode)
>  {
>         const struct iommu_ops *ops;
>
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index 254685085c825c..70f97096c776e4 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -12,6 +12,8 @@
>  #include <linux/device.h>
>  #include <linux/property.h>
>
> +struct iommu_fwspec;
> +
>  /* TBD: Make dynamic */
>  #define ACPI_MAX_HANDLES       10
>  struct acpi_handle_list {
> @@ -625,9 +627,9 @@ struct acpi_pci_root {
>
>  bool acpi_dma_supported(const struct acpi_device *adev);
>  enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -                          struct fwnode_handle *fwnode,
> -                          const struct iommu_ops *ops);
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                          u32 id, struct fwnode_handle *fwnode,
> +                          bool iommu_driver_available);
>  int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>                            const u32 *input_id);
> diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> index 1cb65592c95dd3..80794ec45d1693 100644
> --- a/include/linux/acpi_iort.h
> +++ b/include/linux/acpi_iort.h
> @@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
>                        struct list_head *head);
>  /* IOMMU interface */
>  int iort_dma_get_ranges(struct device *dev, u64 *size);
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +                           const u32 *id_in);
>  void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
>  phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
>  #else
> diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
> index a5a12243156377..f1874cb6d43c09 100644
> --- a/include/linux/acpi_viot.h
> +++ b/include/linux/acpi_viot.h
> @@ -8,11 +8,12 @@
>  #ifdef CONFIG_ACPI_VIOT
>  void __init acpi_viot_early_init(void);
>  void __init acpi_viot_init(void);
> -int viot_iommu_configure(struct device *dev);
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
>  #else
>  static inline void acpi_viot_early_init(void) {}
>  static inline void acpi_viot_init(void) {}
> -static inline int viot_iommu_configure(struct device *dev)
> +static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
> +                                      struct device *dev)
>  {
>         return -ENODEV;
>  }
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index c5a5e2b5e2cc2a..27e4605d498850 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
>  int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
>                           struct fwnode_handle *iommu_fwnode,
>                           struct of_phandle_args *iommu_spec);
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +                             struct fwnode_handle *iommu_fwnode);
>
>  int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
>                       const struct iommu_ops *ops);
> --
> 2.42.0
>

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-06 14:36     ` Rafael J. Wysocki
  0 siblings, 0 replies; 242+ messages in thread
From: Rafael J. Wysocki @ 2023-11-06 14:36 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 3, 2023 at 5:45 PM Jason Gunthorpe <jgg@nvidia.com> wrote:
>
> This call chain is using dev->iommu->fwspec to pass around the fwspec
> between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
> iommu_probe_device()).
>
> However there is no locking around the accesses to dev->iommu, so this is
> all racy.
>
> Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
> pass it through all functions on the stack to fill it with data, and
> finally pass it into iommu_probe_device_fwspec() which will load it into
> dev->iommu under a lock.
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/acpi/arm64/iort.c | 39 ++++++++---------
>  drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
>  drivers/acpi/viot.c       | 44 ++++++++++---------
>  drivers/iommu/iommu.c     |  5 +--
>  include/acpi/acpi_bus.h   |  8 ++--
>  include/linux/acpi_iort.h |  3 +-
>  include/linux/acpi_viot.h |  5 ++-
>  include/linux/iommu.h     |  2 +
>  8 files changed, 97 insertions(+), 98 deletions(-)
>
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 6496ff5a6ba20d..accd01dcfe93f5 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
>         return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
>  }
>
> -static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> -                           u32 streamid)
> +static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> +                           struct acpi_iort_node *node, u32 streamid)
>  {
> -       const struct iommu_ops *ops;
>         struct fwnode_handle *iort_fwnode;
>
>         if (!node)
> @@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
>          * in the kernel or not, defer the IOMMU configuration
>          * or just abort it.
>          */
> -       ops = iommu_ops_from_fwnode(iort_fwnode);
> -       if (!ops)
> -               return iort_iommu_driver_enabled(node->type) ?
> -                      -EPROBE_DEFER : -ENODEV;
> -
> -       return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
> +       return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
> +                                     iort_iommu_driver_enabled(node->type));
>  }
>
>  struct iort_pci_alias_info {
>         struct device *dev;
>         struct acpi_iort_node *node;
> +       struct iommu_fwspec *fwspec;
>  };
>
>  static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> @@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
>
>         parent = iort_node_map_id(info->node, alias, &streamid,
>                                   IORT_IOMMU_TYPE);
> -       return iort_iommu_xlate(info->dev, parent, streamid);
> +       return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
>  }
>
>  static void iort_named_component_init(struct device *dev,
> @@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
>                 dev_warn(dev, "Could not add device properties\n");
>  }
>
> -static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> +static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
> +                            struct acpi_iort_node *node)
>  {
>         struct acpi_iort_node *parent;
>         int err = -ENODEV, i = 0;
> @@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
>                                                    i++);
>
>                 if (parent)
> -                       err = iort_iommu_xlate(dev, parent, streamid);
> +                       err = iort_iommu_xlate(fwspec, dev, parent, streamid);
>         } while (parent && !err);
>
>         return err;
>  }
>
> -static int iort_nc_iommu_map_id(struct device *dev,
> +static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
>                                 struct acpi_iort_node *node,
>                                 const u32 *in_id)
>  {
> @@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
>
>         parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
>         if (parent)
> -               return iort_iommu_xlate(dev, parent, streamid);
> +               return iort_iommu_xlate(fwspec, dev, parent, streamid);
>
>         return -ENODEV;
>  }
> @@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
>   *
>   * Returns: 0 on success, <0 on failure
>   */
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +                           const u32 *id_in)
>  {
>         struct acpi_iort_node *node;
>         int err = -ENODEV;
>
>         if (dev_is_pci(dev)) {
> -               struct iommu_fwspec *fwspec;
>                 struct pci_bus *bus = to_pci_dev(dev)->bus;
> -               struct iort_pci_alias_info info = { .dev = dev };
> +               struct iort_pci_alias_info info = { .dev = dev,
> +                                                   .fwspec = fwspec };
>
>                 node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
>                                       iort_match_node_callback, &bus->dev);
> @@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>                 err = pci_for_each_dma_alias(to_pci_dev(dev),
>                                              iort_pci_iommu_init, &info);
>
> -               fwspec = dev_iommu_fwspec_get(dev);
> -               if (fwspec && iort_pci_rc_supports_ats(node))
> +               if (iort_pci_rc_supports_ats(node))
>                         fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
>         } else {
>                 node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> @@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>                 if (!node)
>                         return -ENODEV;
>
> -               err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
> -                             iort_nc_iommu_map(dev, node);
> +               err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
> +                             iort_nc_iommu_map(fwspec, dev, node);
>
>                 if (!err)
>                         iort_named_component_init(dev, node);
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index fbabde001a23a2..1e01a8e0316867 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
>  }
>
>  #ifdef CONFIG_IOMMU_API
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -                          struct fwnode_handle *fwnode,
> -                          const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                          u32 id, struct fwnode_handle *fwnode,
> +                          bool iommu_driver_available)
>  {
> -       int ret = iommu_fwspec_init(dev, fwnode, ops);
> +       int ret;
>
> -       if (!ret)
> -               ret = iommu_fwspec_add_ids(dev, &id, 1);
> -
> -       return ret;
> -}
> -
> -static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
> -{
> -       struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> -
> -       return fwspec ? fwspec->ops : NULL;
> +       ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
> +       if (ret) {
> +               if (ret == -EPROBE_DEFER && !iommu_driver_available)
> +                       return -ENODEV;
> +               return ret;
> +       }
> +       return iommu_fwspec_append_ids(fwspec, &id, 1);
>  }
>
>  static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
>         int err;
> -       const struct iommu_ops *ops;
> +       struct iommu_fwspec *fwspec;
>
> -       /*
> -        * If we already translated the fwspec there is nothing left to do,
> -        * return the iommu_ops.
> -        */
> -       ops = acpi_iommu_fwspec_ops(dev);
> -       if (ops)
> -               return 0;
> +       fwspec = iommu_fwspec_alloc();
> +       if (IS_ERR(fwspec))
> +               return PTR_ERR(fwspec);
>
> -       err = iort_iommu_configure_id(dev, id_in);
> -       if (err && err != -EPROBE_DEFER)
> -               err = viot_iommu_configure(dev);
> +       err = iort_iommu_configure_id(fwspec, dev, id_in);
> +       if (err == -ENODEV)
> +               err = viot_iommu_configure(fwspec, dev);
> +       if (err == -ENODEV || err == -EPROBE_DEFER)
> +               goto err_free;
> +       if (err)
> +               goto err_log;
>
> -       /*
> -        * If we have reason to believe the IOMMU driver missed the initial
> -        * iommu_probe_device() call for dev, replay it to get things in order.
> -        */
> -       if (!err && dev->bus)
> -               err = iommu_probe_device(dev);
> -
> -       /* Ignore all other errors apart from EPROBE_DEFER */
> -       if (err == -EPROBE_DEFER) {
> -               return err;
> -       } else if (err) {
> -               dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> -               return -ENODEV;
> +       err = iommu_probe_device_fwspec(dev, fwspec);
> +       if (err) {
> +               /*
> +                * Ownership for fwspec always passes into
> +                * iommu_probe_device_fwspec()
> +                */
> +               fwspec = NULL;
> +               goto err_log;
>         }
> -       if (!acpi_iommu_fwspec_ops(dev))
> -               return -ENODEV;
> -       return 0;
> +
> +err_log:
> +       dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> +err_free:
> +       iommu_fwspec_dealloc(fwspec);
> +       return err;
>  }
>
>  #else /* !CONFIG_IOMMU_API */
>
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -                          struct fwnode_handle *fwnode,
> -                          const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                          u32 id, struct fwnode_handle *fwnode,
> +                          bool iommu_driver_available)
>  {
>         return -ENODEV;
>  }
>
> -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> -                                                      const u32 *id_in)
> +static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
> -       return NULL;
> +       return -ENODEV;
>  }
>
>  #endif /* !CONFIG_IOMMU_API */
> diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
> index c8025921c129b2..33b511dd202d15 100644
> --- a/drivers/acpi/viot.c
> +++ b/drivers/acpi/viot.c
> @@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
>         acpi_put_table(hdr);
>  }
>
> -static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> -                              u32 epid)
> +static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                              struct viot_iommu *viommu, u32 epid)
>  {
> -       const struct iommu_ops *ops;
> -
>         if (!viommu)
>                 return -ENODEV;
>
> @@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
>         if (device_match_fwnode(dev, viommu->fwnode))
>                 return -EINVAL;
>
> -       ops = iommu_ops_from_fwnode(viommu->fwnode);
> -       if (!ops)
> -               return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
> -                       -EPROBE_DEFER : -ENODEV;
> -
> -       return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
> +       return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
> +                                     IS_ENABLED(CONFIG_VIRTIO_IOMMU));
>  }
>
> +struct viot_pci_alias_info {
> +       struct device *dev;
> +       struct iommu_fwspec *fwspec;
> +};
> +
>  static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>  {
>         u32 epid;
>         struct viot_endpoint *ep;
> -       struct device *aliased_dev = data;
> +       struct viot_pci_alias_info *info = data;
>         u32 domain_nr = pci_domain_nr(pdev->bus);
>
>         list_for_each_entry(ep, &viot_pci_ranges, list) {
> @@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>                         epid = ((domain_nr - ep->segment_start) << 16) +
>                                 dev_id - ep->bdf_start + ep->endpoint_id;
>
> -                       return viot_dev_iommu_init(aliased_dev, ep->viommu,
> -                                                  epid);
> +                       return viot_dev_iommu_init(info->fwspec, info->dev,
> +                                                  ep->viommu, epid);
>                 }
>         }
>         return -ENODEV;
>  }
>
> -static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> +static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
> +                                   struct platform_device *pdev)
>  {
>         struct resource *mem;
>         struct viot_endpoint *ep;
> @@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>
>         list_for_each_entry(ep, &viot_mmio_endpoints, list) {
>                 if (ep->address == mem->start)
> -                       return viot_dev_iommu_init(&pdev->dev, ep->viommu,
> -                                                  ep->endpoint_id);
> +                       return viot_dev_iommu_init(fwspec, &pdev->dev,
> +                                                  ep->viommu, ep->endpoint_id);
>         }
>         return -ENODEV;
>  }
> @@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>   *
>   * Return: 0 on success, <0 on failure
>   */
> -int viot_iommu_configure(struct device *dev)
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
>  {
> -       if (dev_is_pci(dev))
> +       if (dev_is_pci(dev)) {
> +               struct viot_pci_alias_info info = { .dev = dev,
> +                                                   .fwspec = fwspec };
>                 return pci_for_each_dma_alias(to_pci_dev(dev),
> -                                             viot_pci_dev_iommu_init, dev);
> +                                             viot_pci_dev_iommu_init, &info);
> +       }
>         else if (dev_is_platform(dev))
> -               return viot_mmio_dev_iommu_init(to_platform_device(dev));
> +               return viot_mmio_dev_iommu_init(fwspec,
> +                                               to_platform_device(dev));
>         return -ENODEV;
>  }
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 15dbe2d9eb24c2..9cfba9d12d1400 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
>         return ops;
>  }
>
> -static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
> -                                    struct device *dev,
> -                                    struct fwnode_handle *iommu_fwnode)
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +                             struct fwnode_handle *iommu_fwnode)
>  {
>         const struct iommu_ops *ops;
>
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index 254685085c825c..70f97096c776e4 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -12,6 +12,8 @@
>  #include <linux/device.h>
>  #include <linux/property.h>
>
> +struct iommu_fwspec;
> +
>  /* TBD: Make dynamic */
>  #define ACPI_MAX_HANDLES       10
>  struct acpi_handle_list {
> @@ -625,9 +627,9 @@ struct acpi_pci_root {
>
>  bool acpi_dma_supported(const struct acpi_device *adev);
>  enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -                          struct fwnode_handle *fwnode,
> -                          const struct iommu_ops *ops);
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                          u32 id, struct fwnode_handle *fwnode,
> +                          bool iommu_driver_available);
>  int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>                            const u32 *input_id);
> diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> index 1cb65592c95dd3..80794ec45d1693 100644
> --- a/include/linux/acpi_iort.h
> +++ b/include/linux/acpi_iort.h
> @@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
>                        struct list_head *head);
>  /* IOMMU interface */
>  int iort_dma_get_ranges(struct device *dev, u64 *size);
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +                           const u32 *id_in);
>  void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
>  phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
>  #else
> diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
> index a5a12243156377..f1874cb6d43c09 100644
> --- a/include/linux/acpi_viot.h
> +++ b/include/linux/acpi_viot.h
> @@ -8,11 +8,12 @@
>  #ifdef CONFIG_ACPI_VIOT
>  void __init acpi_viot_early_init(void);
>  void __init acpi_viot_init(void);
> -int viot_iommu_configure(struct device *dev);
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
>  #else
>  static inline void acpi_viot_early_init(void) {}
>  static inline void acpi_viot_init(void) {}
> -static inline int viot_iommu_configure(struct device *dev)
> +static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
> +                                      struct device *dev)
>  {
>         return -ENODEV;
>  }
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index c5a5e2b5e2cc2a..27e4605d498850 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
>  int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
>                           struct fwnode_handle *iommu_fwnode,
>                           struct of_phandle_args *iommu_spec);
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +                             struct fwnode_handle *iommu_fwnode);
>
>  int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
>                       const struct iommu_ops *ops);
> --
> 2.42.0
>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-06 14:36     ` Rafael J. Wysocki
  0 siblings, 0 replies; 242+ messages in thread
From: Rafael J. Wysocki @ 2023-11-06 14:36 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 3, 2023 at 5:45 PM Jason Gunthorpe <jgg@nvidia.com> wrote:
>
> This call chain is using dev->iommu->fwspec to pass around the fwspec
> between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
> iommu_probe_device()).
>
> However there is no locking around the accesses to dev->iommu, so this is
> all racy.
>
> Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
> pass it through all functions on the stack to fill it with data, and
> finally pass it into iommu_probe_device_fwspec() which will load it into
> dev->iommu under a lock.
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/acpi/arm64/iort.c | 39 ++++++++---------
>  drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
>  drivers/acpi/viot.c       | 44 ++++++++++---------
>  drivers/iommu/iommu.c     |  5 +--
>  include/acpi/acpi_bus.h   |  8 ++--
>  include/linux/acpi_iort.h |  3 +-
>  include/linux/acpi_viot.h |  5 ++-
>  include/linux/iommu.h     |  2 +
>  8 files changed, 97 insertions(+), 98 deletions(-)
>
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 6496ff5a6ba20d..accd01dcfe93f5 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
>         return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
>  }
>
> -static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> -                           u32 streamid)
> +static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> +                           struct acpi_iort_node *node, u32 streamid)
>  {
> -       const struct iommu_ops *ops;
>         struct fwnode_handle *iort_fwnode;
>
>         if (!node)
> @@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
>          * in the kernel or not, defer the IOMMU configuration
>          * or just abort it.
>          */
> -       ops = iommu_ops_from_fwnode(iort_fwnode);
> -       if (!ops)
> -               return iort_iommu_driver_enabled(node->type) ?
> -                      -EPROBE_DEFER : -ENODEV;
> -
> -       return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
> +       return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
> +                                     iort_iommu_driver_enabled(node->type));
>  }
>
>  struct iort_pci_alias_info {
>         struct device *dev;
>         struct acpi_iort_node *node;
> +       struct iommu_fwspec *fwspec;
>  };
>
>  static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> @@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
>
>         parent = iort_node_map_id(info->node, alias, &streamid,
>                                   IORT_IOMMU_TYPE);
> -       return iort_iommu_xlate(info->dev, parent, streamid);
> +       return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
>  }
>
>  static void iort_named_component_init(struct device *dev,
> @@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
>                 dev_warn(dev, "Could not add device properties\n");
>  }
>
> -static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> +static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
> +                            struct acpi_iort_node *node)
>  {
>         struct acpi_iort_node *parent;
>         int err = -ENODEV, i = 0;
> @@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
>                                                    i++);
>
>                 if (parent)
> -                       err = iort_iommu_xlate(dev, parent, streamid);
> +                       err = iort_iommu_xlate(fwspec, dev, parent, streamid);
>         } while (parent && !err);
>
>         return err;
>  }
>
> -static int iort_nc_iommu_map_id(struct device *dev,
> +static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
>                                 struct acpi_iort_node *node,
>                                 const u32 *in_id)
>  {
> @@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
>
>         parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
>         if (parent)
> -               return iort_iommu_xlate(dev, parent, streamid);
> +               return iort_iommu_xlate(fwspec, dev, parent, streamid);
>
>         return -ENODEV;
>  }
> @@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
>   *
>   * Returns: 0 on success, <0 on failure
>   */
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +                           const u32 *id_in)
>  {
>         struct acpi_iort_node *node;
>         int err = -ENODEV;
>
>         if (dev_is_pci(dev)) {
> -               struct iommu_fwspec *fwspec;
>                 struct pci_bus *bus = to_pci_dev(dev)->bus;
> -               struct iort_pci_alias_info info = { .dev = dev };
> +               struct iort_pci_alias_info info = { .dev = dev,
> +                                                   .fwspec = fwspec };
>
>                 node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
>                                       iort_match_node_callback, &bus->dev);
> @@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>                 err = pci_for_each_dma_alias(to_pci_dev(dev),
>                                              iort_pci_iommu_init, &info);
>
> -               fwspec = dev_iommu_fwspec_get(dev);
> -               if (fwspec && iort_pci_rc_supports_ats(node))
> +               if (iort_pci_rc_supports_ats(node))
>                         fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
>         } else {
>                 node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> @@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>                 if (!node)
>                         return -ENODEV;
>
> -               err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
> -                             iort_nc_iommu_map(dev, node);
> +               err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
> +                             iort_nc_iommu_map(fwspec, dev, node);
>
>                 if (!err)
>                         iort_named_component_init(dev, node);
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index fbabde001a23a2..1e01a8e0316867 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
>  }
>
>  #ifdef CONFIG_IOMMU_API
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -                          struct fwnode_handle *fwnode,
> -                          const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                          u32 id, struct fwnode_handle *fwnode,
> +                          bool iommu_driver_available)
>  {
> -       int ret = iommu_fwspec_init(dev, fwnode, ops);
> +       int ret;
>
> -       if (!ret)
> -               ret = iommu_fwspec_add_ids(dev, &id, 1);
> -
> -       return ret;
> -}
> -
> -static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
> -{
> -       struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> -
> -       return fwspec ? fwspec->ops : NULL;
> +       ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
> +       if (ret) {
> +               if (ret == -EPROBE_DEFER && !iommu_driver_available)
> +                       return -ENODEV;
> +               return ret;
> +       }
> +       return iommu_fwspec_append_ids(fwspec, &id, 1);
>  }
>
>  static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
>         int err;
> -       const struct iommu_ops *ops;
> +       struct iommu_fwspec *fwspec;
>
> -       /*
> -        * If we already translated the fwspec there is nothing left to do,
> -        * return the iommu_ops.
> -        */
> -       ops = acpi_iommu_fwspec_ops(dev);
> -       if (ops)
> -               return 0;
> +       fwspec = iommu_fwspec_alloc();
> +       if (IS_ERR(fwspec))
> +               return PTR_ERR(fwspec);
>
> -       err = iort_iommu_configure_id(dev, id_in);
> -       if (err && err != -EPROBE_DEFER)
> -               err = viot_iommu_configure(dev);
> +       err = iort_iommu_configure_id(fwspec, dev, id_in);
> +       if (err == -ENODEV)
> +               err = viot_iommu_configure(fwspec, dev);
> +       if (err == -ENODEV || err == -EPROBE_DEFER)
> +               goto err_free;
> +       if (err)
> +               goto err_log;
>
> -       /*
> -        * If we have reason to believe the IOMMU driver missed the initial
> -        * iommu_probe_device() call for dev, replay it to get things in order.
> -        */
> -       if (!err && dev->bus)
> -               err = iommu_probe_device(dev);
> -
> -       /* Ignore all other errors apart from EPROBE_DEFER */
> -       if (err == -EPROBE_DEFER) {
> -               return err;
> -       } else if (err) {
> -               dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> -               return -ENODEV;
> +       err = iommu_probe_device_fwspec(dev, fwspec);
> +       if (err) {
> +               /*
> +                * Ownership for fwspec always passes into
> +                * iommu_probe_device_fwspec()
> +                */
> +               fwspec = NULL;
> +               goto err_log;
>         }
> -       if (!acpi_iommu_fwspec_ops(dev))
> -               return -ENODEV;
> -       return 0;
> +
> +err_log:
> +       dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> +err_free:
> +       iommu_fwspec_dealloc(fwspec);
> +       return err;
>  }
>
>  #else /* !CONFIG_IOMMU_API */
>
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -                          struct fwnode_handle *fwnode,
> -                          const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                          u32 id, struct fwnode_handle *fwnode,
> +                          bool iommu_driver_available)
>  {
>         return -ENODEV;
>  }
>
> -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> -                                                      const u32 *id_in)
> +static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
> -       return NULL;
> +       return -ENODEV;
>  }
>
>  #endif /* !CONFIG_IOMMU_API */
> diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
> index c8025921c129b2..33b511dd202d15 100644
> --- a/drivers/acpi/viot.c
> +++ b/drivers/acpi/viot.c
> @@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
>         acpi_put_table(hdr);
>  }
>
> -static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> -                              u32 epid)
> +static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                              struct viot_iommu *viommu, u32 epid)
>  {
> -       const struct iommu_ops *ops;
> -
>         if (!viommu)
>                 return -ENODEV;
>
> @@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
>         if (device_match_fwnode(dev, viommu->fwnode))
>                 return -EINVAL;
>
> -       ops = iommu_ops_from_fwnode(viommu->fwnode);
> -       if (!ops)
> -               return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
> -                       -EPROBE_DEFER : -ENODEV;
> -
> -       return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
> +       return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
> +                                     IS_ENABLED(CONFIG_VIRTIO_IOMMU));
>  }
>
> +struct viot_pci_alias_info {
> +       struct device *dev;
> +       struct iommu_fwspec *fwspec;
> +};
> +
>  static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>  {
>         u32 epid;
>         struct viot_endpoint *ep;
> -       struct device *aliased_dev = data;
> +       struct viot_pci_alias_info *info = data;
>         u32 domain_nr = pci_domain_nr(pdev->bus);
>
>         list_for_each_entry(ep, &viot_pci_ranges, list) {
> @@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>                         epid = ((domain_nr - ep->segment_start) << 16) +
>                                 dev_id - ep->bdf_start + ep->endpoint_id;
>
> -                       return viot_dev_iommu_init(aliased_dev, ep->viommu,
> -                                                  epid);
> +                       return viot_dev_iommu_init(info->fwspec, info->dev,
> +                                                  ep->viommu, epid);
>                 }
>         }
>         return -ENODEV;
>  }
>
> -static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> +static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
> +                                   struct platform_device *pdev)
>  {
>         struct resource *mem;
>         struct viot_endpoint *ep;
> @@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>
>         list_for_each_entry(ep, &viot_mmio_endpoints, list) {
>                 if (ep->address == mem->start)
> -                       return viot_dev_iommu_init(&pdev->dev, ep->viommu,
> -                                                  ep->endpoint_id);
> +                       return viot_dev_iommu_init(fwspec, &pdev->dev,
> +                                                  ep->viommu, ep->endpoint_id);
>         }
>         return -ENODEV;
>  }
> @@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>   *
>   * Return: 0 on success, <0 on failure
>   */
> -int viot_iommu_configure(struct device *dev)
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
>  {
> -       if (dev_is_pci(dev))
> +       if (dev_is_pci(dev)) {
> +               struct viot_pci_alias_info info = { .dev = dev,
> +                                                   .fwspec = fwspec };
>                 return pci_for_each_dma_alias(to_pci_dev(dev),
> -                                             viot_pci_dev_iommu_init, dev);
> +                                             viot_pci_dev_iommu_init, &info);
> +       }
>         else if (dev_is_platform(dev))
> -               return viot_mmio_dev_iommu_init(to_platform_device(dev));
> +               return viot_mmio_dev_iommu_init(fwspec,
> +                                               to_platform_device(dev));
>         return -ENODEV;
>  }
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 15dbe2d9eb24c2..9cfba9d12d1400 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
>         return ops;
>  }
>
> -static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
> -                                    struct device *dev,
> -                                    struct fwnode_handle *iommu_fwnode)
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +                             struct fwnode_handle *iommu_fwnode)
>  {
>         const struct iommu_ops *ops;
>
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index 254685085c825c..70f97096c776e4 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -12,6 +12,8 @@
>  #include <linux/device.h>
>  #include <linux/property.h>
>
> +struct iommu_fwspec;
> +
>  /* TBD: Make dynamic */
>  #define ACPI_MAX_HANDLES       10
>  struct acpi_handle_list {
> @@ -625,9 +627,9 @@ struct acpi_pci_root {
>
>  bool acpi_dma_supported(const struct acpi_device *adev);
>  enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -                          struct fwnode_handle *fwnode,
> -                          const struct iommu_ops *ops);
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                          u32 id, struct fwnode_handle *fwnode,
> +                          bool iommu_driver_available);
>  int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>                            const u32 *input_id);
> diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> index 1cb65592c95dd3..80794ec45d1693 100644
> --- a/include/linux/acpi_iort.h
> +++ b/include/linux/acpi_iort.h
> @@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
>                        struct list_head *head);
>  /* IOMMU interface */
>  int iort_dma_get_ranges(struct device *dev, u64 *size);
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +                           const u32 *id_in);
>  void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
>  phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
>  #else
> diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
> index a5a12243156377..f1874cb6d43c09 100644
> --- a/include/linux/acpi_viot.h
> +++ b/include/linux/acpi_viot.h
> @@ -8,11 +8,12 @@
>  #ifdef CONFIG_ACPI_VIOT
>  void __init acpi_viot_early_init(void);
>  void __init acpi_viot_init(void);
> -int viot_iommu_configure(struct device *dev);
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
>  #else
>  static inline void acpi_viot_early_init(void) {}
>  static inline void acpi_viot_init(void) {}
> -static inline int viot_iommu_configure(struct device *dev)
> +static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
> +                                      struct device *dev)
>  {
>         return -ENODEV;
>  }
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index c5a5e2b5e2cc2a..27e4605d498850 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
>  int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
>                           struct fwnode_handle *iommu_fwnode,
>                           struct of_phandle_args *iommu_spec);
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +                             struct fwnode_handle *iommu_fwnode);
>
>  int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
>                       const struct iommu_ops *ops);
> --
> 2.42.0
>

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-06 14:36     ` Rafael J. Wysocki
  0 siblings, 0 replies; 242+ messages in thread
From: Rafael J. Wysocki @ 2023-11-06 14:36 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: linux-hyperv, Rafael J. Wysocki, Catalin Marinas,
	Lorenzo Pieralisi, Robert Moore, Thierry Reding, Hanjun Guo,
	acpica-devel, Christoph Hellwig, Alyssa Rosenzweig,
	Marek Szyprowski, Jean-Philippe Brucker, Wei Liu, Will Deacon,
	Joerg Roedel, Dexuan Cui, Russell King, linux-riscv,
	Jonathan Hunter, linux-acpi, iommu, Vineet Gupta, linux-snps-arc,
	Len Brown, devicetree, Albert Ou, Sven Peter, Haiyang Zhang,
	Krishna Reddy, Rob Herring, Paul Walmsley, linux-tegra,
	virtualization, linux-arm-kernel, Thomas Bogendoerfer,
	Robin Murphy, Zhenhua Huang, Hector Martin, linux-mips,
	Palmer Dabbelt, asahi, Suravee Suthikulpanit, Sudeep Holla,
	David Woodhouse, Lu Baolu

On Fri, Nov 3, 2023 at 5:45 PM Jason Gunthorpe <jgg@nvidia.com> wrote:
>
> This call chain is using dev->iommu->fwspec to pass around the fwspec
> between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
> iommu_probe_device()).
>
> However there is no locking around the accesses to dev->iommu, so this is
> all racy.
>
> Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
> pass it through all functions on the stack to fill it with data, and
> finally pass it into iommu_probe_device_fwspec() which will load it into
> dev->iommu under a lock.
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/acpi/arm64/iort.c | 39 ++++++++---------
>  drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
>  drivers/acpi/viot.c       | 44 ++++++++++---------
>  drivers/iommu/iommu.c     |  5 +--
>  include/acpi/acpi_bus.h   |  8 ++--
>  include/linux/acpi_iort.h |  3 +-
>  include/linux/acpi_viot.h |  5 ++-
>  include/linux/iommu.h     |  2 +
>  8 files changed, 97 insertions(+), 98 deletions(-)
>
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 6496ff5a6ba20d..accd01dcfe93f5 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
>         return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
>  }
>
> -static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> -                           u32 streamid)
> +static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> +                           struct acpi_iort_node *node, u32 streamid)
>  {
> -       const struct iommu_ops *ops;
>         struct fwnode_handle *iort_fwnode;
>
>         if (!node)
> @@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
>          * in the kernel or not, defer the IOMMU configuration
>          * or just abort it.
>          */
> -       ops = iommu_ops_from_fwnode(iort_fwnode);
> -       if (!ops)
> -               return iort_iommu_driver_enabled(node->type) ?
> -                      -EPROBE_DEFER : -ENODEV;
> -
> -       return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
> +       return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
> +                                     iort_iommu_driver_enabled(node->type));
>  }
>
>  struct iort_pci_alias_info {
>         struct device *dev;
>         struct acpi_iort_node *node;
> +       struct iommu_fwspec *fwspec;
>  };
>
>  static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> @@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
>
>         parent = iort_node_map_id(info->node, alias, &streamid,
>                                   IORT_IOMMU_TYPE);
> -       return iort_iommu_xlate(info->dev, parent, streamid);
> +       return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
>  }
>
>  static void iort_named_component_init(struct device *dev,
> @@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
>                 dev_warn(dev, "Could not add device properties\n");
>  }
>
> -static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> +static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
> +                            struct acpi_iort_node *node)
>  {
>         struct acpi_iort_node *parent;
>         int err = -ENODEV, i = 0;
> @@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
>                                                    i++);
>
>                 if (parent)
> -                       err = iort_iommu_xlate(dev, parent, streamid);
> +                       err = iort_iommu_xlate(fwspec, dev, parent, streamid);
>         } while (parent && !err);
>
>         return err;
>  }
>
> -static int iort_nc_iommu_map_id(struct device *dev,
> +static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
>                                 struct acpi_iort_node *node,
>                                 const u32 *in_id)
>  {
> @@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
>
>         parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
>         if (parent)
> -               return iort_iommu_xlate(dev, parent, streamid);
> +               return iort_iommu_xlate(fwspec, dev, parent, streamid);
>
>         return -ENODEV;
>  }
> @@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
>   *
>   * Returns: 0 on success, <0 on failure
>   */
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +                           const u32 *id_in)
>  {
>         struct acpi_iort_node *node;
>         int err = -ENODEV;
>
>         if (dev_is_pci(dev)) {
> -               struct iommu_fwspec *fwspec;
>                 struct pci_bus *bus = to_pci_dev(dev)->bus;
> -               struct iort_pci_alias_info info = { .dev = dev };
> +               struct iort_pci_alias_info info = { .dev = dev,
> +                                                   .fwspec = fwspec };
>
>                 node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
>                                       iort_match_node_callback, &bus->dev);
> @@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>                 err = pci_for_each_dma_alias(to_pci_dev(dev),
>                                              iort_pci_iommu_init, &info);
>
> -               fwspec = dev_iommu_fwspec_get(dev);
> -               if (fwspec && iort_pci_rc_supports_ats(node))
> +               if (iort_pci_rc_supports_ats(node))
>                         fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
>         } else {
>                 node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> @@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>                 if (!node)
>                         return -ENODEV;
>
> -               err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
> -                             iort_nc_iommu_map(dev, node);
> +               err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
> +                             iort_nc_iommu_map(fwspec, dev, node);
>
>                 if (!err)
>                         iort_named_component_init(dev, node);
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index fbabde001a23a2..1e01a8e0316867 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
>  }
>
>  #ifdef CONFIG_IOMMU_API
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -                          struct fwnode_handle *fwnode,
> -                          const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                          u32 id, struct fwnode_handle *fwnode,
> +                          bool iommu_driver_available)
>  {
> -       int ret = iommu_fwspec_init(dev, fwnode, ops);
> +       int ret;
>
> -       if (!ret)
> -               ret = iommu_fwspec_add_ids(dev, &id, 1);
> -
> -       return ret;
> -}
> -
> -static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
> -{
> -       struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> -
> -       return fwspec ? fwspec->ops : NULL;
> +       ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
> +       if (ret) {
> +               if (ret == -EPROBE_DEFER && !iommu_driver_available)
> +                       return -ENODEV;
> +               return ret;
> +       }
> +       return iommu_fwspec_append_ids(fwspec, &id, 1);
>  }
>
>  static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
>         int err;
> -       const struct iommu_ops *ops;
> +       struct iommu_fwspec *fwspec;
>
> -       /*
> -        * If we already translated the fwspec there is nothing left to do,
> -        * return the iommu_ops.
> -        */
> -       ops = acpi_iommu_fwspec_ops(dev);
> -       if (ops)
> -               return 0;
> +       fwspec = iommu_fwspec_alloc();
> +       if (IS_ERR(fwspec))
> +               return PTR_ERR(fwspec);
>
> -       err = iort_iommu_configure_id(dev, id_in);
> -       if (err && err != -EPROBE_DEFER)
> -               err = viot_iommu_configure(dev);
> +       err = iort_iommu_configure_id(fwspec, dev, id_in);
> +       if (err == -ENODEV)
> +               err = viot_iommu_configure(fwspec, dev);
> +       if (err == -ENODEV || err == -EPROBE_DEFER)
> +               goto err_free;
> +       if (err)
> +               goto err_log;
>
> -       /*
> -        * If we have reason to believe the IOMMU driver missed the initial
> -        * iommu_probe_device() call for dev, replay it to get things in order.
> -        */
> -       if (!err && dev->bus)
> -               err = iommu_probe_device(dev);
> -
> -       /* Ignore all other errors apart from EPROBE_DEFER */
> -       if (err == -EPROBE_DEFER) {
> -               return err;
> -       } else if (err) {
> -               dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> -               return -ENODEV;
> +       err = iommu_probe_device_fwspec(dev, fwspec);
> +       if (err) {
> +               /*
> +                * Ownership for fwspec always passes into
> +                * iommu_probe_device_fwspec()
> +                */
> +               fwspec = NULL;
> +               goto err_log;
>         }
> -       if (!acpi_iommu_fwspec_ops(dev))
> -               return -ENODEV;
> -       return 0;
> +
> +err_log:
> +       dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> +err_free:
> +       iommu_fwspec_dealloc(fwspec);
> +       return err;
>  }
>
>  #else /* !CONFIG_IOMMU_API */
>
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -                          struct fwnode_handle *fwnode,
> -                          const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                          u32 id, struct fwnode_handle *fwnode,
> +                          bool iommu_driver_available)
>  {
>         return -ENODEV;
>  }
>
> -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> -                                                      const u32 *id_in)
> +static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
> -       return NULL;
> +       return -ENODEV;
>  }
>
>  #endif /* !CONFIG_IOMMU_API */
> diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
> index c8025921c129b2..33b511dd202d15 100644
> --- a/drivers/acpi/viot.c
> +++ b/drivers/acpi/viot.c
> @@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
>         acpi_put_table(hdr);
>  }
>
> -static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> -                              u32 epid)
> +static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                              struct viot_iommu *viommu, u32 epid)
>  {
> -       const struct iommu_ops *ops;
> -
>         if (!viommu)
>                 return -ENODEV;
>
> @@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
>         if (device_match_fwnode(dev, viommu->fwnode))
>                 return -EINVAL;
>
> -       ops = iommu_ops_from_fwnode(viommu->fwnode);
> -       if (!ops)
> -               return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
> -                       -EPROBE_DEFER : -ENODEV;
> -
> -       return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
> +       return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
> +                                     IS_ENABLED(CONFIG_VIRTIO_IOMMU));
>  }
>
> +struct viot_pci_alias_info {
> +       struct device *dev;
> +       struct iommu_fwspec *fwspec;
> +};
> +
>  static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>  {
>         u32 epid;
>         struct viot_endpoint *ep;
> -       struct device *aliased_dev = data;
> +       struct viot_pci_alias_info *info = data;
>         u32 domain_nr = pci_domain_nr(pdev->bus);
>
>         list_for_each_entry(ep, &viot_pci_ranges, list) {
> @@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>                         epid = ((domain_nr - ep->segment_start) << 16) +
>                                 dev_id - ep->bdf_start + ep->endpoint_id;
>
> -                       return viot_dev_iommu_init(aliased_dev, ep->viommu,
> -                                                  epid);
> +                       return viot_dev_iommu_init(info->fwspec, info->dev,
> +                                                  ep->viommu, epid);
>                 }
>         }
>         return -ENODEV;
>  }
>
> -static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> +static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
> +                                   struct platform_device *pdev)
>  {
>         struct resource *mem;
>         struct viot_endpoint *ep;
> @@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>
>         list_for_each_entry(ep, &viot_mmio_endpoints, list) {
>                 if (ep->address == mem->start)
> -                       return viot_dev_iommu_init(&pdev->dev, ep->viommu,
> -                                                  ep->endpoint_id);
> +                       return viot_dev_iommu_init(fwspec, &pdev->dev,
> +                                                  ep->viommu, ep->endpoint_id);
>         }
>         return -ENODEV;
>  }
> @@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>   *
>   * Return: 0 on success, <0 on failure
>   */
> -int viot_iommu_configure(struct device *dev)
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
>  {
> -       if (dev_is_pci(dev))
> +       if (dev_is_pci(dev)) {
> +               struct viot_pci_alias_info info = { .dev = dev,
> +                                                   .fwspec = fwspec };
>                 return pci_for_each_dma_alias(to_pci_dev(dev),
> -                                             viot_pci_dev_iommu_init, dev);
> +                                             viot_pci_dev_iommu_init, &info);
> +       }
>         else if (dev_is_platform(dev))
> -               return viot_mmio_dev_iommu_init(to_platform_device(dev));
> +               return viot_mmio_dev_iommu_init(fwspec,
> +                                               to_platform_device(dev));
>         return -ENODEV;
>  }
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 15dbe2d9eb24c2..9cfba9d12d1400 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
>         return ops;
>  }
>
> -static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
> -                                    struct device *dev,
> -                                    struct fwnode_handle *iommu_fwnode)
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +                             struct fwnode_handle *iommu_fwnode)
>  {
>         const struct iommu_ops *ops;
>
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index 254685085c825c..70f97096c776e4 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -12,6 +12,8 @@
>  #include <linux/device.h>
>  #include <linux/property.h>
>
> +struct iommu_fwspec;
> +
>  /* TBD: Make dynamic */
>  #define ACPI_MAX_HANDLES       10
>  struct acpi_handle_list {
> @@ -625,9 +627,9 @@ struct acpi_pci_root {
>
>  bool acpi_dma_supported(const struct acpi_device *adev);
>  enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -                          struct fwnode_handle *fwnode,
> -                          const struct iommu_ops *ops);
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                          u32 id, struct fwnode_handle *fwnode,
> +                          bool iommu_driver_available);
>  int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>                            const u32 *input_id);
> diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> index 1cb65592c95dd3..80794ec45d1693 100644
> --- a/include/linux/acpi_iort.h
> +++ b/include/linux/acpi_iort.h
> @@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
>                        struct list_head *head);
>  /* IOMMU interface */
>  int iort_dma_get_ranges(struct device *dev, u64 *size);
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +                           const u32 *id_in);
>  void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
>  phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
>  #else
> diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
> index a5a12243156377..f1874cb6d43c09 100644
> --- a/include/linux/acpi_viot.h
> +++ b/include/linux/acpi_viot.h
> @@ -8,11 +8,12 @@
>  #ifdef CONFIG_ACPI_VIOT
>  void __init acpi_viot_early_init(void);
>  void __init acpi_viot_init(void);
> -int viot_iommu_configure(struct device *dev);
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
>  #else
>  static inline void acpi_viot_early_init(void) {}
>  static inline void acpi_viot_init(void) {}
> -static inline int viot_iommu_configure(struct device *dev)
> +static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
> +                                      struct device *dev)
>  {
>         return -ENODEV;
>  }
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index c5a5e2b5e2cc2a..27e4605d498850 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
>  int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
>                           struct fwnode_handle *iommu_fwnode,
>                           struct of_phandle_args *iommu_spec);
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +                             struct fwnode_handle *iommu_fwnode);
>
>  int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
>                       const struct iommu_ops *ops);
> --
> 2.42.0
>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-06 14:36     ` Rafael J. Wysocki
  0 siblings, 0 replies; 242+ messages in thread
From: Rafael J. Wysocki @ 2023-11-06 14:36 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 3, 2023 at 5:45 PM Jason Gunthorpe <jgg@nvidia.com> wrote:
>
> This call chain is using dev->iommu->fwspec to pass around the fwspec
> between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
> iommu_probe_device()).
>
> However there is no locking around the accesses to dev->iommu, so this is
> all racy.
>
> Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
> pass it through all functions on the stack to fill it with data, and
> finally pass it into iommu_probe_device_fwspec() which will load it into
> dev->iommu under a lock.
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/acpi/arm64/iort.c | 39 ++++++++---------
>  drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
>  drivers/acpi/viot.c       | 44 ++++++++++---------
>  drivers/iommu/iommu.c     |  5 +--
>  include/acpi/acpi_bus.h   |  8 ++--
>  include/linux/acpi_iort.h |  3 +-
>  include/linux/acpi_viot.h |  5 ++-
>  include/linux/iommu.h     |  2 +
>  8 files changed, 97 insertions(+), 98 deletions(-)
>
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 6496ff5a6ba20d..accd01dcfe93f5 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
>         return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
>  }
>
> -static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> -                           u32 streamid)
> +static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> +                           struct acpi_iort_node *node, u32 streamid)
>  {
> -       const struct iommu_ops *ops;
>         struct fwnode_handle *iort_fwnode;
>
>         if (!node)
> @@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
>          * in the kernel or not, defer the IOMMU configuration
>          * or just abort it.
>          */
> -       ops = iommu_ops_from_fwnode(iort_fwnode);
> -       if (!ops)
> -               return iort_iommu_driver_enabled(node->type) ?
> -                      -EPROBE_DEFER : -ENODEV;
> -
> -       return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
> +       return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
> +                                     iort_iommu_driver_enabled(node->type));
>  }
>
>  struct iort_pci_alias_info {
>         struct device *dev;
>         struct acpi_iort_node *node;
> +       struct iommu_fwspec *fwspec;
>  };
>
>  static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> @@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
>
>         parent = iort_node_map_id(info->node, alias, &streamid,
>                                   IORT_IOMMU_TYPE);
> -       return iort_iommu_xlate(info->dev, parent, streamid);
> +       return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
>  }
>
>  static void iort_named_component_init(struct device *dev,
> @@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
>                 dev_warn(dev, "Could not add device properties\n");
>  }
>
> -static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> +static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
> +                            struct acpi_iort_node *node)
>  {
>         struct acpi_iort_node *parent;
>         int err = -ENODEV, i = 0;
> @@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
>                                                    i++);
>
>                 if (parent)
> -                       err = iort_iommu_xlate(dev, parent, streamid);
> +                       err = iort_iommu_xlate(fwspec, dev, parent, streamid);
>         } while (parent && !err);
>
>         return err;
>  }
>
> -static int iort_nc_iommu_map_id(struct device *dev,
> +static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
>                                 struct acpi_iort_node *node,
>                                 const u32 *in_id)
>  {
> @@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
>
>         parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
>         if (parent)
> -               return iort_iommu_xlate(dev, parent, streamid);
> +               return iort_iommu_xlate(fwspec, dev, parent, streamid);
>
>         return -ENODEV;
>  }
> @@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
>   *
>   * Returns: 0 on success, <0 on failure
>   */
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +                           const u32 *id_in)
>  {
>         struct acpi_iort_node *node;
>         int err = -ENODEV;
>
>         if (dev_is_pci(dev)) {
> -               struct iommu_fwspec *fwspec;
>                 struct pci_bus *bus = to_pci_dev(dev)->bus;
> -               struct iort_pci_alias_info info = { .dev = dev };
> +               struct iort_pci_alias_info info = { .dev = dev,
> +                                                   .fwspec = fwspec };
>
>                 node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
>                                       iort_match_node_callback, &bus->dev);
> @@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>                 err = pci_for_each_dma_alias(to_pci_dev(dev),
>                                              iort_pci_iommu_init, &info);
>
> -               fwspec = dev_iommu_fwspec_get(dev);
> -               if (fwspec && iort_pci_rc_supports_ats(node))
> +               if (iort_pci_rc_supports_ats(node))
>                         fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
>         } else {
>                 node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> @@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>                 if (!node)
>                         return -ENODEV;
>
> -               err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
> -                             iort_nc_iommu_map(dev, node);
> +               err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
> +                             iort_nc_iommu_map(fwspec, dev, node);
>
>                 if (!err)
>                         iort_named_component_init(dev, node);
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index fbabde001a23a2..1e01a8e0316867 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
>  }
>
>  #ifdef CONFIG_IOMMU_API
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -                          struct fwnode_handle *fwnode,
> -                          const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                          u32 id, struct fwnode_handle *fwnode,
> +                          bool iommu_driver_available)
>  {
> -       int ret = iommu_fwspec_init(dev, fwnode, ops);
> +       int ret;
>
> -       if (!ret)
> -               ret = iommu_fwspec_add_ids(dev, &id, 1);
> -
> -       return ret;
> -}
> -
> -static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
> -{
> -       struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> -
> -       return fwspec ? fwspec->ops : NULL;
> +       ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
> +       if (ret) {
> +               if (ret == -EPROBE_DEFER && !iommu_driver_available)
> +                       return -ENODEV;
> +               return ret;
> +       }
> +       return iommu_fwspec_append_ids(fwspec, &id, 1);
>  }
>
>  static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
>         int err;
> -       const struct iommu_ops *ops;
> +       struct iommu_fwspec *fwspec;
>
> -       /*
> -        * If we already translated the fwspec there is nothing left to do,
> -        * return the iommu_ops.
> -        */
> -       ops = acpi_iommu_fwspec_ops(dev);
> -       if (ops)
> -               return 0;
> +       fwspec = iommu_fwspec_alloc();
> +       if (IS_ERR(fwspec))
> +               return PTR_ERR(fwspec);
>
> -       err = iort_iommu_configure_id(dev, id_in);
> -       if (err && err != -EPROBE_DEFER)
> -               err = viot_iommu_configure(dev);
> +       err = iort_iommu_configure_id(fwspec, dev, id_in);
> +       if (err == -ENODEV)
> +               err = viot_iommu_configure(fwspec, dev);
> +       if (err == -ENODEV || err == -EPROBE_DEFER)
> +               goto err_free;
> +       if (err)
> +               goto err_log;
>
> -       /*
> -        * If we have reason to believe the IOMMU driver missed the initial
> -        * iommu_probe_device() call for dev, replay it to get things in order.
> -        */
> -       if (!err && dev->bus)
> -               err = iommu_probe_device(dev);
> -
> -       /* Ignore all other errors apart from EPROBE_DEFER */
> -       if (err == -EPROBE_DEFER) {
> -               return err;
> -       } else if (err) {
> -               dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> -               return -ENODEV;
> +       err = iommu_probe_device_fwspec(dev, fwspec);
> +       if (err) {
> +               /*
> +                * Ownership for fwspec always passes into
> +                * iommu_probe_device_fwspec()
> +                */
> +               fwspec = NULL;
> +               goto err_log;
>         }
> -       if (!acpi_iommu_fwspec_ops(dev))
> -               return -ENODEV;
> -       return 0;
> +
> +err_log:
> +       dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> +err_free:
> +       iommu_fwspec_dealloc(fwspec);
> +       return err;
>  }
>
>  #else /* !CONFIG_IOMMU_API */
>
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -                          struct fwnode_handle *fwnode,
> -                          const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                          u32 id, struct fwnode_handle *fwnode,
> +                          bool iommu_driver_available)
>  {
>         return -ENODEV;
>  }
>
> -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> -                                                      const u32 *id_in)
> +static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
> -       return NULL;
> +       return -ENODEV;
>  }
>
>  #endif /* !CONFIG_IOMMU_API */
> diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
> index c8025921c129b2..33b511dd202d15 100644
> --- a/drivers/acpi/viot.c
> +++ b/drivers/acpi/viot.c
> @@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
>         acpi_put_table(hdr);
>  }
>
> -static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> -                              u32 epid)
> +static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                              struct viot_iommu *viommu, u32 epid)
>  {
> -       const struct iommu_ops *ops;
> -
>         if (!viommu)
>                 return -ENODEV;
>
> @@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
>         if (device_match_fwnode(dev, viommu->fwnode))
>                 return -EINVAL;
>
> -       ops = iommu_ops_from_fwnode(viommu->fwnode);
> -       if (!ops)
> -               return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
> -                       -EPROBE_DEFER : -ENODEV;
> -
> -       return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
> +       return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
> +                                     IS_ENABLED(CONFIG_VIRTIO_IOMMU));
>  }
>
> +struct viot_pci_alias_info {
> +       struct device *dev;
> +       struct iommu_fwspec *fwspec;
> +};
> +
>  static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>  {
>         u32 epid;
>         struct viot_endpoint *ep;
> -       struct device *aliased_dev = data;
> +       struct viot_pci_alias_info *info = data;
>         u32 domain_nr = pci_domain_nr(pdev->bus);
>
>         list_for_each_entry(ep, &viot_pci_ranges, list) {
> @@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>                         epid = ((domain_nr - ep->segment_start) << 16) +
>                                 dev_id - ep->bdf_start + ep->endpoint_id;
>
> -                       return viot_dev_iommu_init(aliased_dev, ep->viommu,
> -                                                  epid);
> +                       return viot_dev_iommu_init(info->fwspec, info->dev,
> +                                                  ep->viommu, epid);
>                 }
>         }
>         return -ENODEV;
>  }
>
> -static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> +static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
> +                                   struct platform_device *pdev)
>  {
>         struct resource *mem;
>         struct viot_endpoint *ep;
> @@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>
>         list_for_each_entry(ep, &viot_mmio_endpoints, list) {
>                 if (ep->address == mem->start)
> -                       return viot_dev_iommu_init(&pdev->dev, ep->viommu,
> -                                                  ep->endpoint_id);
> +                       return viot_dev_iommu_init(fwspec, &pdev->dev,
> +                                                  ep->viommu, ep->endpoint_id);
>         }
>         return -ENODEV;
>  }
> @@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>   *
>   * Return: 0 on success, <0 on failure
>   */
> -int viot_iommu_configure(struct device *dev)
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
>  {
> -       if (dev_is_pci(dev))
> +       if (dev_is_pci(dev)) {
> +               struct viot_pci_alias_info info = { .dev = dev,
> +                                                   .fwspec = fwspec };
>                 return pci_for_each_dma_alias(to_pci_dev(dev),
> -                                             viot_pci_dev_iommu_init, dev);
> +                                             viot_pci_dev_iommu_init, &info);
> +       }
>         else if (dev_is_platform(dev))
> -               return viot_mmio_dev_iommu_init(to_platform_device(dev));
> +               return viot_mmio_dev_iommu_init(fwspec,
> +                                               to_platform_device(dev));
>         return -ENODEV;
>  }
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 15dbe2d9eb24c2..9cfba9d12d1400 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
>         return ops;
>  }
>
> -static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
> -                                    struct device *dev,
> -                                    struct fwnode_handle *iommu_fwnode)
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +                             struct fwnode_handle *iommu_fwnode)
>  {
>         const struct iommu_ops *ops;
>
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index 254685085c825c..70f97096c776e4 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -12,6 +12,8 @@
>  #include <linux/device.h>
>  #include <linux/property.h>
>
> +struct iommu_fwspec;
> +
>  /* TBD: Make dynamic */
>  #define ACPI_MAX_HANDLES       10
>  struct acpi_handle_list {
> @@ -625,9 +627,9 @@ struct acpi_pci_root {
>
>  bool acpi_dma_supported(const struct acpi_device *adev);
>  enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -                          struct fwnode_handle *fwnode,
> -                          const struct iommu_ops *ops);
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +                          u32 id, struct fwnode_handle *fwnode,
> +                          bool iommu_driver_available);
>  int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>                            const u32 *input_id);
> diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> index 1cb65592c95dd3..80794ec45d1693 100644
> --- a/include/linux/acpi_iort.h
> +++ b/include/linux/acpi_iort.h
> @@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
>                        struct list_head *head);
>  /* IOMMU interface */
>  int iort_dma_get_ranges(struct device *dev, u64 *size);
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +                           const u32 *id_in);
>  void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
>  phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
>  #else
> diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
> index a5a12243156377..f1874cb6d43c09 100644
> --- a/include/linux/acpi_viot.h
> +++ b/include/linux/acpi_viot.h
> @@ -8,11 +8,12 @@
>  #ifdef CONFIG_ACPI_VIOT
>  void __init acpi_viot_early_init(void);
>  void __init acpi_viot_init(void);
> -int viot_iommu_configure(struct device *dev);
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
>  #else
>  static inline void acpi_viot_early_init(void) {}
>  static inline void acpi_viot_init(void) {}
> -static inline int viot_iommu_configure(struct device *dev)
> +static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
> +                                      struct device *dev)
>  {
>         return -ENODEV;
>  }
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index c5a5e2b5e2cc2a..27e4605d498850 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
>  int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
>                           struct fwnode_handle *iommu_fwnode,
>                           struct of_phandle_args *iommu_spec);
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +                             struct fwnode_handle *iommu_fwnode);
>
>  int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
>                       const struct iommu_ops *ops);
> --
> 2.42.0
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-08  8:01     ` Baolu Lu
  -1 siblings, 0 replies; 242+ messages in thread
From: Baolu Lu @ 2023-11-08  8:01 UTC (permalink / raw)
  To: Jason Gunthorpe, acpica-devel, Alyssa Rosenzweig, Albert Ou,
	asahi, Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: baolu.lu, Zhenhua Huang

On 2023/11/4 0:44, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.
> 
> Signed-off-by: Jason Gunthorpe<jgg@nvidia.com>
> ---
>   arch/arc/mm/dma.c               |  2 +-
>   arch/arm/mm/dma-mapping-nommu.c |  2 +-
>   arch/arm/mm/dma-mapping.c       | 10 +++++-----
>   arch/arm64/mm/dma-mapping.c     |  4 ++--
>   arch/mips/mm/dma-noncoherent.c  |  2 +-
>   arch/riscv/mm/dma-noncoherent.c |  2 +-
>   drivers/acpi/scan.c             |  3 +--
>   drivers/hv/hv_common.c          |  2 +-
>   drivers/of/device.c             |  2 +-
>   include/linux/dma-map-ops.h     |  4 ++--
>   10 files changed, 16 insertions(+), 17 deletions(-)

Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>

Best regards,
baolu

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-08  8:01     ` Baolu Lu
  0 siblings, 0 replies; 242+ messages in thread
From: Baolu Lu @ 2023-11-08  8:01 UTC (permalink / raw)
  To: Jason Gunthorpe, acpica-devel, Alyssa Rosenzweig, Albert Ou,
	asahi, Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: baolu.lu, Zhenhua Huang

On 2023/11/4 0:44, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.
> 
> Signed-off-by: Jason Gunthorpe<jgg@nvidia.com>
> ---
>   arch/arc/mm/dma.c               |  2 +-
>   arch/arm/mm/dma-mapping-nommu.c |  2 +-
>   arch/arm/mm/dma-mapping.c       | 10 +++++-----
>   arch/arm64/mm/dma-mapping.c     |  4 ++--
>   arch/mips/mm/dma-noncoherent.c  |  2 +-
>   arch/riscv/mm/dma-noncoherent.c |  2 +-
>   drivers/acpi/scan.c             |  3 +--
>   drivers/hv/hv_common.c          |  2 +-
>   drivers/of/device.c             |  2 +-
>   include/linux/dma-map-ops.h     |  4 ++--
>   10 files changed, 16 insertions(+), 17 deletions(-)

Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>

Best regards,
baolu

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-08  8:01     ` Baolu Lu
  0 siblings, 0 replies; 242+ messages in thread
From: Baolu Lu @ 2023-11-08  8:01 UTC (permalink / raw)
  To: Jason Gunthorpe, acpica-devel, Alyssa Rosenzweig, Albert Ou,
	asahi, Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: baolu.lu, Zhenhua Huang

On 2023/11/4 0:44, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.
> 
> Signed-off-by: Jason Gunthorpe<jgg@nvidia.com>
> ---
>   arch/arc/mm/dma.c               |  2 +-
>   arch/arm/mm/dma-mapping-nommu.c |  2 +-
>   arch/arm/mm/dma-mapping.c       | 10 +++++-----
>   arch/arm64/mm/dma-mapping.c     |  4 ++--
>   arch/mips/mm/dma-noncoherent.c  |  2 +-
>   arch/riscv/mm/dma-noncoherent.c |  2 +-
>   drivers/acpi/scan.c             |  3 +--
>   drivers/hv/hv_common.c          |  2 +-
>   drivers/of/device.c             |  2 +-
>   include/linux/dma-map-ops.h     |  4 ++--
>   10 files changed, 16 insertions(+), 17 deletions(-)

Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>

Best regards,
baolu

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-08  8:01     ` Baolu Lu
  0 siblings, 0 replies; 242+ messages in thread
From: Baolu Lu @ 2023-11-08  8:01 UTC (permalink / raw)
  To: Jason Gunthorpe, acpica-devel, Alyssa Rosenzweig, Albert Ou,
	asahi, Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: baolu.lu, Zhenhua Huang

On 2023/11/4 0:44, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.
> 
> Signed-off-by: Jason Gunthorpe<jgg@nvidia.com>
> ---
>   arch/arc/mm/dma.c               |  2 +-
>   arch/arm/mm/dma-mapping-nommu.c |  2 +-
>   arch/arm/mm/dma-mapping.c       | 10 +++++-----
>   arch/arm64/mm/dma-mapping.c     |  4 ++--
>   arch/mips/mm/dma-noncoherent.c  |  2 +-
>   arch/riscv/mm/dma-noncoherent.c |  2 +-
>   drivers/acpi/scan.c             |  3 +--
>   drivers/hv/hv_common.c          |  2 +-
>   drivers/of/device.c             |  2 +-
>   include/linux/dma-map-ops.h     |  4 ++--
>   10 files changed, 16 insertions(+), 17 deletions(-)

Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>

Best regards,
baolu

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 17/17] iommu: Mark dev_iommu_priv_set() with a lockdep
  2023-11-03 16:45   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-08  8:18     ` Baolu Lu
  -1 siblings, 0 replies; 242+ messages in thread
From: Baolu Lu @ 2023-11-08  8:18 UTC (permalink / raw)
  To: Jason Gunthorpe, acpica-devel, Alyssa Rosenzweig, Albert Ou,
	asahi, Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: baolu.lu, Zhenhua Huang

On 2023/11/4 0:45, Jason Gunthorpe wrote:
> A perfect driver would only call dev_iommu_priv_set() from its probe
> callback. We've made it functionally correct to call it from the of_xlate
> by adding a lock around that call.
> 
> lockdep assert that iommu_probe_device_lock is held to discourage misuse.
> 
> Exclude PPC kernels with CONFIG_FSL_PAMU turned on because FSL_PAMU uses a
> global static for its priv and abuses priv for its domain.
> 
> Remove the pointless stores of NULL, all these are on paths where the core
> code will free dev->iommu after the op returns.
> 
> Signed-off-by: Jason Gunthorpe<jgg@nvidia.com>
> ---
>   drivers/iommu/amd/iommu.c                   | 2 --
>   drivers/iommu/apple-dart.c                  | 1 -
>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 -
>   drivers/iommu/arm/arm-smmu/arm-smmu.c       | 1 -
>   drivers/iommu/intel/iommu.c                 | 2 --
>   drivers/iommu/iommu.c                       | 9 +++++++++
>   drivers/iommu/omap-iommu.c                  | 1 -
>   include/linux/iommu.h                       | 5 +----
>   8 files changed, 10 insertions(+), 12 deletions(-)

Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>

Best regards,
baolu

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 17/17] iommu: Mark dev_iommu_priv_set() with a lockdep
@ 2023-11-08  8:18     ` Baolu Lu
  0 siblings, 0 replies; 242+ messages in thread
From: Baolu Lu @ 2023-11-08  8:18 UTC (permalink / raw)
  To: Jason Gunthorpe, acpica-devel, Alyssa Rosenzweig, Albert Ou,
	asahi, Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: baolu.lu, Zhenhua Huang

On 2023/11/4 0:45, Jason Gunthorpe wrote:
> A perfect driver would only call dev_iommu_priv_set() from its probe
> callback. We've made it functionally correct to call it from the of_xlate
> by adding a lock around that call.
> 
> lockdep assert that iommu_probe_device_lock is held to discourage misuse.
> 
> Exclude PPC kernels with CONFIG_FSL_PAMU turned on because FSL_PAMU uses a
> global static for its priv and abuses priv for its domain.
> 
> Remove the pointless stores of NULL, all these are on paths where the core
> code will free dev->iommu after the op returns.
> 
> Signed-off-by: Jason Gunthorpe<jgg@nvidia.com>
> ---
>   drivers/iommu/amd/iommu.c                   | 2 --
>   drivers/iommu/apple-dart.c                  | 1 -
>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 -
>   drivers/iommu/arm/arm-smmu/arm-smmu.c       | 1 -
>   drivers/iommu/intel/iommu.c                 | 2 --
>   drivers/iommu/iommu.c                       | 9 +++++++++
>   drivers/iommu/omap-iommu.c                  | 1 -
>   include/linux/iommu.h                       | 5 +----
>   8 files changed, 10 insertions(+), 12 deletions(-)

Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>

Best regards,
baolu

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 17/17] iommu: Mark dev_iommu_priv_set() with a lockdep
@ 2023-11-08  8:18     ` Baolu Lu
  0 siblings, 0 replies; 242+ messages in thread
From: Baolu Lu @ 2023-11-08  8:18 UTC (permalink / raw)
  To: Jason Gunthorpe, acpica-devel, Alyssa Rosenzweig, Albert Ou,
	asahi, Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: baolu.lu, Zhenhua Huang

On 2023/11/4 0:45, Jason Gunthorpe wrote:
> A perfect driver would only call dev_iommu_priv_set() from its probe
> callback. We've made it functionally correct to call it from the of_xlate
> by adding a lock around that call.
> 
> lockdep assert that iommu_probe_device_lock is held to discourage misuse.
> 
> Exclude PPC kernels with CONFIG_FSL_PAMU turned on because FSL_PAMU uses a
> global static for its priv and abuses priv for its domain.
> 
> Remove the pointless stores of NULL, all these are on paths where the core
> code will free dev->iommu after the op returns.
> 
> Signed-off-by: Jason Gunthorpe<jgg@nvidia.com>
> ---
>   drivers/iommu/amd/iommu.c                   | 2 --
>   drivers/iommu/apple-dart.c                  | 1 -
>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 -
>   drivers/iommu/arm/arm-smmu/arm-smmu.c       | 1 -
>   drivers/iommu/intel/iommu.c                 | 2 --
>   drivers/iommu/iommu.c                       | 9 +++++++++
>   drivers/iommu/omap-iommu.c                  | 1 -
>   include/linux/iommu.h                       | 5 +----
>   8 files changed, 10 insertions(+), 12 deletions(-)

Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>

Best regards,
baolu

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 17/17] iommu: Mark dev_iommu_priv_set() with a lockdep
@ 2023-11-08  8:18     ` Baolu Lu
  0 siblings, 0 replies; 242+ messages in thread
From: Baolu Lu @ 2023-11-08  8:18 UTC (permalink / raw)
  To: Jason Gunthorpe, acpica-devel, Alyssa Rosenzweig, Albert Ou,
	asahi, Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: baolu.lu, Zhenhua Huang

On 2023/11/4 0:45, Jason Gunthorpe wrote:
> A perfect driver would only call dev_iommu_priv_set() from its probe
> callback. We've made it functionally correct to call it from the of_xlate
> by adding a lock around that call.
> 
> lockdep assert that iommu_probe_device_lock is held to discourage misuse.
> 
> Exclude PPC kernels with CONFIG_FSL_PAMU turned on because FSL_PAMU uses a
> global static for its priv and abuses priv for its domain.
> 
> Remove the pointless stores of NULL, all these are on paths where the core
> code will free dev->iommu after the op returns.
> 
> Signed-off-by: Jason Gunthorpe<jgg@nvidia.com>
> ---
>   drivers/iommu/amd/iommu.c                   | 2 --
>   drivers/iommu/apple-dart.c                  | 1 -
>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 -
>   drivers/iommu/arm/arm-smmu/arm-smmu.c       | 1 -
>   drivers/iommu/intel/iommu.c                 | 2 --
>   drivers/iommu/iommu.c                       | 9 +++++++++
>   drivers/iommu/omap-iommu.c                  | 1 -
>   include/linux/iommu.h                       | 5 +----
>   8 files changed, 10 insertions(+), 12 deletions(-)

Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>

Best regards,
baolu

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-08 16:11     ` Rob Herring
  -1 siblings, 0 replies; 242+ messages in thread
From: Rob Herring @ 2023-11-08 16:11 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Robin Murphy, Sudeep Holla, Suravee Suthikulpanit,
	Sven Peter, Thierry Reding, Thomas Bogendoerfer, Krishna Reddy,
	Vineet Gupta, virtualization, Wei Liu, Will Deacon,
	Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:48PM -0300, Jason Gunthorpe wrote:
> Instead of returning 1 and trying to handle positive error codes just
> stick to the convention of returning -ENODEV. Remove references to ops
> from of_iommu_configure(), a NULL ops will already generate an error code.

nit: "iommu: of: ..." or "iommu/of: " for the subject. "of: ..." is 
generally drivers/of/.

> 
> There is no reason to check dev->bus, if err=0 at this point then the
> called configure functions thought there was an iommu and we should try to
> probe it. Remove it.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/of_iommu.c | 42 +++++++++++++---------------------------
>  1 file changed, 13 insertions(+), 29 deletions(-)

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
@ 2023-11-08 16:11     ` Rob Herring
  0 siblings, 0 replies; 242+ messages in thread
From: Rob Herring @ 2023-11-08 16:11 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Robin Murphy, Sudeep Holla, Suravee Suthikulpanit,
	Sven Peter, Thierry Reding, Thomas Bogendoerfer, Krishna Reddy,
	Vineet Gupta, virtualization, Wei Liu, Will Deacon,
	Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:48PM -0300, Jason Gunthorpe wrote:
> Instead of returning 1 and trying to handle positive error codes just
> stick to the convention of returning -ENODEV. Remove references to ops
> from of_iommu_configure(), a NULL ops will already generate an error code.

nit: "iommu: of: ..." or "iommu/of: " for the subject. "of: ..." is 
generally drivers/of/.

> 
> There is no reason to check dev->bus, if err=0 at this point then the
> called configure functions thought there was an iommu and we should try to
> probe it. Remove it.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/of_iommu.c | 42 +++++++++++++---------------------------
>  1 file changed, 13 insertions(+), 29 deletions(-)

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
@ 2023-11-08 16:11     ` Rob Herring
  0 siblings, 0 replies; 242+ messages in thread
From: Rob Herring @ 2023-11-08 16:11 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Robin Murphy, Sudeep Holla, Suravee Suthikulpanit,
	Sven Peter, Thierry Reding, Thomas Bogendoerfer, Krishna Reddy,
	Vineet Gupta, virtualization, Wei Liu, Will Deacon,
	Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:48PM -0300, Jason Gunthorpe wrote:
> Instead of returning 1 and trying to handle positive error codes just
> stick to the convention of returning -ENODEV. Remove references to ops
> from of_iommu_configure(), a NULL ops will already generate an error code.

nit: "iommu: of: ..." or "iommu/of: " for the subject. "of: ..." is 
generally drivers/of/.

> 
> There is no reason to check dev->bus, if err=0 at this point then the
> called configure functions thought there was an iommu and we should try to
> probe it. Remove it.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/of_iommu.c | 42 +++++++++++++---------------------------
>  1 file changed, 13 insertions(+), 29 deletions(-)

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure()
@ 2023-11-08 16:11     ` Rob Herring
  0 siblings, 0 replies; 242+ messages in thread
From: Rob Herring @ 2023-11-08 16:11 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Robin Murphy, Sudeep Holla, Suravee Suthikulpanit,
	Sven Peter, Thierry Reding, Thomas Bogendoerfer, Krishna Reddy,
	Vineet Gupta, virtualization, Wei Liu, Will Deacon,
	Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:48PM -0300, Jason Gunthorpe wrote:
> Instead of returning 1 and trying to handle positive error codes just
> stick to the convention of returning -ENODEV. Remove references to ops
> from of_iommu_configure(), a NULL ops will already generate an error code.

nit: "iommu: of: ..." or "iommu/of: " for the subject. "of: ..." is 
generally drivers/of/.

> 
> There is no reason to check dev->bus, if err=0 at this point then the
> called configure functions thought there was an iommu and we should try to
> probe it. Remove it.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/of_iommu.c | 42 +++++++++++++---------------------------
>  1 file changed, 13 insertions(+), 29 deletions(-)

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-08 16:17     ` Rob Herring
  -1 siblings, 0 replies; 242+ messages in thread
From: Rob Herring @ 2023-11-08 16:17 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Robin Murphy, Sudeep Holla, Suravee Suthikulpanit,
	Sven Peter, Thierry Reding, Thomas Bogendoerfer, Krishna Reddy,
	Vineet Gupta, virtualization, Wei Liu, Will Deacon,
	Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:47PM -0300, Jason Gunthorpe wrote:
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
>  drivers/of/device.c      | 22 +++++++++++++++-------

Acked-by: Rob Herring <robh@kernel.org>

>  include/linux/of_iommu.h | 13 ++++++-------
>  3 files changed, 39 insertions(+), 25 deletions(-)

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
@ 2023-11-08 16:17     ` Rob Herring
  0 siblings, 0 replies; 242+ messages in thread
From: Rob Herring @ 2023-11-08 16:17 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Robin Murphy, Sudeep Holla, Suravee Suthikulpanit,
	Sven Peter, Thierry Reding, Thomas Bogendoerfer, Krishna Reddy,
	Vineet Gupta, virtualization, Wei Liu, Will Deacon,
	Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:47PM -0300, Jason Gunthorpe wrote:
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
>  drivers/of/device.c      | 22 +++++++++++++++-------

Acked-by: Rob Herring <robh@kernel.org>

>  include/linux/of_iommu.h | 13 ++++++-------
>  3 files changed, 39 insertions(+), 25 deletions(-)

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
@ 2023-11-08 16:17     ` Rob Herring
  0 siblings, 0 replies; 242+ messages in thread
From: Rob Herring @ 2023-11-08 16:17 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Robin Murphy, Sudeep Holla, Suravee Suthikulpanit,
	Sven Peter, Thierry Reding, Thomas Bogendoerfer, Krishna Reddy,
	Vineet Gupta, virtualization, Wei Liu, Will Deacon,
	Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:47PM -0300, Jason Gunthorpe wrote:
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
>  drivers/of/device.c      | 22 +++++++++++++++-------

Acked-by: Rob Herring <robh@kernel.org>

>  include/linux/of_iommu.h | 13 ++++++-------
>  3 files changed, 39 insertions(+), 25 deletions(-)

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure()
@ 2023-11-08 16:17     ` Rob Herring
  0 siblings, 0 replies; 242+ messages in thread
From: Rob Herring @ 2023-11-08 16:17 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Robin Murphy, Sudeep Holla, Suravee Suthikulpanit,
	Sven Peter, Thierry Reding, Thomas Bogendoerfer, Krishna Reddy,
	Vineet Gupta, virtualization, Wei Liu, Will Deacon,
	Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:47PM -0300, Jason Gunthorpe wrote:
> Nothing needs this pointer. Return a normal error code with the usual
> IOMMU semantic that ENODEV means 'there is no IOMMU driver'.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/of_iommu.c | 29 ++++++++++++++++++-----------
>  drivers/of/device.c      | 22 +++++++++++++++-------

Acked-by: Rob Herring <robh@kernel.org>

>  include/linux/of_iommu.h | 13 ++++++-------
>  3 files changed, 39 insertions(+), 25 deletions(-)

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-08 16:18     ` Rob Herring
  -1 siblings, 0 replies; 242+ messages in thread
From: Rob Herring @ 2023-11-08 16:18 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Robin Murphy, Sudeep Holla, Suravee Suthikulpanit,
	Sven Peter, Thierry Reding, Thomas Bogendoerfer, Krishna Reddy,
	Vineet Gupta, virtualization, Wei Liu, Will Deacon,
	Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:46PM -0300, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  arch/arc/mm/dma.c               |  2 +-
>  arch/arm/mm/dma-mapping-nommu.c |  2 +-
>  arch/arm/mm/dma-mapping.c       | 10 +++++-----
>  arch/arm64/mm/dma-mapping.c     |  4 ++--
>  arch/mips/mm/dma-noncoherent.c  |  2 +-
>  arch/riscv/mm/dma-noncoherent.c |  2 +-
>  drivers/acpi/scan.c             |  3 +--
>  drivers/hv/hv_common.c          |  2 +-
>  drivers/of/device.c             |  2 +-

Acked-by: Rob Herring <robh@kernel.org>

>  include/linux/dma-map-ops.h     |  4 ++--
>  10 files changed, 16 insertions(+), 17 deletions(-)

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-08 16:18     ` Rob Herring
  0 siblings, 0 replies; 242+ messages in thread
From: Rob Herring @ 2023-11-08 16:18 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Robin Murphy, Sudeep Holla, Suravee Suthikulpanit,
	Sven Peter, Thierry Reding, Thomas Bogendoerfer, Krishna Reddy,
	Vineet Gupta, virtualization, Wei Liu, Will Deacon,
	Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:46PM -0300, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  arch/arc/mm/dma.c               |  2 +-
>  arch/arm/mm/dma-mapping-nommu.c |  2 +-
>  arch/arm/mm/dma-mapping.c       | 10 +++++-----
>  arch/arm64/mm/dma-mapping.c     |  4 ++--
>  arch/mips/mm/dma-noncoherent.c  |  2 +-
>  arch/riscv/mm/dma-noncoherent.c |  2 +-
>  drivers/acpi/scan.c             |  3 +--
>  drivers/hv/hv_common.c          |  2 +-
>  drivers/of/device.c             |  2 +-

Acked-by: Rob Herring <robh@kernel.org>

>  include/linux/dma-map-ops.h     |  4 ++--
>  10 files changed, 16 insertions(+), 17 deletions(-)

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-08 16:18     ` Rob Herring
  0 siblings, 0 replies; 242+ messages in thread
From: Rob Herring @ 2023-11-08 16:18 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Robin Murphy, Sudeep Holla, Suravee Suthikulpanit,
	Sven Peter, Thierry Reding, Thomas Bogendoerfer, Krishna Reddy,
	Vineet Gupta, virtualization, Wei Liu, Will Deacon,
	Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:46PM -0300, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  arch/arc/mm/dma.c               |  2 +-
>  arch/arm/mm/dma-mapping-nommu.c |  2 +-
>  arch/arm/mm/dma-mapping.c       | 10 +++++-----
>  arch/arm64/mm/dma-mapping.c     |  4 ++--
>  arch/mips/mm/dma-noncoherent.c  |  2 +-
>  arch/riscv/mm/dma-noncoherent.c |  2 +-
>  drivers/acpi/scan.c             |  3 +--
>  drivers/hv/hv_common.c          |  2 +-
>  drivers/of/device.c             |  2 +-

Acked-by: Rob Herring <robh@kernel.org>

>  include/linux/dma-map-ops.h     |  4 ++--
>  10 files changed, 16 insertions(+), 17 deletions(-)

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-08 16:18     ` Rob Herring
  0 siblings, 0 replies; 242+ messages in thread
From: Rob Herring @ 2023-11-08 16:18 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Robin Murphy, Sudeep Holla, Suravee Suthikulpanit,
	Sven Peter, Thierry Reding, Thomas Bogendoerfer, Krishna Reddy,
	Vineet Gupta, virtualization, Wei Liu, Will Deacon,
	Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:46PM -0300, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  arch/arc/mm/dma.c               |  2 +-
>  arch/arm/mm/dma-mapping-nommu.c |  2 +-
>  arch/arm/mm/dma-mapping.c       | 10 +++++-----
>  arch/arm64/mm/dma-mapping.c     |  4 ++--
>  arch/mips/mm/dma-noncoherent.c  |  2 +-
>  arch/riscv/mm/dma-noncoherent.c |  2 +-
>  drivers/acpi/scan.c             |  3 +--
>  drivers/hv/hv_common.c          |  2 +-
>  drivers/of/device.c             |  2 +-

Acked-by: Rob Herring <robh@kernel.org>

>  include/linux/dma-map-ops.h     |  4 ++--
>  10 files changed, 16 insertions(+), 17 deletions(-)

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 12/17] iommu: Make iommu_ops_from_fwnode() static
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-08 18:12     ` André Draszik
  -1 siblings, 0 replies; 242+ messages in thread
From: André Draszik @ 2023-11-08 18:12 UTC (permalink / raw)
  To: Jason Gunthorpe, acpica-devel, Alyssa Rosenzweig, Albert Ou,
	asahi, Lu Baolu, Catalin Marinas, Dexuan Cui, devicetree,
	David Woodhouse, Frank Rowand, Hanjun Guo, Haiyang Zhang,
	Christoph Hellwig, iommu, Jean-Philippe Brucker, Jonathan Hunter,
	Joerg Roedel, K. Y. Srinivasan, Len Brown, linux-acpi,
	linux-arm-kernel, linux-hyperv, linux-mips, linux-riscv,
	linux-snps-arc, linux-tegra, Russell King, Lorenzo Pieralisi,
	Marek Szyprowski, Hector Martin, Palmer Dabbelt, Paul Walmsley,
	Rafael J. Wysocki, Robert Moore, Rob Herring, Robin Murphy,
	Sudeep Holla, Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Hi Jason,

On Fri, 2023-11-03 at 13:44 -0300, Jason Gunthorpe wrote:
> There are no external callers now.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/iommu.c | 3 ++-
>  include/linux/iommu.h | 6 ------
>  2 files changed, 2 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 62c82a28cd5db3..becd1b881e62dc 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -2945,7 +2945,8 @@ bool iommu_default_passthrough(void)
>  }
>  EXPORT_SYMBOL_GPL(iommu_default_passthrough);
>  
> -const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle
> *fwnode)
> +static const struct iommu_ops *
> +iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
>  {
>         const struct iommu_ops *ops = NULL;
>         struct iommu_device *iommu;
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 27e4605d498850..37948eee8d7394 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -701,7 +701,6 @@ static inline void iommu_fwspec_free(struct
> device *dev)
>         dev->iommu->fwspec = NULL;
>  }
>  int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
> -const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle
> *fwnode);
>  int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids,
> int num_ids);
>  
>  static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct
> device *dev)
> @@ -1044,11 +1043,6 @@ static inline int iommu_fwspec_add_ids(struct
> device *dev, u32 *ids,
>  }
>  
>  static inline
> -const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle
> *fwnode)
> -{
> -       return NULL;
> -}
> -
>  static inline int
>  iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features
> feat)

This leaves the extra line with 'static inline', it should also be
removed.

Cheers,
Andre'


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 12/17] iommu: Make iommu_ops_from_fwnode() static
@ 2023-11-08 18:12     ` André Draszik
  0 siblings, 0 replies; 242+ messages in thread
From: André Draszik @ 2023-11-08 18:12 UTC (permalink / raw)
  To: Jason Gunthorpe, acpica-devel, Alyssa Rosenzweig, Albert Ou,
	asahi, Lu Baolu, Catalin Marinas, Dexuan Cui, devicetree,
	David Woodhouse, Frank Rowand, Hanjun Guo, Haiyang Zhang,
	Christoph Hellwig, iommu, Jean-Philippe Brucker, Jonathan Hunter,
	Joerg Roedel, K. Y. Srinivasan, Len Brown, linux-acpi,
	linux-arm-kernel, linux-hyperv, linux-mips, linux-riscv,
	linux-snps-arc, linux-tegra, Russell King, Lorenzo Pieralisi,
	Marek Szyprowski, Hector Martin, Palmer Dabbelt, Paul Walmsley,
	Rafael J. Wysocki, Robert Moore, Rob Herring, Robin Murphy,
	Sudeep Holla, Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Hi Jason,

On Fri, 2023-11-03 at 13:44 -0300, Jason Gunthorpe wrote:
> There are no external callers now.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/iommu.c | 3 ++-
>  include/linux/iommu.h | 6 ------
>  2 files changed, 2 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 62c82a28cd5db3..becd1b881e62dc 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -2945,7 +2945,8 @@ bool iommu_default_passthrough(void)
>  }
>  EXPORT_SYMBOL_GPL(iommu_default_passthrough);
>  
> -const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle
> *fwnode)
> +static const struct iommu_ops *
> +iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
>  {
>         const struct iommu_ops *ops = NULL;
>         struct iommu_device *iommu;
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 27e4605d498850..37948eee8d7394 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -701,7 +701,6 @@ static inline void iommu_fwspec_free(struct
> device *dev)
>         dev->iommu->fwspec = NULL;
>  }
>  int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
> -const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle
> *fwnode);
>  int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids,
> int num_ids);
>  
>  static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct
> device *dev)
> @@ -1044,11 +1043,6 @@ static inline int iommu_fwspec_add_ids(struct
> device *dev, u32 *ids,
>  }
>  
>  static inline
> -const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle
> *fwnode)
> -{
> -       return NULL;
> -}
> -
>  static inline int
>  iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features
> feat)

This leaves the extra line with 'static inline', it should also be
removed.

Cheers,
Andre'


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 12/17] iommu: Make iommu_ops_from_fwnode() static
@ 2023-11-08 18:12     ` André Draszik
  0 siblings, 0 replies; 242+ messages in thread
From: André Draszik @ 2023-11-08 18:12 UTC (permalink / raw)
  To: Jason Gunthorpe, acpica-devel, Alyssa Rosenzweig, Albert Ou,
	asahi, Lu Baolu, Catalin Marinas, Dexuan Cui, devicetree,
	David Woodhouse, Frank Rowand, Hanjun Guo, Haiyang Zhang,
	Christoph Hellwig, iommu, Jean-Philippe Brucker, Jonathan Hunter,
	Joerg Roedel, K. Y. Srinivasan, Len Brown, linux-acpi,
	linux-arm-kernel, linux-hyperv, linux-mips, linux-riscv,
	linux-snps-arc, linux-tegra, Russell King, Lorenzo Pieralisi,
	Marek Szyprowski, Hector Martin, Palmer Dabbelt, Paul Walmsley,
	Rafael J. Wysocki, Robert Moore, Rob Herring, Robin Murphy,
	Sudeep Holla, Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Hi Jason,

On Fri, 2023-11-03 at 13:44 -0300, Jason Gunthorpe wrote:
> There are no external callers now.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/iommu.c | 3 ++-
>  include/linux/iommu.h | 6 ------
>  2 files changed, 2 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 62c82a28cd5db3..becd1b881e62dc 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -2945,7 +2945,8 @@ bool iommu_default_passthrough(void)
>  }
>  EXPORT_SYMBOL_GPL(iommu_default_passthrough);
>  
> -const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle
> *fwnode)
> +static const struct iommu_ops *
> +iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
>  {
>         const struct iommu_ops *ops = NULL;
>         struct iommu_device *iommu;
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 27e4605d498850..37948eee8d7394 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -701,7 +701,6 @@ static inline void iommu_fwspec_free(struct
> device *dev)
>         dev->iommu->fwspec = NULL;
>  }
>  int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
> -const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle
> *fwnode);
>  int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids,
> int num_ids);
>  
>  static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct
> device *dev)
> @@ -1044,11 +1043,6 @@ static inline int iommu_fwspec_add_ids(struct
> device *dev, u32 *ids,
>  }
>  
>  static inline
> -const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle
> *fwnode)
> -{
> -       return NULL;
> -}
> -
>  static inline int
>  iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features
> feat)

This leaves the extra line with 'static inline', it should also be
removed.

Cheers,
Andre'


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 12/17] iommu: Make iommu_ops_from_fwnode() static
@ 2023-11-08 18:12     ` André Draszik
  0 siblings, 0 replies; 242+ messages in thread
From: André Draszik @ 2023-11-08 18:12 UTC (permalink / raw)
  To: Jason Gunthorpe, acpica-devel, Alyssa Rosenzweig, Albert Ou,
	asahi, Lu Baolu, Catalin Marinas, Dexuan Cui, devicetree,
	David Woodhouse, Frank Rowand, Hanjun Guo, Haiyang Zhang,
	Christoph Hellwig, iommu, Jean-Philippe Brucker, Jonathan Hunter,
	Joerg Roedel, K. Y. Srinivasan, Len Brown, linux-acpi,
	linux-arm-kernel, linux-hyperv, linux-mips, linux-riscv,
	linux-snps-arc, linux-tegra, Russell King, Lorenzo Pieralisi,
	Marek Szyprowski, Hector Martin, Palmer Dabbelt, Paul Walmsley,
	Rafael J. Wysocki, Robert Moore, Rob Herring, Robin Murphy,
	Sudeep Holla, Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon
  Cc: Zhenhua Huang

Hi Jason,

On Fri, 2023-11-03 at 13:44 -0300, Jason Gunthorpe wrote:
> There are no external callers now.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  drivers/iommu/iommu.c | 3 ++-
>  include/linux/iommu.h | 6 ------
>  2 files changed, 2 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 62c82a28cd5db3..becd1b881e62dc 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -2945,7 +2945,8 @@ bool iommu_default_passthrough(void)
>  }
>  EXPORT_SYMBOL_GPL(iommu_default_passthrough);
>  
> -const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle
> *fwnode)
> +static const struct iommu_ops *
> +iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
>  {
>         const struct iommu_ops *ops = NULL;
>         struct iommu_device *iommu;
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 27e4605d498850..37948eee8d7394 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -701,7 +701,6 @@ static inline void iommu_fwspec_free(struct
> device *dev)
>         dev->iommu->fwspec = NULL;
>  }
>  int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
> -const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle
> *fwnode);
>  int iommu_fwspec_append_ids(struct iommu_fwspec *fwspec, u32 *ids,
> int num_ids);
>  
>  static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct
> device *dev)
> @@ -1044,11 +1043,6 @@ static inline int iommu_fwspec_add_ids(struct
> device *dev, u32 *ids,
>  }
>  
>  static inline
> -const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle
> *fwnode)
> -{
> -       return NULL;
> -}
> -
>  static inline int
>  iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features
> feat)

This leaves the extra line with 'static inline', it should also be
removed.

Cheers,
Andre'


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
  2023-11-03 16:44 ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-08 18:34   ` André Draszik
  -1 siblings, 0 replies; 242+ messages in thread
From: André Draszik @ 2023-11-08 18:34 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Zhenhua Huang, acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi,
	Lu Baolu, Catalin Marinas, Dexuan Cui, devicetree,
	David Woodhouse, Frank Rowand, Hanjun Guo, Haiyang Zhang,
	Christoph Hellwig, iommu, Jean-Philippe Brucker, Jonathan Hunter,
	Joerg Roedel, K. Y. Srinivasan, Len Brown, linux-acpi,
	linux-arm-kernel, linux-hyperv, linux-mips, linux-riscv,
	linux-snps-arc, linux-tegra, Russell King, Lorenzo Pieralisi,
	Marek Szyprowski, Hector Martin, Palmer Dabbelt, Paul Walmsley,
	Rafael J. Wysocki, Robert Moore, Rob Herring, Robin Murphy,
	Sudeep Holla, Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon

Hi Jason,

On Fri, 2023-11-03 at 13:44 -0300, Jason Gunthorpe wrote:
> This is a more complete solution that the first attempt here:
> https://lore.kernel.org/r/1698825902-10685-1-git-send-email-quic_zhenhuah@quicinc.com
> 
> I haven't been able to test this on any HW that touches these paths, so if
> some people with HW can help get it in shape it can become non-RFC.

Thank you for this series.

Please note that we're also observing this issue on 6.1.
I think this series is a good candidate for a back port (slightly complicated by
the fact that various refactors have happened since).

For me, it's working fine so far on master, and I've also done my own back port
to 6.1 and am currently testing both. An official back port once finalised
could be useful, though :-)


Cheers,
Andre'


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
@ 2023-11-08 18:34   ` André Draszik
  0 siblings, 0 replies; 242+ messages in thread
From: André Draszik @ 2023-11-08 18:34 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Zhenhua Huang, acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi,
	Lu Baolu, Catalin Marinas, Dexuan Cui, devicetree,
	David Woodhouse, Frank Rowand, Hanjun Guo, Haiyang Zhang,
	Christoph Hellwig, iommu, Jean-Philippe Brucker, Jonathan Hunter,
	Joerg Roedel, K. Y. Srinivasan, Len Brown, linux-acpi,
	linux-arm-kernel, linux-hyperv, linux-mips, linux-riscv,
	linux-snps-arc, linux-tegra, Russell King, Lorenzo Pieralisi,
	Marek Szyprowski, Hector Martin, Palmer Dabbelt, Paul Walmsley,
	Rafael J. Wysocki, Robert Moore, Rob Herring, Robin Murphy,
	Sudeep Holla, Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon

Hi Jason,

On Fri, 2023-11-03 at 13:44 -0300, Jason Gunthorpe wrote:
> This is a more complete solution that the first attempt here:
> https://lore.kernel.org/r/1698825902-10685-1-git-send-email-quic_zhenhuah@quicinc.com
> 
> I haven't been able to test this on any HW that touches these paths, so if
> some people with HW can help get it in shape it can become non-RFC.

Thank you for this series.

Please note that we're also observing this issue on 6.1.
I think this series is a good candidate for a back port (slightly complicated by
the fact that various refactors have happened since).

For me, it's working fine so far on master, and I've also done my own back port
to 6.1 and am currently testing both. An official back port once finalised
could be useful, though :-)


Cheers,
Andre'


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
@ 2023-11-08 18:34   ` André Draszik
  0 siblings, 0 replies; 242+ messages in thread
From: André Draszik @ 2023-11-08 18:34 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Zhenhua Huang, acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi,
	Lu Baolu, Catalin Marinas, Dexuan Cui, devicetree,
	David Woodhouse, Frank Rowand, Hanjun Guo, Haiyang Zhang,
	Christoph Hellwig, iommu, Jean-Philippe Brucker, Jonathan Hunter,
	Joerg Roedel, K. Y. Srinivasan, Len Brown, linux-acpi,
	linux-arm-kernel, linux-hyperv, linux-mips, linux-riscv,
	linux-snps-arc, linux-tegra, Russell King, Lorenzo Pieralisi,
	Marek Szyprowski, Hector Martin, Palmer Dabbelt, Paul Walmsley,
	Rafael J. Wysocki, Robert Moore, Rob Herring, Robin Murphy,
	Sudeep Holla, Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon

Hi Jason,

On Fri, 2023-11-03 at 13:44 -0300, Jason Gunthorpe wrote:
> This is a more complete solution that the first attempt here:
> https://lore.kernel.org/r/1698825902-10685-1-git-send-email-quic_zhenhuah@quicinc.com
> 
> I haven't been able to test this on any HW that touches these paths, so if
> some people with HW can help get it in shape it can become non-RFC.

Thank you for this series.

Please note that we're also observing this issue on 6.1.
I think this series is a good candidate for a back port (slightly complicated by
the fact that various refactors have happened since).

For me, it's working fine so far on master, and I've also done my own back port
to 6.1 and am currently testing both. An official back port once finalised
could be useful, though :-)


Cheers,
Andre'


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
@ 2023-11-08 18:34   ` André Draszik
  0 siblings, 0 replies; 242+ messages in thread
From: André Draszik @ 2023-11-08 18:34 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Zhenhua Huang, acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi,
	Lu Baolu, Catalin Marinas, Dexuan Cui, devicetree,
	David Woodhouse, Frank Rowand, Hanjun Guo, Haiyang Zhang,
	Christoph Hellwig, iommu, Jean-Philippe Brucker, Jonathan Hunter,
	Joerg Roedel, K. Y. Srinivasan, Len Brown, linux-acpi,
	linux-arm-kernel, linux-hyperv, linux-mips, linux-riscv,
	linux-snps-arc, linux-tegra, Russell King, Lorenzo Pieralisi,
	Marek Szyprowski, Hector Martin, Palmer Dabbelt, Paul Walmsley,
	Rafael J. Wysocki, Robert Moore, Rob Herring, Robin Murphy,
	Sudeep Holla, Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon

Hi Jason,

On Fri, 2023-11-03 at 13:44 -0300, Jason Gunthorpe wrote:
> This is a more complete solution that the first attempt here:
> https://lore.kernel.org/r/1698825902-10685-1-git-send-email-quic_zhenhuah@quicinc.com
> 
> I haven't been able to test this on any HW that touches these paths, so if
> some people with HW can help get it in shape it can become non-RFC.

Thank you for this series.

Please note that we're also observing this issue on 6.1.
I think this series is a good candidate for a back port (slightly complicated by
the fact that various refactors have happened since).

For me, it's working fine so far on master, and I've also done my own back port
to 6.1 and am currently testing both. An official back port once finalised
could be useful, though :-)


Cheers,
Andre'


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
  2023-11-08 18:34   ` André Draszik
  (?)
  (?)
@ 2023-11-08 19:22     ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-08 19:22 UTC (permalink / raw)
  To: André Draszik
  Cc: Zhenhua Huang, acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi,
	Lu Baolu, Catalin Marinas, Dexuan Cui, devicetree,
	David Woodhouse, Frank Rowand, Hanjun Guo, Haiyang Zhang,
	Christoph Hellwig, iommu, Jean-Philippe Brucker, Jonathan Hunter,
	Joerg Roedel, K. Y. Srinivasan, Len Brown, linux-acpi,
	linux-arm-kernel, linux-hyperv, linux-mips, linux-riscv,
	linux-snps-arc, linux-tegra, Russell King, Lorenzo Pieralisi,
	Marek Szyprowski, Hector Martin, Palmer Dabbelt, Paul Walmsley,
	Rafael J. Wysocki, Robert Moore, Rob Herring, Robin Murphy,
	Sudeep Holla, Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon

On Wed, Nov 08, 2023 at 06:34:58PM +0000, André Draszik wrote:

> For me, it's working fine so far on master, and I've also done my own back port
> to 6.1 and am currently testing both. An official back port once finalised
> could be useful, though :-)

Great, I'll post a non-RFC version next week (LPC permitting)

BTW, kbuild 0-day caught your note in the other email and a bunch of
other wonky stuff I've fixed on the github version.

Thanks,
Jason

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
@ 2023-11-08 19:22     ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-08 19:22 UTC (permalink / raw)
  To: André Draszik
  Cc: Zhenhua Huang, acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi,
	Lu Baolu, Catalin Marinas, Dexuan Cui, devicetree,
	David Woodhouse, Frank Rowand, Hanjun Guo, Haiyang Zhang,
	Christoph Hellwig, iommu, Jean-Philippe Brucker, Jonathan Hunter,
	Joerg Roedel, K. Y. Srinivasan, Len Brown, linux-acpi,
	linux-arm-kernel, linux-hyperv, linux-mips, linux-riscv,
	linux-snps-arc, linux-tegra, Russell King, Lorenzo Pieralisi,
	Marek Szyprowski, Hector Martin, Palmer Dabbelt, Paul Walmsley,
	Rafael J. Wysocki, Robert Moore, Rob Herring, Robin Murphy,
	Sudeep Holla, Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon

On Wed, Nov 08, 2023 at 06:34:58PM +0000, André Draszik wrote:

> For me, it's working fine so far on master, and I've also done my own back port
> to 6.1 and am currently testing both. An official back port once finalised
> could be useful, though :-)

Great, I'll post a non-RFC version next week (LPC permitting)

BTW, kbuild 0-day caught your note in the other email and a bunch of
other wonky stuff I've fixed on the github version.

Thanks,
Jason

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
@ 2023-11-08 19:22     ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-08 19:22 UTC (permalink / raw)
  To: André Draszik
  Cc: Zhenhua Huang, acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi,
	Lu Baolu, Catalin Marinas, Dexuan Cui, devicetree,
	David Woodhouse, Frank Rowand, Hanjun Guo, Haiyang Zhang,
	Christoph Hellwig, iommu, Jean-Philippe Brucker, Jonathan Hunter,
	Joerg Roedel, K. Y. Srinivasan, Len Brown, linux-acpi,
	linux-arm-kernel, linux-hyperv, linux-mips, linux-riscv,
	linux-snps-arc, linux-tegra, Russell King, Lorenzo Pieralisi,
	Marek Szyprowski, Hector Martin, Palmer Dabbelt, Paul Walmsley,
	Rafael J. Wysocki, Robert Moore, Rob Herring, Robin Murphy,
	Sudeep Holla, Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon

On Wed, Nov 08, 2023 at 06:34:58PM +0000, André Draszik wrote:

> For me, it's working fine so far on master, and I've also done my own back port
> to 6.1 and am currently testing both. An official back port once finalised
> could be useful, though :-)

Great, I'll post a non-RFC version next week (LPC permitting)

BTW, kbuild 0-day caught your note in the other email and a bunch of
other wonky stuff I've fixed on the github version.

Thanks,
Jason

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
@ 2023-11-08 19:22     ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-08 19:22 UTC (permalink / raw)
  To: André Draszik
  Cc: Zhenhua Huang, acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi,
	Lu Baolu, Catalin Marinas, Dexuan Cui, devicetree,
	David Woodhouse, Frank Rowand, Hanjun Guo, Haiyang Zhang,
	Christoph Hellwig, iommu, Jean-Philippe Brucker, Jonathan Hunter,
	Joerg Roedel, K. Y. Srinivasan, Len Brown, linux-acpi,
	linux-arm-kernel, linux-hyperv, linux-mips, linux-riscv,
	linux-snps-arc, linux-tegra, Russell King, Lorenzo Pieralisi,
	Marek Szyprowski, Hector Martin, Palmer Dabbelt, Paul Walmsley,
	Rafael J. Wysocki, Robert Moore, Rob Herring, Robin Murphy,
	Sudeep Holla, Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon

On Wed, Nov 08, 2023 at 06:34:58PM +0000, André Draszik wrote:

> For me, it's working fine so far on master, and I've also done my own back port
> to 6.1 and am currently testing both. An official back port once finalised
> could be useful, though :-)

Great, I'll post a non-RFC version next week (LPC permitting)

BTW, kbuild 0-day caught your note in the other email and a bunch of
other wonky stuff I've fixed on the github version.

Thanks,
Jason

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-12 17:35     ` Moritz Fischer
  -1 siblings, 0 replies; 242+ messages in thread
From: Moritz Fischer @ 2023-11-12 17:35 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:46PM -0300, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Reviewed-by: Moritz Fischer <mdf@kernel.org>
> ---
>  arch/arc/mm/dma.c               |  2 +-
>  arch/arm/mm/dma-mapping-nommu.c |  2 +-
>  arch/arm/mm/dma-mapping.c       | 10 +++++-----
>  arch/arm64/mm/dma-mapping.c     |  4 ++--
>  arch/mips/mm/dma-noncoherent.c  |  2 +-
>  arch/riscv/mm/dma-noncoherent.c |  2 +-
>  drivers/acpi/scan.c             |  3 +--
>  drivers/hv/hv_common.c          |  2 +-
>  drivers/of/device.c             |  2 +-
>  include/linux/dma-map-ops.h     |  4 ++--
>  10 files changed, 16 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
> index 2a7fbbb83b7056..197707bc765889 100644
> --- a/arch/arc/mm/dma.c
> +++ b/arch/arc/mm/dma.c
> @@ -91,7 +91,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
>   * Plug in direct dma map ops.
>   */
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	/*
>  	 * IOC hardware snoops all DMA traffic keeping the caches consistent
> diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
> index cfd9c933d2f09c..b94850b579952a 100644
> --- a/arch/arm/mm/dma-mapping-nommu.c
> +++ b/arch/arm/mm/dma-mapping-nommu.c
> @@ -34,7 +34,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
>  }
>  
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	if (IS_ENABLED(CONFIG_CPU_V7M)) {
>  		/*
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index 5409225b4abc06..6c359a3af8d9c7 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -1713,7 +1713,7 @@ void arm_iommu_detach_device(struct device *dev)
>  EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
>  
>  static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -				    const struct iommu_ops *iommu, bool coherent)
> +				    bool coherent)
>  {
>  	struct dma_iommu_mapping *mapping;
>  
> @@ -1748,7 +1748,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
>  #else
>  
>  static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -				    const struct iommu_ops *iommu, bool coherent)
> +				    bool coherent)
>  {
>  }
>  
> @@ -1757,7 +1757,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }
>  #endif	/* CONFIG_ARM_DMA_USE_IOMMU */
>  
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	/*
>  	 * Due to legacy code that sets the ->dma_coherent flag from a bus
> @@ -1776,8 +1776,8 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
>  	if (dev->dma_ops)
>  		return;
>  
> -	if (iommu)
> -		arm_setup_iommu_dma_ops(dev, dma_base, size, iommu, coherent);
> +	if (device_iommu_mapped(dev))
> +		arm_setup_iommu_dma_ops(dev, dma_base, size, coherent);
>  
>  	xen_setup_dma_ops(dev);
>  	dev->archdata.dma_ops_setup = true;
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index 3cb101e8cb29ba..61886e43e3a10f 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -47,7 +47,7 @@ void arch_teardown_dma_ops(struct device *dev)
>  #endif
>  
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	int cls = cache_line_size_of_cpu();
>  
> @@ -58,7 +58,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
>  		   ARCH_DMA_MINALIGN, cls);
>  
>  	dev->dma_coherent = coherent;
> -	if (iommu)
> +	if (device_iommu_mapped(dev))
>  		iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1);
>  
>  	xen_setup_dma_ops(dev);
> diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
> index 3c4fc97b9f394b..0f3cec663a12cd 100644
> --- a/arch/mips/mm/dma-noncoherent.c
> +++ b/arch/mips/mm/dma-noncoherent.c
> @@ -138,7 +138,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
>  
>  #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -		const struct iommu_ops *iommu, bool coherent)
> +		bool coherent)
>  {
>  	dev->dma_coherent = coherent;
>  }
> diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
> index b76e7e192eb183..f91fa741c41211 100644
> --- a/arch/riscv/mm/dma-noncoherent.c
> +++ b/arch/riscv/mm/dma-noncoherent.c
> @@ -135,7 +135,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
>  }
>  
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -		const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	WARN_TAINT(!coherent && riscv_cbom_block_size > ARCH_DMA_MINALIGN,
>  		   TAINT_CPU_OUT_OF_SPEC,
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index 691d4b7686ee7e..a6891ad0ceee2c 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1636,8 +1636,7 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>  	if (PTR_ERR(iommu) == -EPROBE_DEFER)
>  		return -EPROBE_DEFER;
>  
> -	arch_setup_dma_ops(dev, 0, U64_MAX,
> -				iommu, attr == DEV_DMA_COHERENT);
> +	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
>  
>  	return 0;
>  }
> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> index ccad7bca3fd3da..fd938b6dfa7ed4 100644
> --- a/drivers/hv/hv_common.c
> +++ b/drivers/hv/hv_common.c
> @@ -489,7 +489,7 @@ void hv_setup_dma_ops(struct device *dev, bool coherent)
>  	 * Hyper-V does not offer a vIOMMU in the guest
>  	 * VM, so pass 0/NULL for the IOMMU settings
>  	 */
> -	arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
> +	arch_setup_dma_ops(dev, 0, 0, coherent);
>  }
>  EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
>  
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index 1ca42ad9dd159d..65c71be71a8d45 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -193,7 +193,7 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
>  	dev_dbg(dev, "device is%sbehind an iommu\n",
>  		iommu ? " " : " not ");
>  
> -	arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
> +	arch_setup_dma_ops(dev, dma_start, size, coherent);
>  
>  	if (!iommu)
>  		of_dma_set_restricted_buffer(dev, np);
> diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
> index f2fc203fb8a1a2..2cb98a12c50348 100644
> --- a/include/linux/dma-map-ops.h
> +++ b/include/linux/dma-map-ops.h
> @@ -426,10 +426,10 @@ bool arch_dma_unmap_sg_direct(struct device *dev, struct scatterlist *sg,
>  
>  #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -		const struct iommu_ops *iommu, bool coherent);
> +		bool coherent);
>  #else
>  static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
> -		u64 size, const struct iommu_ops *iommu, bool coherent)
> +		u64 size, bool coherent)
>  {
>  }
>  #endif /* CONFIG_ARCH_HAS_SETUP_DMA_OPS */
> -- 
> 2.42.0
> 

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-12 17:35     ` Moritz Fischer
  0 siblings, 0 replies; 242+ messages in thread
From: Moritz Fischer @ 2023-11-12 17:35 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:46PM -0300, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Reviewed-by: Moritz Fischer <mdf@kernel.org>
> ---
>  arch/arc/mm/dma.c               |  2 +-
>  arch/arm/mm/dma-mapping-nommu.c |  2 +-
>  arch/arm/mm/dma-mapping.c       | 10 +++++-----
>  arch/arm64/mm/dma-mapping.c     |  4 ++--
>  arch/mips/mm/dma-noncoherent.c  |  2 +-
>  arch/riscv/mm/dma-noncoherent.c |  2 +-
>  drivers/acpi/scan.c             |  3 +--
>  drivers/hv/hv_common.c          |  2 +-
>  drivers/of/device.c             |  2 +-
>  include/linux/dma-map-ops.h     |  4 ++--
>  10 files changed, 16 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
> index 2a7fbbb83b7056..197707bc765889 100644
> --- a/arch/arc/mm/dma.c
> +++ b/arch/arc/mm/dma.c
> @@ -91,7 +91,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
>   * Plug in direct dma map ops.
>   */
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	/*
>  	 * IOC hardware snoops all DMA traffic keeping the caches consistent
> diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
> index cfd9c933d2f09c..b94850b579952a 100644
> --- a/arch/arm/mm/dma-mapping-nommu.c
> +++ b/arch/arm/mm/dma-mapping-nommu.c
> @@ -34,7 +34,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
>  }
>  
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	if (IS_ENABLED(CONFIG_CPU_V7M)) {
>  		/*
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index 5409225b4abc06..6c359a3af8d9c7 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -1713,7 +1713,7 @@ void arm_iommu_detach_device(struct device *dev)
>  EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
>  
>  static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -				    const struct iommu_ops *iommu, bool coherent)
> +				    bool coherent)
>  {
>  	struct dma_iommu_mapping *mapping;
>  
> @@ -1748,7 +1748,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
>  #else
>  
>  static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -				    const struct iommu_ops *iommu, bool coherent)
> +				    bool coherent)
>  {
>  }
>  
> @@ -1757,7 +1757,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }
>  #endif	/* CONFIG_ARM_DMA_USE_IOMMU */
>  
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	/*
>  	 * Due to legacy code that sets the ->dma_coherent flag from a bus
> @@ -1776,8 +1776,8 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
>  	if (dev->dma_ops)
>  		return;
>  
> -	if (iommu)
> -		arm_setup_iommu_dma_ops(dev, dma_base, size, iommu, coherent);
> +	if (device_iommu_mapped(dev))
> +		arm_setup_iommu_dma_ops(dev, dma_base, size, coherent);
>  
>  	xen_setup_dma_ops(dev);
>  	dev->archdata.dma_ops_setup = true;
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index 3cb101e8cb29ba..61886e43e3a10f 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -47,7 +47,7 @@ void arch_teardown_dma_ops(struct device *dev)
>  #endif
>  
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	int cls = cache_line_size_of_cpu();
>  
> @@ -58,7 +58,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
>  		   ARCH_DMA_MINALIGN, cls);
>  
>  	dev->dma_coherent = coherent;
> -	if (iommu)
> +	if (device_iommu_mapped(dev))
>  		iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1);
>  
>  	xen_setup_dma_ops(dev);
> diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
> index 3c4fc97b9f394b..0f3cec663a12cd 100644
> --- a/arch/mips/mm/dma-noncoherent.c
> +++ b/arch/mips/mm/dma-noncoherent.c
> @@ -138,7 +138,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
>  
>  #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -		const struct iommu_ops *iommu, bool coherent)
> +		bool coherent)
>  {
>  	dev->dma_coherent = coherent;
>  }
> diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
> index b76e7e192eb183..f91fa741c41211 100644
> --- a/arch/riscv/mm/dma-noncoherent.c
> +++ b/arch/riscv/mm/dma-noncoherent.c
> @@ -135,7 +135,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
>  }
>  
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -		const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	WARN_TAINT(!coherent && riscv_cbom_block_size > ARCH_DMA_MINALIGN,
>  		   TAINT_CPU_OUT_OF_SPEC,
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index 691d4b7686ee7e..a6891ad0ceee2c 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1636,8 +1636,7 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>  	if (PTR_ERR(iommu) == -EPROBE_DEFER)
>  		return -EPROBE_DEFER;
>  
> -	arch_setup_dma_ops(dev, 0, U64_MAX,
> -				iommu, attr == DEV_DMA_COHERENT);
> +	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
>  
>  	return 0;
>  }
> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> index ccad7bca3fd3da..fd938b6dfa7ed4 100644
> --- a/drivers/hv/hv_common.c
> +++ b/drivers/hv/hv_common.c
> @@ -489,7 +489,7 @@ void hv_setup_dma_ops(struct device *dev, bool coherent)
>  	 * Hyper-V does not offer a vIOMMU in the guest
>  	 * VM, so pass 0/NULL for the IOMMU settings
>  	 */
> -	arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
> +	arch_setup_dma_ops(dev, 0, 0, coherent);
>  }
>  EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
>  
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index 1ca42ad9dd159d..65c71be71a8d45 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -193,7 +193,7 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
>  	dev_dbg(dev, "device is%sbehind an iommu\n",
>  		iommu ? " " : " not ");
>  
> -	arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
> +	arch_setup_dma_ops(dev, dma_start, size, coherent);
>  
>  	if (!iommu)
>  		of_dma_set_restricted_buffer(dev, np);
> diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
> index f2fc203fb8a1a2..2cb98a12c50348 100644
> --- a/include/linux/dma-map-ops.h
> +++ b/include/linux/dma-map-ops.h
> @@ -426,10 +426,10 @@ bool arch_dma_unmap_sg_direct(struct device *dev, struct scatterlist *sg,
>  
>  #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -		const struct iommu_ops *iommu, bool coherent);
> +		bool coherent);
>  #else
>  static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
> -		u64 size, const struct iommu_ops *iommu, bool coherent)
> +		u64 size, bool coherent)
>  {
>  }
>  #endif /* CONFIG_ARCH_HAS_SETUP_DMA_OPS */
> -- 
> 2.42.0
> 

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-12 17:35     ` Moritz Fischer
  0 siblings, 0 replies; 242+ messages in thread
From: Moritz Fischer @ 2023-11-12 17:35 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:46PM -0300, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Reviewed-by: Moritz Fischer <mdf@kernel.org>
> ---
>  arch/arc/mm/dma.c               |  2 +-
>  arch/arm/mm/dma-mapping-nommu.c |  2 +-
>  arch/arm/mm/dma-mapping.c       | 10 +++++-----
>  arch/arm64/mm/dma-mapping.c     |  4 ++--
>  arch/mips/mm/dma-noncoherent.c  |  2 +-
>  arch/riscv/mm/dma-noncoherent.c |  2 +-
>  drivers/acpi/scan.c             |  3 +--
>  drivers/hv/hv_common.c          |  2 +-
>  drivers/of/device.c             |  2 +-
>  include/linux/dma-map-ops.h     |  4 ++--
>  10 files changed, 16 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
> index 2a7fbbb83b7056..197707bc765889 100644
> --- a/arch/arc/mm/dma.c
> +++ b/arch/arc/mm/dma.c
> @@ -91,7 +91,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
>   * Plug in direct dma map ops.
>   */
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	/*
>  	 * IOC hardware snoops all DMA traffic keeping the caches consistent
> diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
> index cfd9c933d2f09c..b94850b579952a 100644
> --- a/arch/arm/mm/dma-mapping-nommu.c
> +++ b/arch/arm/mm/dma-mapping-nommu.c
> @@ -34,7 +34,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
>  }
>  
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	if (IS_ENABLED(CONFIG_CPU_V7M)) {
>  		/*
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index 5409225b4abc06..6c359a3af8d9c7 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -1713,7 +1713,7 @@ void arm_iommu_detach_device(struct device *dev)
>  EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
>  
>  static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -				    const struct iommu_ops *iommu, bool coherent)
> +				    bool coherent)
>  {
>  	struct dma_iommu_mapping *mapping;
>  
> @@ -1748,7 +1748,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
>  #else
>  
>  static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -				    const struct iommu_ops *iommu, bool coherent)
> +				    bool coherent)
>  {
>  }
>  
> @@ -1757,7 +1757,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }
>  #endif	/* CONFIG_ARM_DMA_USE_IOMMU */
>  
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	/*
>  	 * Due to legacy code that sets the ->dma_coherent flag from a bus
> @@ -1776,8 +1776,8 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
>  	if (dev->dma_ops)
>  		return;
>  
> -	if (iommu)
> -		arm_setup_iommu_dma_ops(dev, dma_base, size, iommu, coherent);
> +	if (device_iommu_mapped(dev))
> +		arm_setup_iommu_dma_ops(dev, dma_base, size, coherent);
>  
>  	xen_setup_dma_ops(dev);
>  	dev->archdata.dma_ops_setup = true;
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index 3cb101e8cb29ba..61886e43e3a10f 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -47,7 +47,7 @@ void arch_teardown_dma_ops(struct device *dev)
>  #endif
>  
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	int cls = cache_line_size_of_cpu();
>  
> @@ -58,7 +58,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
>  		   ARCH_DMA_MINALIGN, cls);
>  
>  	dev->dma_coherent = coherent;
> -	if (iommu)
> +	if (device_iommu_mapped(dev))
>  		iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1);
>  
>  	xen_setup_dma_ops(dev);
> diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
> index 3c4fc97b9f394b..0f3cec663a12cd 100644
> --- a/arch/mips/mm/dma-noncoherent.c
> +++ b/arch/mips/mm/dma-noncoherent.c
> @@ -138,7 +138,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
>  
>  #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -		const struct iommu_ops *iommu, bool coherent)
> +		bool coherent)
>  {
>  	dev->dma_coherent = coherent;
>  }
> diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
> index b76e7e192eb183..f91fa741c41211 100644
> --- a/arch/riscv/mm/dma-noncoherent.c
> +++ b/arch/riscv/mm/dma-noncoherent.c
> @@ -135,7 +135,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
>  }
>  
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -		const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	WARN_TAINT(!coherent && riscv_cbom_block_size > ARCH_DMA_MINALIGN,
>  		   TAINT_CPU_OUT_OF_SPEC,
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index 691d4b7686ee7e..a6891ad0ceee2c 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1636,8 +1636,7 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>  	if (PTR_ERR(iommu) == -EPROBE_DEFER)
>  		return -EPROBE_DEFER;
>  
> -	arch_setup_dma_ops(dev, 0, U64_MAX,
> -				iommu, attr == DEV_DMA_COHERENT);
> +	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
>  
>  	return 0;
>  }
> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> index ccad7bca3fd3da..fd938b6dfa7ed4 100644
> --- a/drivers/hv/hv_common.c
> +++ b/drivers/hv/hv_common.c
> @@ -489,7 +489,7 @@ void hv_setup_dma_ops(struct device *dev, bool coherent)
>  	 * Hyper-V does not offer a vIOMMU in the guest
>  	 * VM, so pass 0/NULL for the IOMMU settings
>  	 */
> -	arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
> +	arch_setup_dma_ops(dev, 0, 0, coherent);
>  }
>  EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
>  
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index 1ca42ad9dd159d..65c71be71a8d45 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -193,7 +193,7 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
>  	dev_dbg(dev, "device is%sbehind an iommu\n",
>  		iommu ? " " : " not ");
>  
> -	arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
> +	arch_setup_dma_ops(dev, dma_start, size, coherent);
>  
>  	if (!iommu)
>  		of_dma_set_restricted_buffer(dev, np);
> diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
> index f2fc203fb8a1a2..2cb98a12c50348 100644
> --- a/include/linux/dma-map-ops.h
> +++ b/include/linux/dma-map-ops.h
> @@ -426,10 +426,10 @@ bool arch_dma_unmap_sg_direct(struct device *dev, struct scatterlist *sg,
>  
>  #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -		const struct iommu_ops *iommu, bool coherent);
> +		bool coherent);
>  #else
>  static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
> -		u64 size, const struct iommu_ops *iommu, bool coherent)
> +		u64 size, bool coherent)
>  {
>  }
>  #endif /* CONFIG_ARCH_HAS_SETUP_DMA_OPS */
> -- 
> 2.42.0
> 

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()
@ 2023-11-12 17:35     ` Moritz Fischer
  0 siblings, 0 replies; 242+ messages in thread
From: Moritz Fischer @ 2023-11-12 17:35 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:46PM -0300, Jason Gunthorpe wrote:
> This is not being used to pass ops, it is just a way to tell if an
> iommu driver was probed. These days this can be detected directly via
> device_iommu_mapped(). Call device_iommu_mapped() in the two places that
> need to check it and remove the iommu parameter everywhere.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Reviewed-by: Moritz Fischer <mdf@kernel.org>
> ---
>  arch/arc/mm/dma.c               |  2 +-
>  arch/arm/mm/dma-mapping-nommu.c |  2 +-
>  arch/arm/mm/dma-mapping.c       | 10 +++++-----
>  arch/arm64/mm/dma-mapping.c     |  4 ++--
>  arch/mips/mm/dma-noncoherent.c  |  2 +-
>  arch/riscv/mm/dma-noncoherent.c |  2 +-
>  drivers/acpi/scan.c             |  3 +--
>  drivers/hv/hv_common.c          |  2 +-
>  drivers/of/device.c             |  2 +-
>  include/linux/dma-map-ops.h     |  4 ++--
>  10 files changed, 16 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
> index 2a7fbbb83b7056..197707bc765889 100644
> --- a/arch/arc/mm/dma.c
> +++ b/arch/arc/mm/dma.c
> @@ -91,7 +91,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
>   * Plug in direct dma map ops.
>   */
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	/*
>  	 * IOC hardware snoops all DMA traffic keeping the caches consistent
> diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
> index cfd9c933d2f09c..b94850b579952a 100644
> --- a/arch/arm/mm/dma-mapping-nommu.c
> +++ b/arch/arm/mm/dma-mapping-nommu.c
> @@ -34,7 +34,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
>  }
>  
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	if (IS_ENABLED(CONFIG_CPU_V7M)) {
>  		/*
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index 5409225b4abc06..6c359a3af8d9c7 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -1713,7 +1713,7 @@ void arm_iommu_detach_device(struct device *dev)
>  EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
>  
>  static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -				    const struct iommu_ops *iommu, bool coherent)
> +				    bool coherent)
>  {
>  	struct dma_iommu_mapping *mapping;
>  
> @@ -1748,7 +1748,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
>  #else
>  
>  static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -				    const struct iommu_ops *iommu, bool coherent)
> +				    bool coherent)
>  {
>  }
>  
> @@ -1757,7 +1757,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }
>  #endif	/* CONFIG_ARM_DMA_USE_IOMMU */
>  
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	/*
>  	 * Due to legacy code that sets the ->dma_coherent flag from a bus
> @@ -1776,8 +1776,8 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
>  	if (dev->dma_ops)
>  		return;
>  
> -	if (iommu)
> -		arm_setup_iommu_dma_ops(dev, dma_base, size, iommu, coherent);
> +	if (device_iommu_mapped(dev))
> +		arm_setup_iommu_dma_ops(dev, dma_base, size, coherent);
>  
>  	xen_setup_dma_ops(dev);
>  	dev->archdata.dma_ops_setup = true;
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index 3cb101e8cb29ba..61886e43e3a10f 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -47,7 +47,7 @@ void arch_teardown_dma_ops(struct device *dev)
>  #endif
>  
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	int cls = cache_line_size_of_cpu();
>  
> @@ -58,7 +58,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
>  		   ARCH_DMA_MINALIGN, cls);
>  
>  	dev->dma_coherent = coherent;
> -	if (iommu)
> +	if (device_iommu_mapped(dev))
>  		iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1);
>  
>  	xen_setup_dma_ops(dev);
> diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
> index 3c4fc97b9f394b..0f3cec663a12cd 100644
> --- a/arch/mips/mm/dma-noncoherent.c
> +++ b/arch/mips/mm/dma-noncoherent.c
> @@ -138,7 +138,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
>  
>  #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -		const struct iommu_ops *iommu, bool coherent)
> +		bool coherent)
>  {
>  	dev->dma_coherent = coherent;
>  }
> diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
> index b76e7e192eb183..f91fa741c41211 100644
> --- a/arch/riscv/mm/dma-noncoherent.c
> +++ b/arch/riscv/mm/dma-noncoherent.c
> @@ -135,7 +135,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
>  }
>  
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -		const struct iommu_ops *iommu, bool coherent)
> +			bool coherent)
>  {
>  	WARN_TAINT(!coherent && riscv_cbom_block_size > ARCH_DMA_MINALIGN,
>  		   TAINT_CPU_OUT_OF_SPEC,
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index 691d4b7686ee7e..a6891ad0ceee2c 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1636,8 +1636,7 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>  	if (PTR_ERR(iommu) == -EPROBE_DEFER)
>  		return -EPROBE_DEFER;
>  
> -	arch_setup_dma_ops(dev, 0, U64_MAX,
> -				iommu, attr == DEV_DMA_COHERENT);
> +	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
>  
>  	return 0;
>  }
> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> index ccad7bca3fd3da..fd938b6dfa7ed4 100644
> --- a/drivers/hv/hv_common.c
> +++ b/drivers/hv/hv_common.c
> @@ -489,7 +489,7 @@ void hv_setup_dma_ops(struct device *dev, bool coherent)
>  	 * Hyper-V does not offer a vIOMMU in the guest
>  	 * VM, so pass 0/NULL for the IOMMU settings
>  	 */
> -	arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
> +	arch_setup_dma_ops(dev, 0, 0, coherent);
>  }
>  EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
>  
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index 1ca42ad9dd159d..65c71be71a8d45 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -193,7 +193,7 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
>  	dev_dbg(dev, "device is%sbehind an iommu\n",
>  		iommu ? " " : " not ");
>  
> -	arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
> +	arch_setup_dma_ops(dev, dma_start, size, coherent);
>  
>  	if (!iommu)
>  		of_dma_set_restricted_buffer(dev, np);
> diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
> index f2fc203fb8a1a2..2cb98a12c50348 100644
> --- a/include/linux/dma-map-ops.h
> +++ b/include/linux/dma-map-ops.h
> @@ -426,10 +426,10 @@ bool arch_dma_unmap_sg_direct(struct device *dev, struct scatterlist *sg,
>  
>  #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
>  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -		const struct iommu_ops *iommu, bool coherent);
> +		bool coherent);
>  #else
>  static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
> -		u64 size, const struct iommu_ops *iommu, bool coherent)
> +		u64 size, bool coherent)
>  {
>  }
>  #endif /* CONFIG_ARCH_HAS_SETUP_DMA_OPS */
> -- 
> 2.42.0
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-12 17:44     ` Moritz Fischer
  -1 siblings, 0 replies; 242+ messages in thread
From: Moritz Fischer @ 2023-11-12 17:44 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:55PM -0300, Jason Gunthorpe wrote:
> This call chain is using dev->iommu->fwspec to pass around the fwspec
> between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
> iommu_probe_device()).
> 
> However there is no locking around the accesses to dev->iommu, so this is
> all racy.
> 
> Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
Nit: s/acpu_iommu_configure/acpi_iommu_configure_id() ?
> pass it through all functions on the stack to fill it with data, and
> finally pass it into iommu_probe_device_fwspec() which will load it into
> dev->iommu under a lock.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Reviewed-by: Moritz Fischer <mdf@kernel.org>
> ---
>  drivers/acpi/arm64/iort.c | 39 ++++++++---------
>  drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
>  drivers/acpi/viot.c       | 44 ++++++++++---------
>  drivers/iommu/iommu.c     |  5 +--
>  include/acpi/acpi_bus.h   |  8 ++--
>  include/linux/acpi_iort.h |  3 +-
>  include/linux/acpi_viot.h |  5 ++-
>  include/linux/iommu.h     |  2 +
>  8 files changed, 97 insertions(+), 98 deletions(-)
> 
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 6496ff5a6ba20d..accd01dcfe93f5 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
>  	return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
>  }
>  
> -static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> -			    u32 streamid)
> +static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> +			    struct acpi_iort_node *node, u32 streamid)
>  {
> -	const struct iommu_ops *ops;
>  	struct fwnode_handle *iort_fwnode;
>  
>  	if (!node)
> @@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
>  	 * in the kernel or not, defer the IOMMU configuration
>  	 * or just abort it.
>  	 */
> -	ops = iommu_ops_from_fwnode(iort_fwnode);
> -	if (!ops)
> -		return iort_iommu_driver_enabled(node->type) ?
> -		       -EPROBE_DEFER : -ENODEV;
> -
> -	return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
> +	return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
> +				      iort_iommu_driver_enabled(node->type));
>  }
>  
>  struct iort_pci_alias_info {
>  	struct device *dev;
>  	struct acpi_iort_node *node;
> +	struct iommu_fwspec *fwspec;
>  };
>  
>  static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> @@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
>  
>  	parent = iort_node_map_id(info->node, alias, &streamid,
>  				  IORT_IOMMU_TYPE);
> -	return iort_iommu_xlate(info->dev, parent, streamid);
> +	return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
>  }
>  
>  static void iort_named_component_init(struct device *dev,
> @@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
>  		dev_warn(dev, "Could not add device properties\n");
>  }
>  
> -static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> +static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
> +			     struct acpi_iort_node *node)
>  {
>  	struct acpi_iort_node *parent;
>  	int err = -ENODEV, i = 0;
> @@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
>  						   i++);
>  
>  		if (parent)
> -			err = iort_iommu_xlate(dev, parent, streamid);
> +			err = iort_iommu_xlate(fwspec, dev, parent, streamid);
>  	} while (parent && !err);
>  
>  	return err;
>  }
>  
> -static int iort_nc_iommu_map_id(struct device *dev,
> +static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
>  				struct acpi_iort_node *node,
>  				const u32 *in_id)
>  {
> @@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
>  
>  	parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
>  	if (parent)
> -		return iort_iommu_xlate(dev, parent, streamid);
> +		return iort_iommu_xlate(fwspec, dev, parent, streamid);
>  
>  	return -ENODEV;
>  }
> @@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
>   *
>   * Returns: 0 on success, <0 on failure
>   */
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +			    const u32 *id_in)
>  {
>  	struct acpi_iort_node *node;
>  	int err = -ENODEV;
>  
>  	if (dev_is_pci(dev)) {
> -		struct iommu_fwspec *fwspec;
>  		struct pci_bus *bus = to_pci_dev(dev)->bus;
> -		struct iort_pci_alias_info info = { .dev = dev };
> +		struct iort_pci_alias_info info = { .dev = dev,
> +						    .fwspec = fwspec };
>  
>  		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
>  				      iort_match_node_callback, &bus->dev);
> @@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>  		err = pci_for_each_dma_alias(to_pci_dev(dev),
>  					     iort_pci_iommu_init, &info);
>  
> -		fwspec = dev_iommu_fwspec_get(dev);
> -		if (fwspec && iort_pci_rc_supports_ats(node))
> +		if (iort_pci_rc_supports_ats(node))
>  			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
>  	} else {
>  		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> @@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>  		if (!node)
>  			return -ENODEV;
>  
> -		err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
> -			      iort_nc_iommu_map(dev, node);
> +		err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
> +			      iort_nc_iommu_map(fwspec, dev, node);
>  
>  		if (!err)
>  			iort_named_component_init(dev, node);
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index fbabde001a23a2..1e01a8e0316867 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
>  }
>  
>  #ifdef CONFIG_IOMMU_API
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -			   struct fwnode_handle *fwnode,
> -			   const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +			   u32 id, struct fwnode_handle *fwnode,
> +			   bool iommu_driver_available)
>  {
> -	int ret = iommu_fwspec_init(dev, fwnode, ops);
> +	int ret;
>  
> -	if (!ret)
> -		ret = iommu_fwspec_add_ids(dev, &id, 1);
> -
> -	return ret;
> -}
> -
> -static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
> -{
> -	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> -
> -	return fwspec ? fwspec->ops : NULL;
> +	ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
> +	if (ret) {
> +		if (ret == -EPROBE_DEFER && !iommu_driver_available)
> +			return -ENODEV;
> +		return ret;
> +	}
> +	return iommu_fwspec_append_ids(fwspec, &id, 1);
>  }
>  
>  static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
>  	int err;
> -	const struct iommu_ops *ops;
> +	struct iommu_fwspec *fwspec;
>  
> -	/*
> -	 * If we already translated the fwspec there is nothing left to do,
> -	 * return the iommu_ops.
> -	 */
> -	ops = acpi_iommu_fwspec_ops(dev);
> -	if (ops)
> -		return 0;
> +	fwspec = iommu_fwspec_alloc();
> +	if (IS_ERR(fwspec))
> +		return PTR_ERR(fwspec);
>  
> -	err = iort_iommu_configure_id(dev, id_in);
> -	if (err && err != -EPROBE_DEFER)
> -		err = viot_iommu_configure(dev);
> +	err = iort_iommu_configure_id(fwspec, dev, id_in);
> +	if (err == -ENODEV)
> +		err = viot_iommu_configure(fwspec, dev);
> +	if (err == -ENODEV || err == -EPROBE_DEFER)
> +		goto err_free;
> +	if (err)
> +		goto err_log;
>  
> -	/*
> -	 * If we have reason to believe the IOMMU driver missed the initial
> -	 * iommu_probe_device() call for dev, replay it to get things in order.
> -	 */
> -	if (!err && dev->bus)
> -		err = iommu_probe_device(dev);
> -
> -	/* Ignore all other errors apart from EPROBE_DEFER */
> -	if (err == -EPROBE_DEFER) {
> -		return err;
> -	} else if (err) {
> -		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> -		return -ENODEV;
> +	err = iommu_probe_device_fwspec(dev, fwspec);
> +	if (err) {
> +		/*
> +		 * Ownership for fwspec always passes into
> +		 * iommu_probe_device_fwspec()
> +		 */
> +		fwspec = NULL;
> +		goto err_log;
>  	}
> -	if (!acpi_iommu_fwspec_ops(dev))
> -		return -ENODEV;
> -	return 0;
> +
> +err_log:
> +	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> +err_free:
> +	iommu_fwspec_dealloc(fwspec);
> +	return err;
>  }
>  
>  #else /* !CONFIG_IOMMU_API */
>  
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -			   struct fwnode_handle *fwnode,
> -			   const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +			   u32 id, struct fwnode_handle *fwnode,
> +			   bool iommu_driver_available)
>  {
>  	return -ENODEV;
>  }
>  
> -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> -						       const u32 *id_in)
> +static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
> -	return NULL;
> +	return -ENODEV;
>  }
>  
>  #endif /* !CONFIG_IOMMU_API */
> diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
> index c8025921c129b2..33b511dd202d15 100644
> --- a/drivers/acpi/viot.c
> +++ b/drivers/acpi/viot.c
> @@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
>  	acpi_put_table(hdr);
>  }
>  
> -static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> -			       u32 epid)
> +static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
> +			       struct viot_iommu *viommu, u32 epid)
>  {
> -	const struct iommu_ops *ops;
> -
>  	if (!viommu)
>  		return -ENODEV;
>  
> @@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
>  	if (device_match_fwnode(dev, viommu->fwnode))
>  		return -EINVAL;
>  
> -	ops = iommu_ops_from_fwnode(viommu->fwnode);
> -	if (!ops)
> -		return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
> -			-EPROBE_DEFER : -ENODEV;
> -
> -	return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
> +	return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
> +				      IS_ENABLED(CONFIG_VIRTIO_IOMMU));
>  }
>  
> +struct viot_pci_alias_info {
> +	struct device *dev;
> +	struct iommu_fwspec *fwspec;
> +};
> +
>  static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>  {
>  	u32 epid;
>  	struct viot_endpoint *ep;
> -	struct device *aliased_dev = data;
> +	struct viot_pci_alias_info *info = data;
>  	u32 domain_nr = pci_domain_nr(pdev->bus);
>  
>  	list_for_each_entry(ep, &viot_pci_ranges, list) {
> @@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>  			epid = ((domain_nr - ep->segment_start) << 16) +
>  				dev_id - ep->bdf_start + ep->endpoint_id;
>  
> -			return viot_dev_iommu_init(aliased_dev, ep->viommu,
> -						   epid);
> +			return viot_dev_iommu_init(info->fwspec, info->dev,
> +						   ep->viommu, epid);
>  		}
>  	}
>  	return -ENODEV;
>  }
>  
> -static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> +static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
> +				    struct platform_device *pdev)
>  {
>  	struct resource *mem;
>  	struct viot_endpoint *ep;
> @@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>  
>  	list_for_each_entry(ep, &viot_mmio_endpoints, list) {
>  		if (ep->address == mem->start)
> -			return viot_dev_iommu_init(&pdev->dev, ep->viommu,
> -						   ep->endpoint_id);
> +			return viot_dev_iommu_init(fwspec, &pdev->dev,
> +						   ep->viommu, ep->endpoint_id);
>  	}
>  	return -ENODEV;
>  }
> @@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>   *
>   * Return: 0 on success, <0 on failure
>   */
> -int viot_iommu_configure(struct device *dev)
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
>  {
> -	if (dev_is_pci(dev))
> +	if (dev_is_pci(dev)) {
> +		struct viot_pci_alias_info info = { .dev = dev,
> +						    .fwspec = fwspec };
>  		return pci_for_each_dma_alias(to_pci_dev(dev),
> -					      viot_pci_dev_iommu_init, dev);
> +					      viot_pci_dev_iommu_init, &info);
> +	}
>  	else if (dev_is_platform(dev))
> -		return viot_mmio_dev_iommu_init(to_platform_device(dev));
> +		return viot_mmio_dev_iommu_init(fwspec,
> +						to_platform_device(dev));
>  	return -ENODEV;
>  }
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 15dbe2d9eb24c2..9cfba9d12d1400 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
>  	return ops;
>  }
>  
> -static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
> -				     struct device *dev,
> -				     struct fwnode_handle *iommu_fwnode)
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +			      struct fwnode_handle *iommu_fwnode)
>  {
>  	const struct iommu_ops *ops;
>  
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index 254685085c825c..70f97096c776e4 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -12,6 +12,8 @@
>  #include <linux/device.h>
>  #include <linux/property.h>
>  
> +struct iommu_fwspec;
> +
>  /* TBD: Make dynamic */
>  #define ACPI_MAX_HANDLES	10
>  struct acpi_handle_list {
> @@ -625,9 +627,9 @@ struct acpi_pci_root {
>  
>  bool acpi_dma_supported(const struct acpi_device *adev);
>  enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -			   struct fwnode_handle *fwnode,
> -			   const struct iommu_ops *ops);
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +			   u32 id, struct fwnode_handle *fwnode,
> +			   bool iommu_driver_available);
>  int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>  			   const u32 *input_id);
> diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> index 1cb65592c95dd3..80794ec45d1693 100644
> --- a/include/linux/acpi_iort.h
> +++ b/include/linux/acpi_iort.h
> @@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
>  		       struct list_head *head);
>  /* IOMMU interface */
>  int iort_dma_get_ranges(struct device *dev, u64 *size);
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +			    const u32 *id_in);
>  void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
>  phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
>  #else
> diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
> index a5a12243156377..f1874cb6d43c09 100644
> --- a/include/linux/acpi_viot.h
> +++ b/include/linux/acpi_viot.h
> @@ -8,11 +8,12 @@
>  #ifdef CONFIG_ACPI_VIOT
>  void __init acpi_viot_early_init(void);
>  void __init acpi_viot_init(void);
> -int viot_iommu_configure(struct device *dev);
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
>  #else
>  static inline void acpi_viot_early_init(void) {}
>  static inline void acpi_viot_init(void) {}
> -static inline int viot_iommu_configure(struct device *dev)
> +static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
> +				       struct device *dev)
>  {
>  	return -ENODEV;
>  }
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index c5a5e2b5e2cc2a..27e4605d498850 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
>  int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
>  			  struct fwnode_handle *iommu_fwnode,
>  			  struct of_phandle_args *iommu_spec);
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +			      struct fwnode_handle *iommu_fwnode);
>  
>  int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
>  		      const struct iommu_ops *ops);
> -- 
> 2.42.0
> 

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-12 17:44     ` Moritz Fischer
  0 siblings, 0 replies; 242+ messages in thread
From: Moritz Fischer @ 2023-11-12 17:44 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:55PM -0300, Jason Gunthorpe wrote:
> This call chain is using dev->iommu->fwspec to pass around the fwspec
> between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
> iommu_probe_device()).
> 
> However there is no locking around the accesses to dev->iommu, so this is
> all racy.
> 
> Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
Nit: s/acpu_iommu_configure/acpi_iommu_configure_id() ?
> pass it through all functions on the stack to fill it with data, and
> finally pass it into iommu_probe_device_fwspec() which will load it into
> dev->iommu under a lock.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Reviewed-by: Moritz Fischer <mdf@kernel.org>
> ---
>  drivers/acpi/arm64/iort.c | 39 ++++++++---------
>  drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
>  drivers/acpi/viot.c       | 44 ++++++++++---------
>  drivers/iommu/iommu.c     |  5 +--
>  include/acpi/acpi_bus.h   |  8 ++--
>  include/linux/acpi_iort.h |  3 +-
>  include/linux/acpi_viot.h |  5 ++-
>  include/linux/iommu.h     |  2 +
>  8 files changed, 97 insertions(+), 98 deletions(-)
> 
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 6496ff5a6ba20d..accd01dcfe93f5 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
>  	return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
>  }
>  
> -static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> -			    u32 streamid)
> +static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> +			    struct acpi_iort_node *node, u32 streamid)
>  {
> -	const struct iommu_ops *ops;
>  	struct fwnode_handle *iort_fwnode;
>  
>  	if (!node)
> @@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
>  	 * in the kernel or not, defer the IOMMU configuration
>  	 * or just abort it.
>  	 */
> -	ops = iommu_ops_from_fwnode(iort_fwnode);
> -	if (!ops)
> -		return iort_iommu_driver_enabled(node->type) ?
> -		       -EPROBE_DEFER : -ENODEV;
> -
> -	return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
> +	return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
> +				      iort_iommu_driver_enabled(node->type));
>  }
>  
>  struct iort_pci_alias_info {
>  	struct device *dev;
>  	struct acpi_iort_node *node;
> +	struct iommu_fwspec *fwspec;
>  };
>  
>  static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> @@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
>  
>  	parent = iort_node_map_id(info->node, alias, &streamid,
>  				  IORT_IOMMU_TYPE);
> -	return iort_iommu_xlate(info->dev, parent, streamid);
> +	return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
>  }
>  
>  static void iort_named_component_init(struct device *dev,
> @@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
>  		dev_warn(dev, "Could not add device properties\n");
>  }
>  
> -static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> +static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
> +			     struct acpi_iort_node *node)
>  {
>  	struct acpi_iort_node *parent;
>  	int err = -ENODEV, i = 0;
> @@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
>  						   i++);
>  
>  		if (parent)
> -			err = iort_iommu_xlate(dev, parent, streamid);
> +			err = iort_iommu_xlate(fwspec, dev, parent, streamid);
>  	} while (parent && !err);
>  
>  	return err;
>  }
>  
> -static int iort_nc_iommu_map_id(struct device *dev,
> +static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
>  				struct acpi_iort_node *node,
>  				const u32 *in_id)
>  {
> @@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
>  
>  	parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
>  	if (parent)
> -		return iort_iommu_xlate(dev, parent, streamid);
> +		return iort_iommu_xlate(fwspec, dev, parent, streamid);
>  
>  	return -ENODEV;
>  }
> @@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
>   *
>   * Returns: 0 on success, <0 on failure
>   */
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +			    const u32 *id_in)
>  {
>  	struct acpi_iort_node *node;
>  	int err = -ENODEV;
>  
>  	if (dev_is_pci(dev)) {
> -		struct iommu_fwspec *fwspec;
>  		struct pci_bus *bus = to_pci_dev(dev)->bus;
> -		struct iort_pci_alias_info info = { .dev = dev };
> +		struct iort_pci_alias_info info = { .dev = dev,
> +						    .fwspec = fwspec };
>  
>  		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
>  				      iort_match_node_callback, &bus->dev);
> @@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>  		err = pci_for_each_dma_alias(to_pci_dev(dev),
>  					     iort_pci_iommu_init, &info);
>  
> -		fwspec = dev_iommu_fwspec_get(dev);
> -		if (fwspec && iort_pci_rc_supports_ats(node))
> +		if (iort_pci_rc_supports_ats(node))
>  			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
>  	} else {
>  		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> @@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>  		if (!node)
>  			return -ENODEV;
>  
> -		err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
> -			      iort_nc_iommu_map(dev, node);
> +		err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
> +			      iort_nc_iommu_map(fwspec, dev, node);
>  
>  		if (!err)
>  			iort_named_component_init(dev, node);
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index fbabde001a23a2..1e01a8e0316867 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
>  }
>  
>  #ifdef CONFIG_IOMMU_API
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -			   struct fwnode_handle *fwnode,
> -			   const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +			   u32 id, struct fwnode_handle *fwnode,
> +			   bool iommu_driver_available)
>  {
> -	int ret = iommu_fwspec_init(dev, fwnode, ops);
> +	int ret;
>  
> -	if (!ret)
> -		ret = iommu_fwspec_add_ids(dev, &id, 1);
> -
> -	return ret;
> -}
> -
> -static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
> -{
> -	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> -
> -	return fwspec ? fwspec->ops : NULL;
> +	ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
> +	if (ret) {
> +		if (ret == -EPROBE_DEFER && !iommu_driver_available)
> +			return -ENODEV;
> +		return ret;
> +	}
> +	return iommu_fwspec_append_ids(fwspec, &id, 1);
>  }
>  
>  static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
>  	int err;
> -	const struct iommu_ops *ops;
> +	struct iommu_fwspec *fwspec;
>  
> -	/*
> -	 * If we already translated the fwspec there is nothing left to do,
> -	 * return the iommu_ops.
> -	 */
> -	ops = acpi_iommu_fwspec_ops(dev);
> -	if (ops)
> -		return 0;
> +	fwspec = iommu_fwspec_alloc();
> +	if (IS_ERR(fwspec))
> +		return PTR_ERR(fwspec);
>  
> -	err = iort_iommu_configure_id(dev, id_in);
> -	if (err && err != -EPROBE_DEFER)
> -		err = viot_iommu_configure(dev);
> +	err = iort_iommu_configure_id(fwspec, dev, id_in);
> +	if (err == -ENODEV)
> +		err = viot_iommu_configure(fwspec, dev);
> +	if (err == -ENODEV || err == -EPROBE_DEFER)
> +		goto err_free;
> +	if (err)
> +		goto err_log;
>  
> -	/*
> -	 * If we have reason to believe the IOMMU driver missed the initial
> -	 * iommu_probe_device() call for dev, replay it to get things in order.
> -	 */
> -	if (!err && dev->bus)
> -		err = iommu_probe_device(dev);
> -
> -	/* Ignore all other errors apart from EPROBE_DEFER */
> -	if (err == -EPROBE_DEFER) {
> -		return err;
> -	} else if (err) {
> -		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> -		return -ENODEV;
> +	err = iommu_probe_device_fwspec(dev, fwspec);
> +	if (err) {
> +		/*
> +		 * Ownership for fwspec always passes into
> +		 * iommu_probe_device_fwspec()
> +		 */
> +		fwspec = NULL;
> +		goto err_log;
>  	}
> -	if (!acpi_iommu_fwspec_ops(dev))
> -		return -ENODEV;
> -	return 0;
> +
> +err_log:
> +	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> +err_free:
> +	iommu_fwspec_dealloc(fwspec);
> +	return err;
>  }
>  
>  #else /* !CONFIG_IOMMU_API */
>  
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -			   struct fwnode_handle *fwnode,
> -			   const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +			   u32 id, struct fwnode_handle *fwnode,
> +			   bool iommu_driver_available)
>  {
>  	return -ENODEV;
>  }
>  
> -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> -						       const u32 *id_in)
> +static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
> -	return NULL;
> +	return -ENODEV;
>  }
>  
>  #endif /* !CONFIG_IOMMU_API */
> diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
> index c8025921c129b2..33b511dd202d15 100644
> --- a/drivers/acpi/viot.c
> +++ b/drivers/acpi/viot.c
> @@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
>  	acpi_put_table(hdr);
>  }
>  
> -static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> -			       u32 epid)
> +static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
> +			       struct viot_iommu *viommu, u32 epid)
>  {
> -	const struct iommu_ops *ops;
> -
>  	if (!viommu)
>  		return -ENODEV;
>  
> @@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
>  	if (device_match_fwnode(dev, viommu->fwnode))
>  		return -EINVAL;
>  
> -	ops = iommu_ops_from_fwnode(viommu->fwnode);
> -	if (!ops)
> -		return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
> -			-EPROBE_DEFER : -ENODEV;
> -
> -	return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
> +	return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
> +				      IS_ENABLED(CONFIG_VIRTIO_IOMMU));
>  }
>  
> +struct viot_pci_alias_info {
> +	struct device *dev;
> +	struct iommu_fwspec *fwspec;
> +};
> +
>  static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>  {
>  	u32 epid;
>  	struct viot_endpoint *ep;
> -	struct device *aliased_dev = data;
> +	struct viot_pci_alias_info *info = data;
>  	u32 domain_nr = pci_domain_nr(pdev->bus);
>  
>  	list_for_each_entry(ep, &viot_pci_ranges, list) {
> @@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>  			epid = ((domain_nr - ep->segment_start) << 16) +
>  				dev_id - ep->bdf_start + ep->endpoint_id;
>  
> -			return viot_dev_iommu_init(aliased_dev, ep->viommu,
> -						   epid);
> +			return viot_dev_iommu_init(info->fwspec, info->dev,
> +						   ep->viommu, epid);
>  		}
>  	}
>  	return -ENODEV;
>  }
>  
> -static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> +static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
> +				    struct platform_device *pdev)
>  {
>  	struct resource *mem;
>  	struct viot_endpoint *ep;
> @@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>  
>  	list_for_each_entry(ep, &viot_mmio_endpoints, list) {
>  		if (ep->address == mem->start)
> -			return viot_dev_iommu_init(&pdev->dev, ep->viommu,
> -						   ep->endpoint_id);
> +			return viot_dev_iommu_init(fwspec, &pdev->dev,
> +						   ep->viommu, ep->endpoint_id);
>  	}
>  	return -ENODEV;
>  }
> @@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>   *
>   * Return: 0 on success, <0 on failure
>   */
> -int viot_iommu_configure(struct device *dev)
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
>  {
> -	if (dev_is_pci(dev))
> +	if (dev_is_pci(dev)) {
> +		struct viot_pci_alias_info info = { .dev = dev,
> +						    .fwspec = fwspec };
>  		return pci_for_each_dma_alias(to_pci_dev(dev),
> -					      viot_pci_dev_iommu_init, dev);
> +					      viot_pci_dev_iommu_init, &info);
> +	}
>  	else if (dev_is_platform(dev))
> -		return viot_mmio_dev_iommu_init(to_platform_device(dev));
> +		return viot_mmio_dev_iommu_init(fwspec,
> +						to_platform_device(dev));
>  	return -ENODEV;
>  }
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 15dbe2d9eb24c2..9cfba9d12d1400 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
>  	return ops;
>  }
>  
> -static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
> -				     struct device *dev,
> -				     struct fwnode_handle *iommu_fwnode)
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +			      struct fwnode_handle *iommu_fwnode)
>  {
>  	const struct iommu_ops *ops;
>  
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index 254685085c825c..70f97096c776e4 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -12,6 +12,8 @@
>  #include <linux/device.h>
>  #include <linux/property.h>
>  
> +struct iommu_fwspec;
> +
>  /* TBD: Make dynamic */
>  #define ACPI_MAX_HANDLES	10
>  struct acpi_handle_list {
> @@ -625,9 +627,9 @@ struct acpi_pci_root {
>  
>  bool acpi_dma_supported(const struct acpi_device *adev);
>  enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -			   struct fwnode_handle *fwnode,
> -			   const struct iommu_ops *ops);
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +			   u32 id, struct fwnode_handle *fwnode,
> +			   bool iommu_driver_available);
>  int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>  			   const u32 *input_id);
> diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> index 1cb65592c95dd3..80794ec45d1693 100644
> --- a/include/linux/acpi_iort.h
> +++ b/include/linux/acpi_iort.h
> @@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
>  		       struct list_head *head);
>  /* IOMMU interface */
>  int iort_dma_get_ranges(struct device *dev, u64 *size);
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +			    const u32 *id_in);
>  void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
>  phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
>  #else
> diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
> index a5a12243156377..f1874cb6d43c09 100644
> --- a/include/linux/acpi_viot.h
> +++ b/include/linux/acpi_viot.h
> @@ -8,11 +8,12 @@
>  #ifdef CONFIG_ACPI_VIOT
>  void __init acpi_viot_early_init(void);
>  void __init acpi_viot_init(void);
> -int viot_iommu_configure(struct device *dev);
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
>  #else
>  static inline void acpi_viot_early_init(void) {}
>  static inline void acpi_viot_init(void) {}
> -static inline int viot_iommu_configure(struct device *dev)
> +static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
> +				       struct device *dev)
>  {
>  	return -ENODEV;
>  }
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index c5a5e2b5e2cc2a..27e4605d498850 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
>  int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
>  			  struct fwnode_handle *iommu_fwnode,
>  			  struct of_phandle_args *iommu_spec);
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +			      struct fwnode_handle *iommu_fwnode);
>  
>  int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
>  		      const struct iommu_ops *ops);
> -- 
> 2.42.0
> 

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-12 17:44     ` Moritz Fischer
  0 siblings, 0 replies; 242+ messages in thread
From: Moritz Fischer @ 2023-11-12 17:44 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:55PM -0300, Jason Gunthorpe wrote:
> This call chain is using dev->iommu->fwspec to pass around the fwspec
> between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
> iommu_probe_device()).
> 
> However there is no locking around the accesses to dev->iommu, so this is
> all racy.
> 
> Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
Nit: s/acpu_iommu_configure/acpi_iommu_configure_id() ?
> pass it through all functions on the stack to fill it with data, and
> finally pass it into iommu_probe_device_fwspec() which will load it into
> dev->iommu under a lock.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Reviewed-by: Moritz Fischer <mdf@kernel.org>
> ---
>  drivers/acpi/arm64/iort.c | 39 ++++++++---------
>  drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
>  drivers/acpi/viot.c       | 44 ++++++++++---------
>  drivers/iommu/iommu.c     |  5 +--
>  include/acpi/acpi_bus.h   |  8 ++--
>  include/linux/acpi_iort.h |  3 +-
>  include/linux/acpi_viot.h |  5 ++-
>  include/linux/iommu.h     |  2 +
>  8 files changed, 97 insertions(+), 98 deletions(-)
> 
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 6496ff5a6ba20d..accd01dcfe93f5 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
>  	return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
>  }
>  
> -static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> -			    u32 streamid)
> +static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> +			    struct acpi_iort_node *node, u32 streamid)
>  {
> -	const struct iommu_ops *ops;
>  	struct fwnode_handle *iort_fwnode;
>  
>  	if (!node)
> @@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
>  	 * in the kernel or not, defer the IOMMU configuration
>  	 * or just abort it.
>  	 */
> -	ops = iommu_ops_from_fwnode(iort_fwnode);
> -	if (!ops)
> -		return iort_iommu_driver_enabled(node->type) ?
> -		       -EPROBE_DEFER : -ENODEV;
> -
> -	return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
> +	return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
> +				      iort_iommu_driver_enabled(node->type));
>  }
>  
>  struct iort_pci_alias_info {
>  	struct device *dev;
>  	struct acpi_iort_node *node;
> +	struct iommu_fwspec *fwspec;
>  };
>  
>  static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> @@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
>  
>  	parent = iort_node_map_id(info->node, alias, &streamid,
>  				  IORT_IOMMU_TYPE);
> -	return iort_iommu_xlate(info->dev, parent, streamid);
> +	return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
>  }
>  
>  static void iort_named_component_init(struct device *dev,
> @@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
>  		dev_warn(dev, "Could not add device properties\n");
>  }
>  
> -static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> +static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
> +			     struct acpi_iort_node *node)
>  {
>  	struct acpi_iort_node *parent;
>  	int err = -ENODEV, i = 0;
> @@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
>  						   i++);
>  
>  		if (parent)
> -			err = iort_iommu_xlate(dev, parent, streamid);
> +			err = iort_iommu_xlate(fwspec, dev, parent, streamid);
>  	} while (parent && !err);
>  
>  	return err;
>  }
>  
> -static int iort_nc_iommu_map_id(struct device *dev,
> +static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
>  				struct acpi_iort_node *node,
>  				const u32 *in_id)
>  {
> @@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
>  
>  	parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
>  	if (parent)
> -		return iort_iommu_xlate(dev, parent, streamid);
> +		return iort_iommu_xlate(fwspec, dev, parent, streamid);
>  
>  	return -ENODEV;
>  }
> @@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
>   *
>   * Returns: 0 on success, <0 on failure
>   */
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +			    const u32 *id_in)
>  {
>  	struct acpi_iort_node *node;
>  	int err = -ENODEV;
>  
>  	if (dev_is_pci(dev)) {
> -		struct iommu_fwspec *fwspec;
>  		struct pci_bus *bus = to_pci_dev(dev)->bus;
> -		struct iort_pci_alias_info info = { .dev = dev };
> +		struct iort_pci_alias_info info = { .dev = dev,
> +						    .fwspec = fwspec };
>  
>  		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
>  				      iort_match_node_callback, &bus->dev);
> @@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>  		err = pci_for_each_dma_alias(to_pci_dev(dev),
>  					     iort_pci_iommu_init, &info);
>  
> -		fwspec = dev_iommu_fwspec_get(dev);
> -		if (fwspec && iort_pci_rc_supports_ats(node))
> +		if (iort_pci_rc_supports_ats(node))
>  			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
>  	} else {
>  		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> @@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>  		if (!node)
>  			return -ENODEV;
>  
> -		err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
> -			      iort_nc_iommu_map(dev, node);
> +		err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
> +			      iort_nc_iommu_map(fwspec, dev, node);
>  
>  		if (!err)
>  			iort_named_component_init(dev, node);
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index fbabde001a23a2..1e01a8e0316867 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
>  }
>  
>  #ifdef CONFIG_IOMMU_API
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -			   struct fwnode_handle *fwnode,
> -			   const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +			   u32 id, struct fwnode_handle *fwnode,
> +			   bool iommu_driver_available)
>  {
> -	int ret = iommu_fwspec_init(dev, fwnode, ops);
> +	int ret;
>  
> -	if (!ret)
> -		ret = iommu_fwspec_add_ids(dev, &id, 1);
> -
> -	return ret;
> -}
> -
> -static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
> -{
> -	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> -
> -	return fwspec ? fwspec->ops : NULL;
> +	ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
> +	if (ret) {
> +		if (ret == -EPROBE_DEFER && !iommu_driver_available)
> +			return -ENODEV;
> +		return ret;
> +	}
> +	return iommu_fwspec_append_ids(fwspec, &id, 1);
>  }
>  
>  static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
>  	int err;
> -	const struct iommu_ops *ops;
> +	struct iommu_fwspec *fwspec;
>  
> -	/*
> -	 * If we already translated the fwspec there is nothing left to do,
> -	 * return the iommu_ops.
> -	 */
> -	ops = acpi_iommu_fwspec_ops(dev);
> -	if (ops)
> -		return 0;
> +	fwspec = iommu_fwspec_alloc();
> +	if (IS_ERR(fwspec))
> +		return PTR_ERR(fwspec);
>  
> -	err = iort_iommu_configure_id(dev, id_in);
> -	if (err && err != -EPROBE_DEFER)
> -		err = viot_iommu_configure(dev);
> +	err = iort_iommu_configure_id(fwspec, dev, id_in);
> +	if (err == -ENODEV)
> +		err = viot_iommu_configure(fwspec, dev);
> +	if (err == -ENODEV || err == -EPROBE_DEFER)
> +		goto err_free;
> +	if (err)
> +		goto err_log;
>  
> -	/*
> -	 * If we have reason to believe the IOMMU driver missed the initial
> -	 * iommu_probe_device() call for dev, replay it to get things in order.
> -	 */
> -	if (!err && dev->bus)
> -		err = iommu_probe_device(dev);
> -
> -	/* Ignore all other errors apart from EPROBE_DEFER */
> -	if (err == -EPROBE_DEFER) {
> -		return err;
> -	} else if (err) {
> -		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> -		return -ENODEV;
> +	err = iommu_probe_device_fwspec(dev, fwspec);
> +	if (err) {
> +		/*
> +		 * Ownership for fwspec always passes into
> +		 * iommu_probe_device_fwspec()
> +		 */
> +		fwspec = NULL;
> +		goto err_log;
>  	}
> -	if (!acpi_iommu_fwspec_ops(dev))
> -		return -ENODEV;
> -	return 0;
> +
> +err_log:
> +	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> +err_free:
> +	iommu_fwspec_dealloc(fwspec);
> +	return err;
>  }
>  
>  #else /* !CONFIG_IOMMU_API */
>  
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -			   struct fwnode_handle *fwnode,
> -			   const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +			   u32 id, struct fwnode_handle *fwnode,
> +			   bool iommu_driver_available)
>  {
>  	return -ENODEV;
>  }
>  
> -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> -						       const u32 *id_in)
> +static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
> -	return NULL;
> +	return -ENODEV;
>  }
>  
>  #endif /* !CONFIG_IOMMU_API */
> diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
> index c8025921c129b2..33b511dd202d15 100644
> --- a/drivers/acpi/viot.c
> +++ b/drivers/acpi/viot.c
> @@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
>  	acpi_put_table(hdr);
>  }
>  
> -static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> -			       u32 epid)
> +static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
> +			       struct viot_iommu *viommu, u32 epid)
>  {
> -	const struct iommu_ops *ops;
> -
>  	if (!viommu)
>  		return -ENODEV;
>  
> @@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
>  	if (device_match_fwnode(dev, viommu->fwnode))
>  		return -EINVAL;
>  
> -	ops = iommu_ops_from_fwnode(viommu->fwnode);
> -	if (!ops)
> -		return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
> -			-EPROBE_DEFER : -ENODEV;
> -
> -	return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
> +	return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
> +				      IS_ENABLED(CONFIG_VIRTIO_IOMMU));
>  }
>  
> +struct viot_pci_alias_info {
> +	struct device *dev;
> +	struct iommu_fwspec *fwspec;
> +};
> +
>  static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>  {
>  	u32 epid;
>  	struct viot_endpoint *ep;
> -	struct device *aliased_dev = data;
> +	struct viot_pci_alias_info *info = data;
>  	u32 domain_nr = pci_domain_nr(pdev->bus);
>  
>  	list_for_each_entry(ep, &viot_pci_ranges, list) {
> @@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>  			epid = ((domain_nr - ep->segment_start) << 16) +
>  				dev_id - ep->bdf_start + ep->endpoint_id;
>  
> -			return viot_dev_iommu_init(aliased_dev, ep->viommu,
> -						   epid);
> +			return viot_dev_iommu_init(info->fwspec, info->dev,
> +						   ep->viommu, epid);
>  		}
>  	}
>  	return -ENODEV;
>  }
>  
> -static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> +static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
> +				    struct platform_device *pdev)
>  {
>  	struct resource *mem;
>  	struct viot_endpoint *ep;
> @@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>  
>  	list_for_each_entry(ep, &viot_mmio_endpoints, list) {
>  		if (ep->address == mem->start)
> -			return viot_dev_iommu_init(&pdev->dev, ep->viommu,
> -						   ep->endpoint_id);
> +			return viot_dev_iommu_init(fwspec, &pdev->dev,
> +						   ep->viommu, ep->endpoint_id);
>  	}
>  	return -ENODEV;
>  }
> @@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>   *
>   * Return: 0 on success, <0 on failure
>   */
> -int viot_iommu_configure(struct device *dev)
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
>  {
> -	if (dev_is_pci(dev))
> +	if (dev_is_pci(dev)) {
> +		struct viot_pci_alias_info info = { .dev = dev,
> +						    .fwspec = fwspec };
>  		return pci_for_each_dma_alias(to_pci_dev(dev),
> -					      viot_pci_dev_iommu_init, dev);
> +					      viot_pci_dev_iommu_init, &info);
> +	}
>  	else if (dev_is_platform(dev))
> -		return viot_mmio_dev_iommu_init(to_platform_device(dev));
> +		return viot_mmio_dev_iommu_init(fwspec,
> +						to_platform_device(dev));
>  	return -ENODEV;
>  }
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 15dbe2d9eb24c2..9cfba9d12d1400 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
>  	return ops;
>  }
>  
> -static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
> -				     struct device *dev,
> -				     struct fwnode_handle *iommu_fwnode)
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +			      struct fwnode_handle *iommu_fwnode)
>  {
>  	const struct iommu_ops *ops;
>  
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index 254685085c825c..70f97096c776e4 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -12,6 +12,8 @@
>  #include <linux/device.h>
>  #include <linux/property.h>
>  
> +struct iommu_fwspec;
> +
>  /* TBD: Make dynamic */
>  #define ACPI_MAX_HANDLES	10
>  struct acpi_handle_list {
> @@ -625,9 +627,9 @@ struct acpi_pci_root {
>  
>  bool acpi_dma_supported(const struct acpi_device *adev);
>  enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -			   struct fwnode_handle *fwnode,
> -			   const struct iommu_ops *ops);
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +			   u32 id, struct fwnode_handle *fwnode,
> +			   bool iommu_driver_available);
>  int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>  			   const u32 *input_id);
> diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> index 1cb65592c95dd3..80794ec45d1693 100644
> --- a/include/linux/acpi_iort.h
> +++ b/include/linux/acpi_iort.h
> @@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
>  		       struct list_head *head);
>  /* IOMMU interface */
>  int iort_dma_get_ranges(struct device *dev, u64 *size);
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +			    const u32 *id_in);
>  void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
>  phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
>  #else
> diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
> index a5a12243156377..f1874cb6d43c09 100644
> --- a/include/linux/acpi_viot.h
> +++ b/include/linux/acpi_viot.h
> @@ -8,11 +8,12 @@
>  #ifdef CONFIG_ACPI_VIOT
>  void __init acpi_viot_early_init(void);
>  void __init acpi_viot_init(void);
> -int viot_iommu_configure(struct device *dev);
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
>  #else
>  static inline void acpi_viot_early_init(void) {}
>  static inline void acpi_viot_init(void) {}
> -static inline int viot_iommu_configure(struct device *dev)
> +static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
> +				       struct device *dev)
>  {
>  	return -ENODEV;
>  }
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index c5a5e2b5e2cc2a..27e4605d498850 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
>  int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
>  			  struct fwnode_handle *iommu_fwnode,
>  			  struct of_phandle_args *iommu_spec);
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +			      struct fwnode_handle *iommu_fwnode);
>  
>  int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
>  		      const struct iommu_ops *ops);
> -- 
> 2.42.0
> 

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-12 17:44     ` Moritz Fischer
  0 siblings, 0 replies; 242+ messages in thread
From: Moritz Fischer @ 2023-11-12 17:44 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:55PM -0300, Jason Gunthorpe wrote:
> This call chain is using dev->iommu->fwspec to pass around the fwspec
> between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
> iommu_probe_device()).
> 
> However there is no locking around the accesses to dev->iommu, so this is
> all racy.
> 
> Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
Nit: s/acpu_iommu_configure/acpi_iommu_configure_id() ?
> pass it through all functions on the stack to fill it with data, and
> finally pass it into iommu_probe_device_fwspec() which will load it into
> dev->iommu under a lock.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Reviewed-by: Moritz Fischer <mdf@kernel.org>
> ---
>  drivers/acpi/arm64/iort.c | 39 ++++++++---------
>  drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
>  drivers/acpi/viot.c       | 44 ++++++++++---------
>  drivers/iommu/iommu.c     |  5 +--
>  include/acpi/acpi_bus.h   |  8 ++--
>  include/linux/acpi_iort.h |  3 +-
>  include/linux/acpi_viot.h |  5 ++-
>  include/linux/iommu.h     |  2 +
>  8 files changed, 97 insertions(+), 98 deletions(-)
> 
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 6496ff5a6ba20d..accd01dcfe93f5 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
>  	return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
>  }
>  
> -static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> -			    u32 streamid)
> +static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> +			    struct acpi_iort_node *node, u32 streamid)
>  {
> -	const struct iommu_ops *ops;
>  	struct fwnode_handle *iort_fwnode;
>  
>  	if (!node)
> @@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
>  	 * in the kernel or not, defer the IOMMU configuration
>  	 * or just abort it.
>  	 */
> -	ops = iommu_ops_from_fwnode(iort_fwnode);
> -	if (!ops)
> -		return iort_iommu_driver_enabled(node->type) ?
> -		       -EPROBE_DEFER : -ENODEV;
> -
> -	return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
> +	return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
> +				      iort_iommu_driver_enabled(node->type));
>  }
>  
>  struct iort_pci_alias_info {
>  	struct device *dev;
>  	struct acpi_iort_node *node;
> +	struct iommu_fwspec *fwspec;
>  };
>  
>  static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> @@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
>  
>  	parent = iort_node_map_id(info->node, alias, &streamid,
>  				  IORT_IOMMU_TYPE);
> -	return iort_iommu_xlate(info->dev, parent, streamid);
> +	return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
>  }
>  
>  static void iort_named_component_init(struct device *dev,
> @@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
>  		dev_warn(dev, "Could not add device properties\n");
>  }
>  
> -static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> +static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
> +			     struct acpi_iort_node *node)
>  {
>  	struct acpi_iort_node *parent;
>  	int err = -ENODEV, i = 0;
> @@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
>  						   i++);
>  
>  		if (parent)
> -			err = iort_iommu_xlate(dev, parent, streamid);
> +			err = iort_iommu_xlate(fwspec, dev, parent, streamid);
>  	} while (parent && !err);
>  
>  	return err;
>  }
>  
> -static int iort_nc_iommu_map_id(struct device *dev,
> +static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
>  				struct acpi_iort_node *node,
>  				const u32 *in_id)
>  {
> @@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
>  
>  	parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
>  	if (parent)
> -		return iort_iommu_xlate(dev, parent, streamid);
> +		return iort_iommu_xlate(fwspec, dev, parent, streamid);
>  
>  	return -ENODEV;
>  }
> @@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
>   *
>   * Returns: 0 on success, <0 on failure
>   */
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +			    const u32 *id_in)
>  {
>  	struct acpi_iort_node *node;
>  	int err = -ENODEV;
>  
>  	if (dev_is_pci(dev)) {
> -		struct iommu_fwspec *fwspec;
>  		struct pci_bus *bus = to_pci_dev(dev)->bus;
> -		struct iort_pci_alias_info info = { .dev = dev };
> +		struct iort_pci_alias_info info = { .dev = dev,
> +						    .fwspec = fwspec };
>  
>  		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
>  				      iort_match_node_callback, &bus->dev);
> @@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>  		err = pci_for_each_dma_alias(to_pci_dev(dev),
>  					     iort_pci_iommu_init, &info);
>  
> -		fwspec = dev_iommu_fwspec_get(dev);
> -		if (fwspec && iort_pci_rc_supports_ats(node))
> +		if (iort_pci_rc_supports_ats(node))
>  			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
>  	} else {
>  		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> @@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
>  		if (!node)
>  			return -ENODEV;
>  
> -		err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
> -			      iort_nc_iommu_map(dev, node);
> +		err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
> +			      iort_nc_iommu_map(fwspec, dev, node);
>  
>  		if (!err)
>  			iort_named_component_init(dev, node);
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index fbabde001a23a2..1e01a8e0316867 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
>  }
>  
>  #ifdef CONFIG_IOMMU_API
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -			   struct fwnode_handle *fwnode,
> -			   const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +			   u32 id, struct fwnode_handle *fwnode,
> +			   bool iommu_driver_available)
>  {
> -	int ret = iommu_fwspec_init(dev, fwnode, ops);
> +	int ret;
>  
> -	if (!ret)
> -		ret = iommu_fwspec_add_ids(dev, &id, 1);
> -
> -	return ret;
> -}
> -
> -static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
> -{
> -	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> -
> -	return fwspec ? fwspec->ops : NULL;
> +	ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
> +	if (ret) {
> +		if (ret == -EPROBE_DEFER && !iommu_driver_available)
> +			return -ENODEV;
> +		return ret;
> +	}
> +	return iommu_fwspec_append_ids(fwspec, &id, 1);
>  }
>  
>  static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
>  	int err;
> -	const struct iommu_ops *ops;
> +	struct iommu_fwspec *fwspec;
>  
> -	/*
> -	 * If we already translated the fwspec there is nothing left to do,
> -	 * return the iommu_ops.
> -	 */
> -	ops = acpi_iommu_fwspec_ops(dev);
> -	if (ops)
> -		return 0;
> +	fwspec = iommu_fwspec_alloc();
> +	if (IS_ERR(fwspec))
> +		return PTR_ERR(fwspec);
>  
> -	err = iort_iommu_configure_id(dev, id_in);
> -	if (err && err != -EPROBE_DEFER)
> -		err = viot_iommu_configure(dev);
> +	err = iort_iommu_configure_id(fwspec, dev, id_in);
> +	if (err == -ENODEV)
> +		err = viot_iommu_configure(fwspec, dev);
> +	if (err == -ENODEV || err == -EPROBE_DEFER)
> +		goto err_free;
> +	if (err)
> +		goto err_log;
>  
> -	/*
> -	 * If we have reason to believe the IOMMU driver missed the initial
> -	 * iommu_probe_device() call for dev, replay it to get things in order.
> -	 */
> -	if (!err && dev->bus)
> -		err = iommu_probe_device(dev);
> -
> -	/* Ignore all other errors apart from EPROBE_DEFER */
> -	if (err == -EPROBE_DEFER) {
> -		return err;
> -	} else if (err) {
> -		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> -		return -ENODEV;
> +	err = iommu_probe_device_fwspec(dev, fwspec);
> +	if (err) {
> +		/*
> +		 * Ownership for fwspec always passes into
> +		 * iommu_probe_device_fwspec()
> +		 */
> +		fwspec = NULL;
> +		goto err_log;
>  	}
> -	if (!acpi_iommu_fwspec_ops(dev))
> -		return -ENODEV;
> -	return 0;
> +
> +err_log:
> +	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> +err_free:
> +	iommu_fwspec_dealloc(fwspec);
> +	return err;
>  }
>  
>  #else /* !CONFIG_IOMMU_API */
>  
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -			   struct fwnode_handle *fwnode,
> -			   const struct iommu_ops *ops)
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +			   u32 id, struct fwnode_handle *fwnode,
> +			   bool iommu_driver_available)
>  {
>  	return -ENODEV;
>  }
>  
> -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> -						       const u32 *id_in)
> +static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>  {
> -	return NULL;
> +	return -ENODEV;
>  }
>  
>  #endif /* !CONFIG_IOMMU_API */
> diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
> index c8025921c129b2..33b511dd202d15 100644
> --- a/drivers/acpi/viot.c
> +++ b/drivers/acpi/viot.c
> @@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
>  	acpi_put_table(hdr);
>  }
>  
> -static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> -			       u32 epid)
> +static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
> +			       struct viot_iommu *viommu, u32 epid)
>  {
> -	const struct iommu_ops *ops;
> -
>  	if (!viommu)
>  		return -ENODEV;
>  
> @@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
>  	if (device_match_fwnode(dev, viommu->fwnode))
>  		return -EINVAL;
>  
> -	ops = iommu_ops_from_fwnode(viommu->fwnode);
> -	if (!ops)
> -		return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
> -			-EPROBE_DEFER : -ENODEV;
> -
> -	return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
> +	return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
> +				      IS_ENABLED(CONFIG_VIRTIO_IOMMU));
>  }
>  
> +struct viot_pci_alias_info {
> +	struct device *dev;
> +	struct iommu_fwspec *fwspec;
> +};
> +
>  static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>  {
>  	u32 epid;
>  	struct viot_endpoint *ep;
> -	struct device *aliased_dev = data;
> +	struct viot_pci_alias_info *info = data;
>  	u32 domain_nr = pci_domain_nr(pdev->bus);
>  
>  	list_for_each_entry(ep, &viot_pci_ranges, list) {
> @@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
>  			epid = ((domain_nr - ep->segment_start) << 16) +
>  				dev_id - ep->bdf_start + ep->endpoint_id;
>  
> -			return viot_dev_iommu_init(aliased_dev, ep->viommu,
> -						   epid);
> +			return viot_dev_iommu_init(info->fwspec, info->dev,
> +						   ep->viommu, epid);
>  		}
>  	}
>  	return -ENODEV;
>  }
>  
> -static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> +static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
> +				    struct platform_device *pdev)
>  {
>  	struct resource *mem;
>  	struct viot_endpoint *ep;
> @@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>  
>  	list_for_each_entry(ep, &viot_mmio_endpoints, list) {
>  		if (ep->address == mem->start)
> -			return viot_dev_iommu_init(&pdev->dev, ep->viommu,
> -						   ep->endpoint_id);
> +			return viot_dev_iommu_init(fwspec, &pdev->dev,
> +						   ep->viommu, ep->endpoint_id);
>  	}
>  	return -ENODEV;
>  }
> @@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
>   *
>   * Return: 0 on success, <0 on failure
>   */
> -int viot_iommu_configure(struct device *dev)
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
>  {
> -	if (dev_is_pci(dev))
> +	if (dev_is_pci(dev)) {
> +		struct viot_pci_alias_info info = { .dev = dev,
> +						    .fwspec = fwspec };
>  		return pci_for_each_dma_alias(to_pci_dev(dev),
> -					      viot_pci_dev_iommu_init, dev);
> +					      viot_pci_dev_iommu_init, &info);
> +	}
>  	else if (dev_is_platform(dev))
> -		return viot_mmio_dev_iommu_init(to_platform_device(dev));
> +		return viot_mmio_dev_iommu_init(fwspec,
> +						to_platform_device(dev));
>  	return -ENODEV;
>  }
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 15dbe2d9eb24c2..9cfba9d12d1400 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
>  	return ops;
>  }
>  
> -static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
> -				     struct device *dev,
> -				     struct fwnode_handle *iommu_fwnode)
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +			      struct fwnode_handle *iommu_fwnode)
>  {
>  	const struct iommu_ops *ops;
>  
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index 254685085c825c..70f97096c776e4 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -12,6 +12,8 @@
>  #include <linux/device.h>
>  #include <linux/property.h>
>  
> +struct iommu_fwspec;
> +
>  /* TBD: Make dynamic */
>  #define ACPI_MAX_HANDLES	10
>  struct acpi_handle_list {
> @@ -625,9 +627,9 @@ struct acpi_pci_root {
>  
>  bool acpi_dma_supported(const struct acpi_device *adev);
>  enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> -			   struct fwnode_handle *fwnode,
> -			   const struct iommu_ops *ops);
> +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> +			   u32 id, struct fwnode_handle *fwnode,
> +			   bool iommu_driver_available);
>  int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
>  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>  			   const u32 *input_id);
> diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> index 1cb65592c95dd3..80794ec45d1693 100644
> --- a/include/linux/acpi_iort.h
> +++ b/include/linux/acpi_iort.h
> @@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
>  		       struct list_head *head);
>  /* IOMMU interface */
>  int iort_dma_get_ranges(struct device *dev, u64 *size);
> -int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
> +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> +			    const u32 *id_in);
>  void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
>  phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
>  #else
> diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
> index a5a12243156377..f1874cb6d43c09 100644
> --- a/include/linux/acpi_viot.h
> +++ b/include/linux/acpi_viot.h
> @@ -8,11 +8,12 @@
>  #ifdef CONFIG_ACPI_VIOT
>  void __init acpi_viot_early_init(void);
>  void __init acpi_viot_init(void);
> -int viot_iommu_configure(struct device *dev);
> +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
>  #else
>  static inline void acpi_viot_early_init(void) {}
>  static inline void acpi_viot_init(void) {}
> -static inline int viot_iommu_configure(struct device *dev)
> +static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
> +				       struct device *dev)
>  {
>  	return -ENODEV;
>  }
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index c5a5e2b5e2cc2a..27e4605d498850 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
>  int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
>  			  struct fwnode_handle *iommu_fwnode,
>  			  struct of_phandle_args *iommu_spec);
> +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> +			      struct fwnode_handle *iommu_fwnode);
>  
>  int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
>  		      const struct iommu_ops *ops);
> -- 
> 2.42.0
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 12/17] iommu: Make iommu_ops_from_fwnode() static
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-13 20:02     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:02 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:57PM -0300, Jason Gunthorpe wrote:
...
> @@ -1044,11 +1043,6 @@ static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
>  }
>  
>  static inline

   ^ was missed in the deletion below

> -const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
> -{
> -	return NULL;
> -}
> -
>  static inline int
>  iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features feat)
>  {
> -- 
> 2.42.0
> 


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 12/17] iommu: Make iommu_ops_from_fwnode() static
@ 2023-11-13 20:02     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:02 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:57PM -0300, Jason Gunthorpe wrote:
...
> @@ -1044,11 +1043,6 @@ static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
>  }
>  
>  static inline

   ^ was missed in the deletion below

> -const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
> -{
> -	return NULL;
> -}
> -
>  static inline int
>  iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features feat)
>  {
> -- 
> 2.42.0
> 


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 12/17] iommu: Make iommu_ops_from_fwnode() static
@ 2023-11-13 20:02     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:02 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:57PM -0300, Jason Gunthorpe wrote:
...
> @@ -1044,11 +1043,6 @@ static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
>  }
>  
>  static inline

   ^ was missed in the deletion below

> -const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
> -{
> -	return NULL;
> -}
> -
>  static inline int
>  iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features feat)
>  {
> -- 
> 2.42.0
> 


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 12/17] iommu: Make iommu_ops_from_fwnode() static
@ 2023-11-13 20:02     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:02 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Fri, Nov 03, 2023 at 01:44:57PM -0300, Jason Gunthorpe wrote:
...
> @@ -1044,11 +1043,6 @@ static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
>  }
>  
>  static inline

   ^ was missed in the deletion below

> -const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
> -{
> -	return NULL;
> -}
> -
>  static inline int
>  iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features feat)
>  {
> -- 
> 2.42.0
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 13/17] iommu: Remove dev_iommu_fwspec_set()
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-13 20:06     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:06 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 13/17] iommu: Remove dev_iommu_fwspec_set()
@ 2023-11-13 20:06     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:06 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 13/17] iommu: Remove dev_iommu_fwspec_set()
@ 2023-11-13 20:06     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:06 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 13/17] iommu: Remove dev_iommu_fwspec_set()
@ 2023-11-13 20:06     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:06 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 05/17] iommu: Make iommu_fwspec->ids a distinct allocation
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-13 20:10     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:10 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 05/17] iommu: Make iommu_fwspec->ids a distinct allocation
@ 2023-11-13 20:10     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:10 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 05/17] iommu: Make iommu_fwspec->ids a distinct allocation
@ 2023-11-13 20:10     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:10 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 05/17] iommu: Make iommu_fwspec->ids a distinct allocation
@ 2023-11-13 20:10     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:10 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 06/17] iommu: Add iommu_fwspec_alloc/dealloc()
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-13 20:11     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:11 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 06/17] iommu: Add iommu_fwspec_alloc/dealloc()
@ 2023-11-13 20:11     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:11 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 06/17] iommu: Add iommu_fwspec_alloc/dealloc()
@ 2023-11-13 20:11     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:11 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 06/17] iommu: Add iommu_fwspec_alloc/dealloc()
@ 2023-11-13 20:11     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:11 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 07/17] iommu: Add iommu_probe_device_fwspec()
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-13 20:11     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:11 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 07/17] iommu: Add iommu_probe_device_fwspec()
@ 2023-11-13 20:11     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:11 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 07/17] iommu: Add iommu_probe_device_fwspec()
@ 2023-11-13 20:11     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:11 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 07/17] iommu: Add iommu_probe_device_fwspec()
@ 2023-11-13 20:11     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:11 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 08/17] of: Do not use dev->iommu within of_iommu_configure()
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-13 20:11     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:11 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 08/17] of: Do not use dev->iommu within of_iommu_configure()
@ 2023-11-13 20:11     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:11 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 08/17] of: Do not use dev->iommu within of_iommu_configure()
@ 2023-11-13 20:11     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:11 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 08/17] of: Do not use dev->iommu within of_iommu_configure()
@ 2023-11-13 20:11     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:11 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 09/17] iommu: Add iommu_fwspec_append_ids()
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-13 20:12     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:12 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 09/17] iommu: Add iommu_fwspec_append_ids()
@ 2023-11-13 20:12     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:12 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 09/17] iommu: Add iommu_fwspec_append_ids()
@ 2023-11-13 20:12     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:12 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 09/17] iommu: Add iommu_fwspec_append_ids()
@ 2023-11-13 20:12     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:12 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-13 20:13     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:13 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-13 20:13     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:13 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-13 20:13     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:13 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-13 20:13     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:13 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 11/17] iommu: Hold iommu_probe_device_lock while calling ops->of_xlate
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-13 20:14     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:14 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 11/17] iommu: Hold iommu_probe_device_lock while calling ops->of_xlate
@ 2023-11-13 20:14     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:14 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 11/17] iommu: Hold iommu_probe_device_lock while calling ops->of_xlate
@ 2023-11-13 20:14     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:14 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 11/17] iommu: Hold iommu_probe_device_lock while calling ops->of_xlate
@ 2023-11-13 20:14     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:14 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 14/17] iommu: Remove pointless iommu_fwspec_free()
  2023-11-03 16:44   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-13 20:18     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:18 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 14/17] iommu: Remove pointless iommu_fwspec_free()
@ 2023-11-13 20:18     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:18 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 14/17] iommu: Remove pointless iommu_fwspec_free()
@ 2023-11-13 20:18     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:18 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 14/17] iommu: Remove pointless iommu_fwspec_free()
@ 2023-11-13 20:18     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:18 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 15/17] iommu: Add ops->of_xlate_fwspec()
  2023-11-03 16:45   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-13 20:23     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:23 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 15/17] iommu: Add ops->of_xlate_fwspec()
@ 2023-11-13 20:23     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:23 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 15/17] iommu: Add ops->of_xlate_fwspec()
@ 2023-11-13 20:23     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:23 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 15/17] iommu: Add ops->of_xlate_fwspec()
@ 2023-11-13 20:23     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:23 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 16/17] iommu: Mark dev_iommu_get() with lockdep
  2023-11-03 16:45   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-13 20:25     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:25 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 16/17] iommu: Mark dev_iommu_get() with lockdep
@ 2023-11-13 20:25     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:25 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 16/17] iommu: Mark dev_iommu_get() with lockdep
@ 2023-11-13 20:25     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:25 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 16/17] iommu: Mark dev_iommu_get() with lockdep
@ 2023-11-13 20:25     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:25 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 17/17] iommu: Mark dev_iommu_priv_set() with a lockdep
  2023-11-03 16:45   ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-13 20:35     ` Jerry Snitselaar
  -1 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:35 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 17/17] iommu: Mark dev_iommu_priv_set() with a lockdep
@ 2023-11-13 20:35     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:35 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 17/17] iommu: Mark dev_iommu_priv_set() with a lockdep
@ 2023-11-13 20:35     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:35 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 17/17] iommu: Mark dev_iommu_priv_set() with a lockdep
@ 2023-11-13 20:35     ` Jerry Snitselaar
  0 siblings, 0 replies; 242+ messages in thread
From: Jerry Snitselaar @ 2023-11-13 20:35 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
  2023-11-12 17:44     ` Moritz Fischer
  (?)
  (?)
@ 2023-11-13 22:37       ` Jason Gunthorpe
  -1 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-13 22:37 UTC (permalink / raw)
  To: Moritz Fischer
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Sun, Nov 12, 2023 at 09:44:18AM -0800, Moritz Fischer wrote:
> On Fri, Nov 03, 2023 at 01:44:55PM -0300, Jason Gunthorpe wrote:
> > This call chain is using dev->iommu->fwspec to pass around the fwspec
> > between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
> > iommu_probe_device()).
> > 
> > However there is no locking around the accesses to dev->iommu, so this is
> > all racy.
> > 
> > Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
> Nit: s/acpu_iommu_configure/acpi_iommu_configure_id() ?

Yep

Thanks
Jason

> > pass it through all functions on the stack to fill it with data, and
> > finally pass it into iommu_probe_device_fwspec() which will load it into
> > dev->iommu under a lock.
> > 
> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> 
> Reviewed-by: Moritz Fischer <mdf@kernel.org>
> > ---
> >  drivers/acpi/arm64/iort.c | 39 ++++++++---------
> >  drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
> >  drivers/acpi/viot.c       | 44 ++++++++++---------
> >  drivers/iommu/iommu.c     |  5 +--
> >  include/acpi/acpi_bus.h   |  8 ++--
> >  include/linux/acpi_iort.h |  3 +-
> >  include/linux/acpi_viot.h |  5 ++-
> >  include/linux/iommu.h     |  2 +
> >  8 files changed, 97 insertions(+), 98 deletions(-)
> > 
> > diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> > index 6496ff5a6ba20d..accd01dcfe93f5 100644
> > --- a/drivers/acpi/arm64/iort.c
> > +++ b/drivers/acpi/arm64/iort.c
> > @@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
> >  	return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
> >  }
> >  
> > -static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> > -			    u32 streamid)
> > +static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> > +			    struct acpi_iort_node *node, u32 streamid)
> >  {
> > -	const struct iommu_ops *ops;
> >  	struct fwnode_handle *iort_fwnode;
> >  
> >  	if (!node)
> > @@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> >  	 * in the kernel or not, defer the IOMMU configuration
> >  	 * or just abort it.
> >  	 */
> > -	ops = iommu_ops_from_fwnode(iort_fwnode);
> > -	if (!ops)
> > -		return iort_iommu_driver_enabled(node->type) ?
> > -		       -EPROBE_DEFER : -ENODEV;
> > -
> > -	return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
> > +	return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
> > +				      iort_iommu_driver_enabled(node->type));
> >  }
> >  
> >  struct iort_pci_alias_info {
> >  	struct device *dev;
> >  	struct acpi_iort_node *node;
> > +	struct iommu_fwspec *fwspec;
> >  };
> >  
> >  static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> > @@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> >  
> >  	parent = iort_node_map_id(info->node, alias, &streamid,
> >  				  IORT_IOMMU_TYPE);
> > -	return iort_iommu_xlate(info->dev, parent, streamid);
> > +	return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
> >  }
> >  
> >  static void iort_named_component_init(struct device *dev,
> > @@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
> >  		dev_warn(dev, "Could not add device properties\n");
> >  }
> >  
> > -static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> > +static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
> > +			     struct acpi_iort_node *node)
> >  {
> >  	struct acpi_iort_node *parent;
> >  	int err = -ENODEV, i = 0;
> > @@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> >  						   i++);
> >  
> >  		if (parent)
> > -			err = iort_iommu_xlate(dev, parent, streamid);
> > +			err = iort_iommu_xlate(fwspec, dev, parent, streamid);
> >  	} while (parent && !err);
> >  
> >  	return err;
> >  }
> >  
> > -static int iort_nc_iommu_map_id(struct device *dev,
> > +static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
> >  				struct acpi_iort_node *node,
> >  				const u32 *in_id)
> >  {
> > @@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
> >  
> >  	parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
> >  	if (parent)
> > -		return iort_iommu_xlate(dev, parent, streamid);
> > +		return iort_iommu_xlate(fwspec, dev, parent, streamid);
> >  
> >  	return -ENODEV;
> >  }
> > @@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
> >   *
> >   * Returns: 0 on success, <0 on failure
> >   */
> > -int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> > +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> > +			    const u32 *id_in)
> >  {
> >  	struct acpi_iort_node *node;
> >  	int err = -ENODEV;
> >  
> >  	if (dev_is_pci(dev)) {
> > -		struct iommu_fwspec *fwspec;
> >  		struct pci_bus *bus = to_pci_dev(dev)->bus;
> > -		struct iort_pci_alias_info info = { .dev = dev };
> > +		struct iort_pci_alias_info info = { .dev = dev,
> > +						    .fwspec = fwspec };
> >  
> >  		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
> >  				      iort_match_node_callback, &bus->dev);
> > @@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> >  		err = pci_for_each_dma_alias(to_pci_dev(dev),
> >  					     iort_pci_iommu_init, &info);
> >  
> > -		fwspec = dev_iommu_fwspec_get(dev);
> > -		if (fwspec && iort_pci_rc_supports_ats(node))
> > +		if (iort_pci_rc_supports_ats(node))
> >  			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
> >  	} else {
> >  		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> > @@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> >  		if (!node)
> >  			return -ENODEV;
> >  
> > -		err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
> > -			      iort_nc_iommu_map(dev, node);
> > +		err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
> > +			      iort_nc_iommu_map(fwspec, dev, node);
> >  
> >  		if (!err)
> >  			iort_named_component_init(dev, node);
> > diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> > index fbabde001a23a2..1e01a8e0316867 100644
> > --- a/drivers/acpi/scan.c
> > +++ b/drivers/acpi/scan.c
> > @@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
> >  }
> >  
> >  #ifdef CONFIG_IOMMU_API
> > -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> > -			   struct fwnode_handle *fwnode,
> > -			   const struct iommu_ops *ops)
> > +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> > +			   u32 id, struct fwnode_handle *fwnode,
> > +			   bool iommu_driver_available)
> >  {
> > -	int ret = iommu_fwspec_init(dev, fwnode, ops);
> > +	int ret;
> >  
> > -	if (!ret)
> > -		ret = iommu_fwspec_add_ids(dev, &id, 1);
> > -
> > -	return ret;
> > -}
> > -
> > -static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
> > -{
> > -	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> > -
> > -	return fwspec ? fwspec->ops : NULL;
> > +	ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
> > +	if (ret) {
> > +		if (ret == -EPROBE_DEFER && !iommu_driver_available)
> > +			return -ENODEV;
> > +		return ret;
> > +	}
> > +	return iommu_fwspec_append_ids(fwspec, &id, 1);
> >  }
> >  
> >  static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
> >  {
> >  	int err;
> > -	const struct iommu_ops *ops;
> > +	struct iommu_fwspec *fwspec;
> >  
> > -	/*
> > -	 * If we already translated the fwspec there is nothing left to do,
> > -	 * return the iommu_ops.
> > -	 */
> > -	ops = acpi_iommu_fwspec_ops(dev);
> > -	if (ops)
> > -		return 0;
> > +	fwspec = iommu_fwspec_alloc();
> > +	if (IS_ERR(fwspec))
> > +		return PTR_ERR(fwspec);
> >  
> > -	err = iort_iommu_configure_id(dev, id_in);
> > -	if (err && err != -EPROBE_DEFER)
> > -		err = viot_iommu_configure(dev);
> > +	err = iort_iommu_configure_id(fwspec, dev, id_in);
> > +	if (err == -ENODEV)
> > +		err = viot_iommu_configure(fwspec, dev);
> > +	if (err == -ENODEV || err == -EPROBE_DEFER)
> > +		goto err_free;
> > +	if (err)
> > +		goto err_log;
> >  
> > -	/*
> > -	 * If we have reason to believe the IOMMU driver missed the initial
> > -	 * iommu_probe_device() call for dev, replay it to get things in order.
> > -	 */
> > -	if (!err && dev->bus)
> > -		err = iommu_probe_device(dev);
> > -
> > -	/* Ignore all other errors apart from EPROBE_DEFER */
> > -	if (err == -EPROBE_DEFER) {
> > -		return err;
> > -	} else if (err) {
> > -		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> > -		return -ENODEV;
> > +	err = iommu_probe_device_fwspec(dev, fwspec);
> > +	if (err) {
> > +		/*
> > +		 * Ownership for fwspec always passes into
> > +		 * iommu_probe_device_fwspec()
> > +		 */
> > +		fwspec = NULL;
> > +		goto err_log;
> >  	}
> > -	if (!acpi_iommu_fwspec_ops(dev))
> > -		return -ENODEV;
> > -	return 0;
> > +
> > +err_log:
> > +	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> > +err_free:
> > +	iommu_fwspec_dealloc(fwspec);
> > +	return err;
> >  }
> >  
> >  #else /* !CONFIG_IOMMU_API */
> >  
> > -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> > -			   struct fwnode_handle *fwnode,
> > -			   const struct iommu_ops *ops)
> > +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> > +			   u32 id, struct fwnode_handle *fwnode,
> > +			   bool iommu_driver_available)
> >  {
> >  	return -ENODEV;
> >  }
> >  
> > -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> > -						       const u32 *id_in)
> > +static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
> >  {
> > -	return NULL;
> > +	return -ENODEV;
> >  }
> >  
> >  #endif /* !CONFIG_IOMMU_API */
> > diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
> > index c8025921c129b2..33b511dd202d15 100644
> > --- a/drivers/acpi/viot.c
> > +++ b/drivers/acpi/viot.c
> > @@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
> >  	acpi_put_table(hdr);
> >  }
> >  
> > -static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> > -			       u32 epid)
> > +static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
> > +			       struct viot_iommu *viommu, u32 epid)
> >  {
> > -	const struct iommu_ops *ops;
> > -
> >  	if (!viommu)
> >  		return -ENODEV;
> >  
> > @@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> >  	if (device_match_fwnode(dev, viommu->fwnode))
> >  		return -EINVAL;
> >  
> > -	ops = iommu_ops_from_fwnode(viommu->fwnode);
> > -	if (!ops)
> > -		return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
> > -			-EPROBE_DEFER : -ENODEV;
> > -
> > -	return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
> > +	return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
> > +				      IS_ENABLED(CONFIG_VIRTIO_IOMMU));
> >  }
> >  
> > +struct viot_pci_alias_info {
> > +	struct device *dev;
> > +	struct iommu_fwspec *fwspec;
> > +};
> > +
> >  static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
> >  {
> >  	u32 epid;
> >  	struct viot_endpoint *ep;
> > -	struct device *aliased_dev = data;
> > +	struct viot_pci_alias_info *info = data;
> >  	u32 domain_nr = pci_domain_nr(pdev->bus);
> >  
> >  	list_for_each_entry(ep, &viot_pci_ranges, list) {
> > @@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
> >  			epid = ((domain_nr - ep->segment_start) << 16) +
> >  				dev_id - ep->bdf_start + ep->endpoint_id;
> >  
> > -			return viot_dev_iommu_init(aliased_dev, ep->viommu,
> > -						   epid);
> > +			return viot_dev_iommu_init(info->fwspec, info->dev,
> > +						   ep->viommu, epid);
> >  		}
> >  	}
> >  	return -ENODEV;
> >  }
> >  
> > -static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> > +static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
> > +				    struct platform_device *pdev)
> >  {
> >  	struct resource *mem;
> >  	struct viot_endpoint *ep;
> > @@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> >  
> >  	list_for_each_entry(ep, &viot_mmio_endpoints, list) {
> >  		if (ep->address == mem->start)
> > -			return viot_dev_iommu_init(&pdev->dev, ep->viommu,
> > -						   ep->endpoint_id);
> > +			return viot_dev_iommu_init(fwspec, &pdev->dev,
> > +						   ep->viommu, ep->endpoint_id);
> >  	}
> >  	return -ENODEV;
> >  }
> > @@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> >   *
> >   * Return: 0 on success, <0 on failure
> >   */
> > -int viot_iommu_configure(struct device *dev)
> > +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
> >  {
> > -	if (dev_is_pci(dev))
> > +	if (dev_is_pci(dev)) {
> > +		struct viot_pci_alias_info info = { .dev = dev,
> > +						    .fwspec = fwspec };
> >  		return pci_for_each_dma_alias(to_pci_dev(dev),
> > -					      viot_pci_dev_iommu_init, dev);
> > +					      viot_pci_dev_iommu_init, &info);
> > +	}
> >  	else if (dev_is_platform(dev))
> > -		return viot_mmio_dev_iommu_init(to_platform_device(dev));
> > +		return viot_mmio_dev_iommu_init(fwspec,
> > +						to_platform_device(dev));
> >  	return -ENODEV;
> >  }
> > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > index 15dbe2d9eb24c2..9cfba9d12d1400 100644
> > --- a/drivers/iommu/iommu.c
> > +++ b/drivers/iommu/iommu.c
> > @@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
> >  	return ops;
> >  }
> >  
> > -static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
> > -				     struct device *dev,
> > -				     struct fwnode_handle *iommu_fwnode)
> > +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> > +			      struct fwnode_handle *iommu_fwnode)
> >  {
> >  	const struct iommu_ops *ops;
> >  
> > diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> > index 254685085c825c..70f97096c776e4 100644
> > --- a/include/acpi/acpi_bus.h
> > +++ b/include/acpi/acpi_bus.h
> > @@ -12,6 +12,8 @@
> >  #include <linux/device.h>
> >  #include <linux/property.h>
> >  
> > +struct iommu_fwspec;
> > +
> >  /* TBD: Make dynamic */
> >  #define ACPI_MAX_HANDLES	10
> >  struct acpi_handle_list {
> > @@ -625,9 +627,9 @@ struct acpi_pci_root {
> >  
> >  bool acpi_dma_supported(const struct acpi_device *adev);
> >  enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> > -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> > -			   struct fwnode_handle *fwnode,
> > -			   const struct iommu_ops *ops);
> > +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> > +			   u32 id, struct fwnode_handle *fwnode,
> > +			   bool iommu_driver_available);
> >  int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
> >  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
> >  			   const u32 *input_id);
> > diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> > index 1cb65592c95dd3..80794ec45d1693 100644
> > --- a/include/linux/acpi_iort.h
> > +++ b/include/linux/acpi_iort.h
> > @@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
> >  		       struct list_head *head);
> >  /* IOMMU interface */
> >  int iort_dma_get_ranges(struct device *dev, u64 *size);
> > -int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
> > +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> > +			    const u32 *id_in);
> >  void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
> >  phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
> >  #else
> > diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
> > index a5a12243156377..f1874cb6d43c09 100644
> > --- a/include/linux/acpi_viot.h
> > +++ b/include/linux/acpi_viot.h
> > @@ -8,11 +8,12 @@
> >  #ifdef CONFIG_ACPI_VIOT
> >  void __init acpi_viot_early_init(void);
> >  void __init acpi_viot_init(void);
> > -int viot_iommu_configure(struct device *dev);
> > +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
> >  #else
> >  static inline void acpi_viot_early_init(void) {}
> >  static inline void acpi_viot_init(void) {}
> > -static inline int viot_iommu_configure(struct device *dev)
> > +static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
> > +				       struct device *dev)
> >  {
> >  	return -ENODEV;
> >  }
> > diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> > index c5a5e2b5e2cc2a..27e4605d498850 100644
> > --- a/include/linux/iommu.h
> > +++ b/include/linux/iommu.h
> > @@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
> >  int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> >  			  struct fwnode_handle *iommu_fwnode,
> >  			  struct of_phandle_args *iommu_spec);
> > +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> > +			      struct fwnode_handle *iommu_fwnode);
> >  
> >  int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
> >  		      const struct iommu_ops *ops);

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-13 22:37       ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-13 22:37 UTC (permalink / raw)
  To: Moritz Fischer
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Sun, Nov 12, 2023 at 09:44:18AM -0800, Moritz Fischer wrote:
> On Fri, Nov 03, 2023 at 01:44:55PM -0300, Jason Gunthorpe wrote:
> > This call chain is using dev->iommu->fwspec to pass around the fwspec
> > between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
> > iommu_probe_device()).
> > 
> > However there is no locking around the accesses to dev->iommu, so this is
> > all racy.
> > 
> > Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
> Nit: s/acpu_iommu_configure/acpi_iommu_configure_id() ?

Yep

Thanks
Jason

> > pass it through all functions on the stack to fill it with data, and
> > finally pass it into iommu_probe_device_fwspec() which will load it into
> > dev->iommu under a lock.
> > 
> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> 
> Reviewed-by: Moritz Fischer <mdf@kernel.org>
> > ---
> >  drivers/acpi/arm64/iort.c | 39 ++++++++---------
> >  drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
> >  drivers/acpi/viot.c       | 44 ++++++++++---------
> >  drivers/iommu/iommu.c     |  5 +--
> >  include/acpi/acpi_bus.h   |  8 ++--
> >  include/linux/acpi_iort.h |  3 +-
> >  include/linux/acpi_viot.h |  5 ++-
> >  include/linux/iommu.h     |  2 +
> >  8 files changed, 97 insertions(+), 98 deletions(-)
> > 
> > diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> > index 6496ff5a6ba20d..accd01dcfe93f5 100644
> > --- a/drivers/acpi/arm64/iort.c
> > +++ b/drivers/acpi/arm64/iort.c
> > @@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
> >  	return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
> >  }
> >  
> > -static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> > -			    u32 streamid)
> > +static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> > +			    struct acpi_iort_node *node, u32 streamid)
> >  {
> > -	const struct iommu_ops *ops;
> >  	struct fwnode_handle *iort_fwnode;
> >  
> >  	if (!node)
> > @@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> >  	 * in the kernel or not, defer the IOMMU configuration
> >  	 * or just abort it.
> >  	 */
> > -	ops = iommu_ops_from_fwnode(iort_fwnode);
> > -	if (!ops)
> > -		return iort_iommu_driver_enabled(node->type) ?
> > -		       -EPROBE_DEFER : -ENODEV;
> > -
> > -	return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
> > +	return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
> > +				      iort_iommu_driver_enabled(node->type));
> >  }
> >  
> >  struct iort_pci_alias_info {
> >  	struct device *dev;
> >  	struct acpi_iort_node *node;
> > +	struct iommu_fwspec *fwspec;
> >  };
> >  
> >  static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> > @@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> >  
> >  	parent = iort_node_map_id(info->node, alias, &streamid,
> >  				  IORT_IOMMU_TYPE);
> > -	return iort_iommu_xlate(info->dev, parent, streamid);
> > +	return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
> >  }
> >  
> >  static void iort_named_component_init(struct device *dev,
> > @@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
> >  		dev_warn(dev, "Could not add device properties\n");
> >  }
> >  
> > -static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> > +static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
> > +			     struct acpi_iort_node *node)
> >  {
> >  	struct acpi_iort_node *parent;
> >  	int err = -ENODEV, i = 0;
> > @@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> >  						   i++);
> >  
> >  		if (parent)
> > -			err = iort_iommu_xlate(dev, parent, streamid);
> > +			err = iort_iommu_xlate(fwspec, dev, parent, streamid);
> >  	} while (parent && !err);
> >  
> >  	return err;
> >  }
> >  
> > -static int iort_nc_iommu_map_id(struct device *dev,
> > +static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
> >  				struct acpi_iort_node *node,
> >  				const u32 *in_id)
> >  {
> > @@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
> >  
> >  	parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
> >  	if (parent)
> > -		return iort_iommu_xlate(dev, parent, streamid);
> > +		return iort_iommu_xlate(fwspec, dev, parent, streamid);
> >  
> >  	return -ENODEV;
> >  }
> > @@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
> >   *
> >   * Returns: 0 on success, <0 on failure
> >   */
> > -int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> > +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> > +			    const u32 *id_in)
> >  {
> >  	struct acpi_iort_node *node;
> >  	int err = -ENODEV;
> >  
> >  	if (dev_is_pci(dev)) {
> > -		struct iommu_fwspec *fwspec;
> >  		struct pci_bus *bus = to_pci_dev(dev)->bus;
> > -		struct iort_pci_alias_info info = { .dev = dev };
> > +		struct iort_pci_alias_info info = { .dev = dev,
> > +						    .fwspec = fwspec };
> >  
> >  		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
> >  				      iort_match_node_callback, &bus->dev);
> > @@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> >  		err = pci_for_each_dma_alias(to_pci_dev(dev),
> >  					     iort_pci_iommu_init, &info);
> >  
> > -		fwspec = dev_iommu_fwspec_get(dev);
> > -		if (fwspec && iort_pci_rc_supports_ats(node))
> > +		if (iort_pci_rc_supports_ats(node))
> >  			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
> >  	} else {
> >  		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> > @@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> >  		if (!node)
> >  			return -ENODEV;
> >  
> > -		err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
> > -			      iort_nc_iommu_map(dev, node);
> > +		err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
> > +			      iort_nc_iommu_map(fwspec, dev, node);
> >  
> >  		if (!err)
> >  			iort_named_component_init(dev, node);
> > diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> > index fbabde001a23a2..1e01a8e0316867 100644
> > --- a/drivers/acpi/scan.c
> > +++ b/drivers/acpi/scan.c
> > @@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
> >  }
> >  
> >  #ifdef CONFIG_IOMMU_API
> > -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> > -			   struct fwnode_handle *fwnode,
> > -			   const struct iommu_ops *ops)
> > +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> > +			   u32 id, struct fwnode_handle *fwnode,
> > +			   bool iommu_driver_available)
> >  {
> > -	int ret = iommu_fwspec_init(dev, fwnode, ops);
> > +	int ret;
> >  
> > -	if (!ret)
> > -		ret = iommu_fwspec_add_ids(dev, &id, 1);
> > -
> > -	return ret;
> > -}
> > -
> > -static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
> > -{
> > -	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> > -
> > -	return fwspec ? fwspec->ops : NULL;
> > +	ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
> > +	if (ret) {
> > +		if (ret == -EPROBE_DEFER && !iommu_driver_available)
> > +			return -ENODEV;
> > +		return ret;
> > +	}
> > +	return iommu_fwspec_append_ids(fwspec, &id, 1);
> >  }
> >  
> >  static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
> >  {
> >  	int err;
> > -	const struct iommu_ops *ops;
> > +	struct iommu_fwspec *fwspec;
> >  
> > -	/*
> > -	 * If we already translated the fwspec there is nothing left to do,
> > -	 * return the iommu_ops.
> > -	 */
> > -	ops = acpi_iommu_fwspec_ops(dev);
> > -	if (ops)
> > -		return 0;
> > +	fwspec = iommu_fwspec_alloc();
> > +	if (IS_ERR(fwspec))
> > +		return PTR_ERR(fwspec);
> >  
> > -	err = iort_iommu_configure_id(dev, id_in);
> > -	if (err && err != -EPROBE_DEFER)
> > -		err = viot_iommu_configure(dev);
> > +	err = iort_iommu_configure_id(fwspec, dev, id_in);
> > +	if (err == -ENODEV)
> > +		err = viot_iommu_configure(fwspec, dev);
> > +	if (err == -ENODEV || err == -EPROBE_DEFER)
> > +		goto err_free;
> > +	if (err)
> > +		goto err_log;
> >  
> > -	/*
> > -	 * If we have reason to believe the IOMMU driver missed the initial
> > -	 * iommu_probe_device() call for dev, replay it to get things in order.
> > -	 */
> > -	if (!err && dev->bus)
> > -		err = iommu_probe_device(dev);
> > -
> > -	/* Ignore all other errors apart from EPROBE_DEFER */
> > -	if (err == -EPROBE_DEFER) {
> > -		return err;
> > -	} else if (err) {
> > -		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> > -		return -ENODEV;
> > +	err = iommu_probe_device_fwspec(dev, fwspec);
> > +	if (err) {
> > +		/*
> > +		 * Ownership for fwspec always passes into
> > +		 * iommu_probe_device_fwspec()
> > +		 */
> > +		fwspec = NULL;
> > +		goto err_log;
> >  	}
> > -	if (!acpi_iommu_fwspec_ops(dev))
> > -		return -ENODEV;
> > -	return 0;
> > +
> > +err_log:
> > +	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> > +err_free:
> > +	iommu_fwspec_dealloc(fwspec);
> > +	return err;
> >  }
> >  
> >  #else /* !CONFIG_IOMMU_API */
> >  
> > -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> > -			   struct fwnode_handle *fwnode,
> > -			   const struct iommu_ops *ops)
> > +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> > +			   u32 id, struct fwnode_handle *fwnode,
> > +			   bool iommu_driver_available)
> >  {
> >  	return -ENODEV;
> >  }
> >  
> > -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> > -						       const u32 *id_in)
> > +static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
> >  {
> > -	return NULL;
> > +	return -ENODEV;
> >  }
> >  
> >  #endif /* !CONFIG_IOMMU_API */
> > diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
> > index c8025921c129b2..33b511dd202d15 100644
> > --- a/drivers/acpi/viot.c
> > +++ b/drivers/acpi/viot.c
> > @@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
> >  	acpi_put_table(hdr);
> >  }
> >  
> > -static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> > -			       u32 epid)
> > +static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
> > +			       struct viot_iommu *viommu, u32 epid)
> >  {
> > -	const struct iommu_ops *ops;
> > -
> >  	if (!viommu)
> >  		return -ENODEV;
> >  
> > @@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> >  	if (device_match_fwnode(dev, viommu->fwnode))
> >  		return -EINVAL;
> >  
> > -	ops = iommu_ops_from_fwnode(viommu->fwnode);
> > -	if (!ops)
> > -		return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
> > -			-EPROBE_DEFER : -ENODEV;
> > -
> > -	return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
> > +	return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
> > +				      IS_ENABLED(CONFIG_VIRTIO_IOMMU));
> >  }
> >  
> > +struct viot_pci_alias_info {
> > +	struct device *dev;
> > +	struct iommu_fwspec *fwspec;
> > +};
> > +
> >  static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
> >  {
> >  	u32 epid;
> >  	struct viot_endpoint *ep;
> > -	struct device *aliased_dev = data;
> > +	struct viot_pci_alias_info *info = data;
> >  	u32 domain_nr = pci_domain_nr(pdev->bus);
> >  
> >  	list_for_each_entry(ep, &viot_pci_ranges, list) {
> > @@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
> >  			epid = ((domain_nr - ep->segment_start) << 16) +
> >  				dev_id - ep->bdf_start + ep->endpoint_id;
> >  
> > -			return viot_dev_iommu_init(aliased_dev, ep->viommu,
> > -						   epid);
> > +			return viot_dev_iommu_init(info->fwspec, info->dev,
> > +						   ep->viommu, epid);
> >  		}
> >  	}
> >  	return -ENODEV;
> >  }
> >  
> > -static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> > +static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
> > +				    struct platform_device *pdev)
> >  {
> >  	struct resource *mem;
> >  	struct viot_endpoint *ep;
> > @@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> >  
> >  	list_for_each_entry(ep, &viot_mmio_endpoints, list) {
> >  		if (ep->address == mem->start)
> > -			return viot_dev_iommu_init(&pdev->dev, ep->viommu,
> > -						   ep->endpoint_id);
> > +			return viot_dev_iommu_init(fwspec, &pdev->dev,
> > +						   ep->viommu, ep->endpoint_id);
> >  	}
> >  	return -ENODEV;
> >  }
> > @@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> >   *
> >   * Return: 0 on success, <0 on failure
> >   */
> > -int viot_iommu_configure(struct device *dev)
> > +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
> >  {
> > -	if (dev_is_pci(dev))
> > +	if (dev_is_pci(dev)) {
> > +		struct viot_pci_alias_info info = { .dev = dev,
> > +						    .fwspec = fwspec };
> >  		return pci_for_each_dma_alias(to_pci_dev(dev),
> > -					      viot_pci_dev_iommu_init, dev);
> > +					      viot_pci_dev_iommu_init, &info);
> > +	}
> >  	else if (dev_is_platform(dev))
> > -		return viot_mmio_dev_iommu_init(to_platform_device(dev));
> > +		return viot_mmio_dev_iommu_init(fwspec,
> > +						to_platform_device(dev));
> >  	return -ENODEV;
> >  }
> > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > index 15dbe2d9eb24c2..9cfba9d12d1400 100644
> > --- a/drivers/iommu/iommu.c
> > +++ b/drivers/iommu/iommu.c
> > @@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
> >  	return ops;
> >  }
> >  
> > -static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
> > -				     struct device *dev,
> > -				     struct fwnode_handle *iommu_fwnode)
> > +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> > +			      struct fwnode_handle *iommu_fwnode)
> >  {
> >  	const struct iommu_ops *ops;
> >  
> > diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> > index 254685085c825c..70f97096c776e4 100644
> > --- a/include/acpi/acpi_bus.h
> > +++ b/include/acpi/acpi_bus.h
> > @@ -12,6 +12,8 @@
> >  #include <linux/device.h>
> >  #include <linux/property.h>
> >  
> > +struct iommu_fwspec;
> > +
> >  /* TBD: Make dynamic */
> >  #define ACPI_MAX_HANDLES	10
> >  struct acpi_handle_list {
> > @@ -625,9 +627,9 @@ struct acpi_pci_root {
> >  
> >  bool acpi_dma_supported(const struct acpi_device *adev);
> >  enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> > -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> > -			   struct fwnode_handle *fwnode,
> > -			   const struct iommu_ops *ops);
> > +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> > +			   u32 id, struct fwnode_handle *fwnode,
> > +			   bool iommu_driver_available);
> >  int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
> >  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
> >  			   const u32 *input_id);
> > diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> > index 1cb65592c95dd3..80794ec45d1693 100644
> > --- a/include/linux/acpi_iort.h
> > +++ b/include/linux/acpi_iort.h
> > @@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
> >  		       struct list_head *head);
> >  /* IOMMU interface */
> >  int iort_dma_get_ranges(struct device *dev, u64 *size);
> > -int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
> > +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> > +			    const u32 *id_in);
> >  void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
> >  phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
> >  #else
> > diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
> > index a5a12243156377..f1874cb6d43c09 100644
> > --- a/include/linux/acpi_viot.h
> > +++ b/include/linux/acpi_viot.h
> > @@ -8,11 +8,12 @@
> >  #ifdef CONFIG_ACPI_VIOT
> >  void __init acpi_viot_early_init(void);
> >  void __init acpi_viot_init(void);
> > -int viot_iommu_configure(struct device *dev);
> > +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
> >  #else
> >  static inline void acpi_viot_early_init(void) {}
> >  static inline void acpi_viot_init(void) {}
> > -static inline int viot_iommu_configure(struct device *dev)
> > +static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
> > +				       struct device *dev)
> >  {
> >  	return -ENODEV;
> >  }
> > diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> > index c5a5e2b5e2cc2a..27e4605d498850 100644
> > --- a/include/linux/iommu.h
> > +++ b/include/linux/iommu.h
> > @@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
> >  int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> >  			  struct fwnode_handle *iommu_fwnode,
> >  			  struct of_phandle_args *iommu_spec);
> > +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> > +			      struct fwnode_handle *iommu_fwnode);
> >  
> >  int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
> >  		      const struct iommu_ops *ops);

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-13 22:37       ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-13 22:37 UTC (permalink / raw)
  To: Moritz Fischer
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Sun, Nov 12, 2023 at 09:44:18AM -0800, Moritz Fischer wrote:
> On Fri, Nov 03, 2023 at 01:44:55PM -0300, Jason Gunthorpe wrote:
> > This call chain is using dev->iommu->fwspec to pass around the fwspec
> > between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
> > iommu_probe_device()).
> > 
> > However there is no locking around the accesses to dev->iommu, so this is
> > all racy.
> > 
> > Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
> Nit: s/acpu_iommu_configure/acpi_iommu_configure_id() ?

Yep

Thanks
Jason

> > pass it through all functions on the stack to fill it with data, and
> > finally pass it into iommu_probe_device_fwspec() which will load it into
> > dev->iommu under a lock.
> > 
> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> 
> Reviewed-by: Moritz Fischer <mdf@kernel.org>
> > ---
> >  drivers/acpi/arm64/iort.c | 39 ++++++++---------
> >  drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
> >  drivers/acpi/viot.c       | 44 ++++++++++---------
> >  drivers/iommu/iommu.c     |  5 +--
> >  include/acpi/acpi_bus.h   |  8 ++--
> >  include/linux/acpi_iort.h |  3 +-
> >  include/linux/acpi_viot.h |  5 ++-
> >  include/linux/iommu.h     |  2 +
> >  8 files changed, 97 insertions(+), 98 deletions(-)
> > 
> > diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> > index 6496ff5a6ba20d..accd01dcfe93f5 100644
> > --- a/drivers/acpi/arm64/iort.c
> > +++ b/drivers/acpi/arm64/iort.c
> > @@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
> >  	return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
> >  }
> >  
> > -static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> > -			    u32 streamid)
> > +static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> > +			    struct acpi_iort_node *node, u32 streamid)
> >  {
> > -	const struct iommu_ops *ops;
> >  	struct fwnode_handle *iort_fwnode;
> >  
> >  	if (!node)
> > @@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> >  	 * in the kernel or not, defer the IOMMU configuration
> >  	 * or just abort it.
> >  	 */
> > -	ops = iommu_ops_from_fwnode(iort_fwnode);
> > -	if (!ops)
> > -		return iort_iommu_driver_enabled(node->type) ?
> > -		       -EPROBE_DEFER : -ENODEV;
> > -
> > -	return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
> > +	return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
> > +				      iort_iommu_driver_enabled(node->type));
> >  }
> >  
> >  struct iort_pci_alias_info {
> >  	struct device *dev;
> >  	struct acpi_iort_node *node;
> > +	struct iommu_fwspec *fwspec;
> >  };
> >  
> >  static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> > @@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> >  
> >  	parent = iort_node_map_id(info->node, alias, &streamid,
> >  				  IORT_IOMMU_TYPE);
> > -	return iort_iommu_xlate(info->dev, parent, streamid);
> > +	return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
> >  }
> >  
> >  static void iort_named_component_init(struct device *dev,
> > @@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
> >  		dev_warn(dev, "Could not add device properties\n");
> >  }
> >  
> > -static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> > +static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
> > +			     struct acpi_iort_node *node)
> >  {
> >  	struct acpi_iort_node *parent;
> >  	int err = -ENODEV, i = 0;
> > @@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> >  						   i++);
> >  
> >  		if (parent)
> > -			err = iort_iommu_xlate(dev, parent, streamid);
> > +			err = iort_iommu_xlate(fwspec, dev, parent, streamid);
> >  	} while (parent && !err);
> >  
> >  	return err;
> >  }
> >  
> > -static int iort_nc_iommu_map_id(struct device *dev,
> > +static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
> >  				struct acpi_iort_node *node,
> >  				const u32 *in_id)
> >  {
> > @@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
> >  
> >  	parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
> >  	if (parent)
> > -		return iort_iommu_xlate(dev, parent, streamid);
> > +		return iort_iommu_xlate(fwspec, dev, parent, streamid);
> >  
> >  	return -ENODEV;
> >  }
> > @@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
> >   *
> >   * Returns: 0 on success, <0 on failure
> >   */
> > -int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> > +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> > +			    const u32 *id_in)
> >  {
> >  	struct acpi_iort_node *node;
> >  	int err = -ENODEV;
> >  
> >  	if (dev_is_pci(dev)) {
> > -		struct iommu_fwspec *fwspec;
> >  		struct pci_bus *bus = to_pci_dev(dev)->bus;
> > -		struct iort_pci_alias_info info = { .dev = dev };
> > +		struct iort_pci_alias_info info = { .dev = dev,
> > +						    .fwspec = fwspec };
> >  
> >  		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
> >  				      iort_match_node_callback, &bus->dev);
> > @@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> >  		err = pci_for_each_dma_alias(to_pci_dev(dev),
> >  					     iort_pci_iommu_init, &info);
> >  
> > -		fwspec = dev_iommu_fwspec_get(dev);
> > -		if (fwspec && iort_pci_rc_supports_ats(node))
> > +		if (iort_pci_rc_supports_ats(node))
> >  			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
> >  	} else {
> >  		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> > @@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> >  		if (!node)
> >  			return -ENODEV;
> >  
> > -		err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
> > -			      iort_nc_iommu_map(dev, node);
> > +		err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
> > +			      iort_nc_iommu_map(fwspec, dev, node);
> >  
> >  		if (!err)
> >  			iort_named_component_init(dev, node);
> > diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> > index fbabde001a23a2..1e01a8e0316867 100644
> > --- a/drivers/acpi/scan.c
> > +++ b/drivers/acpi/scan.c
> > @@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
> >  }
> >  
> >  #ifdef CONFIG_IOMMU_API
> > -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> > -			   struct fwnode_handle *fwnode,
> > -			   const struct iommu_ops *ops)
> > +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> > +			   u32 id, struct fwnode_handle *fwnode,
> > +			   bool iommu_driver_available)
> >  {
> > -	int ret = iommu_fwspec_init(dev, fwnode, ops);
> > +	int ret;
> >  
> > -	if (!ret)
> > -		ret = iommu_fwspec_add_ids(dev, &id, 1);
> > -
> > -	return ret;
> > -}
> > -
> > -static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
> > -{
> > -	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> > -
> > -	return fwspec ? fwspec->ops : NULL;
> > +	ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
> > +	if (ret) {
> > +		if (ret == -EPROBE_DEFER && !iommu_driver_available)
> > +			return -ENODEV;
> > +		return ret;
> > +	}
> > +	return iommu_fwspec_append_ids(fwspec, &id, 1);
> >  }
> >  
> >  static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
> >  {
> >  	int err;
> > -	const struct iommu_ops *ops;
> > +	struct iommu_fwspec *fwspec;
> >  
> > -	/*
> > -	 * If we already translated the fwspec there is nothing left to do,
> > -	 * return the iommu_ops.
> > -	 */
> > -	ops = acpi_iommu_fwspec_ops(dev);
> > -	if (ops)
> > -		return 0;
> > +	fwspec = iommu_fwspec_alloc();
> > +	if (IS_ERR(fwspec))
> > +		return PTR_ERR(fwspec);
> >  
> > -	err = iort_iommu_configure_id(dev, id_in);
> > -	if (err && err != -EPROBE_DEFER)
> > -		err = viot_iommu_configure(dev);
> > +	err = iort_iommu_configure_id(fwspec, dev, id_in);
> > +	if (err == -ENODEV)
> > +		err = viot_iommu_configure(fwspec, dev);
> > +	if (err == -ENODEV || err == -EPROBE_DEFER)
> > +		goto err_free;
> > +	if (err)
> > +		goto err_log;
> >  
> > -	/*
> > -	 * If we have reason to believe the IOMMU driver missed the initial
> > -	 * iommu_probe_device() call for dev, replay it to get things in order.
> > -	 */
> > -	if (!err && dev->bus)
> > -		err = iommu_probe_device(dev);
> > -
> > -	/* Ignore all other errors apart from EPROBE_DEFER */
> > -	if (err == -EPROBE_DEFER) {
> > -		return err;
> > -	} else if (err) {
> > -		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> > -		return -ENODEV;
> > +	err = iommu_probe_device_fwspec(dev, fwspec);
> > +	if (err) {
> > +		/*
> > +		 * Ownership for fwspec always passes into
> > +		 * iommu_probe_device_fwspec()
> > +		 */
> > +		fwspec = NULL;
> > +		goto err_log;
> >  	}
> > -	if (!acpi_iommu_fwspec_ops(dev))
> > -		return -ENODEV;
> > -	return 0;
> > +
> > +err_log:
> > +	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> > +err_free:
> > +	iommu_fwspec_dealloc(fwspec);
> > +	return err;
> >  }
> >  
> >  #else /* !CONFIG_IOMMU_API */
> >  
> > -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> > -			   struct fwnode_handle *fwnode,
> > -			   const struct iommu_ops *ops)
> > +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> > +			   u32 id, struct fwnode_handle *fwnode,
> > +			   bool iommu_driver_available)
> >  {
> >  	return -ENODEV;
> >  }
> >  
> > -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> > -						       const u32 *id_in)
> > +static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
> >  {
> > -	return NULL;
> > +	return -ENODEV;
> >  }
> >  
> >  #endif /* !CONFIG_IOMMU_API */
> > diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
> > index c8025921c129b2..33b511dd202d15 100644
> > --- a/drivers/acpi/viot.c
> > +++ b/drivers/acpi/viot.c
> > @@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
> >  	acpi_put_table(hdr);
> >  }
> >  
> > -static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> > -			       u32 epid)
> > +static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
> > +			       struct viot_iommu *viommu, u32 epid)
> >  {
> > -	const struct iommu_ops *ops;
> > -
> >  	if (!viommu)
> >  		return -ENODEV;
> >  
> > @@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> >  	if (device_match_fwnode(dev, viommu->fwnode))
> >  		return -EINVAL;
> >  
> > -	ops = iommu_ops_from_fwnode(viommu->fwnode);
> > -	if (!ops)
> > -		return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
> > -			-EPROBE_DEFER : -ENODEV;
> > -
> > -	return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
> > +	return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
> > +				      IS_ENABLED(CONFIG_VIRTIO_IOMMU));
> >  }
> >  
> > +struct viot_pci_alias_info {
> > +	struct device *dev;
> > +	struct iommu_fwspec *fwspec;
> > +};
> > +
> >  static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
> >  {
> >  	u32 epid;
> >  	struct viot_endpoint *ep;
> > -	struct device *aliased_dev = data;
> > +	struct viot_pci_alias_info *info = data;
> >  	u32 domain_nr = pci_domain_nr(pdev->bus);
> >  
> >  	list_for_each_entry(ep, &viot_pci_ranges, list) {
> > @@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
> >  			epid = ((domain_nr - ep->segment_start) << 16) +
> >  				dev_id - ep->bdf_start + ep->endpoint_id;
> >  
> > -			return viot_dev_iommu_init(aliased_dev, ep->viommu,
> > -						   epid);
> > +			return viot_dev_iommu_init(info->fwspec, info->dev,
> > +						   ep->viommu, epid);
> >  		}
> >  	}
> >  	return -ENODEV;
> >  }
> >  
> > -static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> > +static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
> > +				    struct platform_device *pdev)
> >  {
> >  	struct resource *mem;
> >  	struct viot_endpoint *ep;
> > @@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> >  
> >  	list_for_each_entry(ep, &viot_mmio_endpoints, list) {
> >  		if (ep->address == mem->start)
> > -			return viot_dev_iommu_init(&pdev->dev, ep->viommu,
> > -						   ep->endpoint_id);
> > +			return viot_dev_iommu_init(fwspec, &pdev->dev,
> > +						   ep->viommu, ep->endpoint_id);
> >  	}
> >  	return -ENODEV;
> >  }
> > @@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> >   *
> >   * Return: 0 on success, <0 on failure
> >   */
> > -int viot_iommu_configure(struct device *dev)
> > +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
> >  {
> > -	if (dev_is_pci(dev))
> > +	if (dev_is_pci(dev)) {
> > +		struct viot_pci_alias_info info = { .dev = dev,
> > +						    .fwspec = fwspec };
> >  		return pci_for_each_dma_alias(to_pci_dev(dev),
> > -					      viot_pci_dev_iommu_init, dev);
> > +					      viot_pci_dev_iommu_init, &info);
> > +	}
> >  	else if (dev_is_platform(dev))
> > -		return viot_mmio_dev_iommu_init(to_platform_device(dev));
> > +		return viot_mmio_dev_iommu_init(fwspec,
> > +						to_platform_device(dev));
> >  	return -ENODEV;
> >  }
> > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > index 15dbe2d9eb24c2..9cfba9d12d1400 100644
> > --- a/drivers/iommu/iommu.c
> > +++ b/drivers/iommu/iommu.c
> > @@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
> >  	return ops;
> >  }
> >  
> > -static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
> > -				     struct device *dev,
> > -				     struct fwnode_handle *iommu_fwnode)
> > +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> > +			      struct fwnode_handle *iommu_fwnode)
> >  {
> >  	const struct iommu_ops *ops;
> >  
> > diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> > index 254685085c825c..70f97096c776e4 100644
> > --- a/include/acpi/acpi_bus.h
> > +++ b/include/acpi/acpi_bus.h
> > @@ -12,6 +12,8 @@
> >  #include <linux/device.h>
> >  #include <linux/property.h>
> >  
> > +struct iommu_fwspec;
> > +
> >  /* TBD: Make dynamic */
> >  #define ACPI_MAX_HANDLES	10
> >  struct acpi_handle_list {
> > @@ -625,9 +627,9 @@ struct acpi_pci_root {
> >  
> >  bool acpi_dma_supported(const struct acpi_device *adev);
> >  enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> > -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> > -			   struct fwnode_handle *fwnode,
> > -			   const struct iommu_ops *ops);
> > +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> > +			   u32 id, struct fwnode_handle *fwnode,
> > +			   bool iommu_driver_available);
> >  int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
> >  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
> >  			   const u32 *input_id);
> > diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> > index 1cb65592c95dd3..80794ec45d1693 100644
> > --- a/include/linux/acpi_iort.h
> > +++ b/include/linux/acpi_iort.h
> > @@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
> >  		       struct list_head *head);
> >  /* IOMMU interface */
> >  int iort_dma_get_ranges(struct device *dev, u64 *size);
> > -int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
> > +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> > +			    const u32 *id_in);
> >  void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
> >  phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
> >  #else
> > diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
> > index a5a12243156377..f1874cb6d43c09 100644
> > --- a/include/linux/acpi_viot.h
> > +++ b/include/linux/acpi_viot.h
> > @@ -8,11 +8,12 @@
> >  #ifdef CONFIG_ACPI_VIOT
> >  void __init acpi_viot_early_init(void);
> >  void __init acpi_viot_init(void);
> > -int viot_iommu_configure(struct device *dev);
> > +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
> >  #else
> >  static inline void acpi_viot_early_init(void) {}
> >  static inline void acpi_viot_init(void) {}
> > -static inline int viot_iommu_configure(struct device *dev)
> > +static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
> > +				       struct device *dev)
> >  {
> >  	return -ENODEV;
> >  }
> > diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> > index c5a5e2b5e2cc2a..27e4605d498850 100644
> > --- a/include/linux/iommu.h
> > +++ b/include/linux/iommu.h
> > @@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
> >  int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> >  			  struct fwnode_handle *iommu_fwnode,
> >  			  struct of_phandle_args *iommu_spec);
> > +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> > +			      struct fwnode_handle *iommu_fwnode);
> >  
> >  int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
> >  		      const struct iommu_ops *ops);

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure()
@ 2023-11-13 22:37       ` Jason Gunthorpe
  0 siblings, 0 replies; 242+ messages in thread
From: Jason Gunthorpe @ 2023-11-13 22:37 UTC (permalink / raw)
  To: Moritz Fischer
  Cc: acpica-devel, Alyssa Rosenzweig, Albert Ou, asahi, Lu Baolu,
	Catalin Marinas, Dexuan Cui, devicetree, David Woodhouse,
	Frank Rowand, Hanjun Guo, Haiyang Zhang, Christoph Hellwig,
	iommu, Jean-Philippe Brucker, Jonathan Hunter, Joerg Roedel,
	K. Y. Srinivasan, Len Brown, linux-acpi, linux-arm-kernel,
	linux-hyperv, linux-mips, linux-riscv, linux-snps-arc,
	linux-tegra, Russell King, Lorenzo Pieralisi, Marek Szyprowski,
	Hector Martin, Palmer Dabbelt, Paul Walmsley, Rafael J. Wysocki,
	Robert Moore, Rob Herring, Robin Murphy, Sudeep Holla,
	Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon, Zhenhua Huang

On Sun, Nov 12, 2023 at 09:44:18AM -0800, Moritz Fischer wrote:
> On Fri, Nov 03, 2023 at 01:44:55PM -0300, Jason Gunthorpe wrote:
> > This call chain is using dev->iommu->fwspec to pass around the fwspec
> > between the three parts (acpi_iommu_configure(), acpi_iommu_fwspec_init(),
> > iommu_probe_device()).
> > 
> > However there is no locking around the accesses to dev->iommu, so this is
> > all racy.
> > 
> > Allocate a clean, local, fwspec at the start of acpu_iommu_configure(),
> Nit: s/acpu_iommu_configure/acpi_iommu_configure_id() ?

Yep

Thanks
Jason

> > pass it through all functions on the stack to fill it with data, and
> > finally pass it into iommu_probe_device_fwspec() which will load it into
> > dev->iommu under a lock.
> > 
> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> 
> Reviewed-by: Moritz Fischer <mdf@kernel.org>
> > ---
> >  drivers/acpi/arm64/iort.c | 39 ++++++++---------
> >  drivers/acpi/scan.c       | 89 ++++++++++++++++++---------------------
> >  drivers/acpi/viot.c       | 44 ++++++++++---------
> >  drivers/iommu/iommu.c     |  5 +--
> >  include/acpi/acpi_bus.h   |  8 ++--
> >  include/linux/acpi_iort.h |  3 +-
> >  include/linux/acpi_viot.h |  5 ++-
> >  include/linux/iommu.h     |  2 +
> >  8 files changed, 97 insertions(+), 98 deletions(-)
> > 
> > diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> > index 6496ff5a6ba20d..accd01dcfe93f5 100644
> > --- a/drivers/acpi/arm64/iort.c
> > +++ b/drivers/acpi/arm64/iort.c
> > @@ -1218,10 +1218,9 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
> >  	return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
> >  }
> >  
> > -static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> > -			    u32 streamid)
> > +static int iort_iommu_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> > +			    struct acpi_iort_node *node, u32 streamid)
> >  {
> > -	const struct iommu_ops *ops;
> >  	struct fwnode_handle *iort_fwnode;
> >  
> >  	if (!node)
> > @@ -1239,17 +1238,14 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
> >  	 * in the kernel or not, defer the IOMMU configuration
> >  	 * or just abort it.
> >  	 */
> > -	ops = iommu_ops_from_fwnode(iort_fwnode);
> > -	if (!ops)
> > -		return iort_iommu_driver_enabled(node->type) ?
> > -		       -EPROBE_DEFER : -ENODEV;
> > -
> > -	return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
> > +	return acpi_iommu_fwspec_init(fwspec, dev, streamid, iort_fwnode,
> > +				      iort_iommu_driver_enabled(node->type));
> >  }
> >  
> >  struct iort_pci_alias_info {
> >  	struct device *dev;
> >  	struct acpi_iort_node *node;
> > +	struct iommu_fwspec *fwspec;
> >  };
> >  
> >  static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> > @@ -1260,7 +1256,7 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> >  
> >  	parent = iort_node_map_id(info->node, alias, &streamid,
> >  				  IORT_IOMMU_TYPE);
> > -	return iort_iommu_xlate(info->dev, parent, streamid);
> > +	return iort_iommu_xlate(info->fwspec, info->dev, parent, streamid);
> >  }
> >  
> >  static void iort_named_component_init(struct device *dev,
> > @@ -1280,7 +1276,8 @@ static void iort_named_component_init(struct device *dev,
> >  		dev_warn(dev, "Could not add device properties\n");
> >  }
> >  
> > -static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> > +static int iort_nc_iommu_map(struct iommu_fwspec *fwspec, struct device *dev,
> > +			     struct acpi_iort_node *node)
> >  {
> >  	struct acpi_iort_node *parent;
> >  	int err = -ENODEV, i = 0;
> > @@ -1293,13 +1290,13 @@ static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> >  						   i++);
> >  
> >  		if (parent)
> > -			err = iort_iommu_xlate(dev, parent, streamid);
> > +			err = iort_iommu_xlate(fwspec, dev, parent, streamid);
> >  	} while (parent && !err);
> >  
> >  	return err;
> >  }
> >  
> > -static int iort_nc_iommu_map_id(struct device *dev,
> > +static int iort_nc_iommu_map_id(struct iommu_fwspec *fwspec, struct device *dev,
> >  				struct acpi_iort_node *node,
> >  				const u32 *in_id)
> >  {
> > @@ -1308,7 +1305,7 @@ static int iort_nc_iommu_map_id(struct device *dev,
> >  
> >  	parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
> >  	if (parent)
> > -		return iort_iommu_xlate(dev, parent, streamid);
> > +		return iort_iommu_xlate(fwspec, dev, parent, streamid);
> >  
> >  	return -ENODEV;
> >  }
> > @@ -1322,15 +1319,16 @@ static int iort_nc_iommu_map_id(struct device *dev,
> >   *
> >   * Returns: 0 on success, <0 on failure
> >   */
> > -int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> > +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> > +			    const u32 *id_in)
> >  {
> >  	struct acpi_iort_node *node;
> >  	int err = -ENODEV;
> >  
> >  	if (dev_is_pci(dev)) {
> > -		struct iommu_fwspec *fwspec;
> >  		struct pci_bus *bus = to_pci_dev(dev)->bus;
> > -		struct iort_pci_alias_info info = { .dev = dev };
> > +		struct iort_pci_alias_info info = { .dev = dev,
> > +						    .fwspec = fwspec };
> >  
> >  		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
> >  				      iort_match_node_callback, &bus->dev);
> > @@ -1341,8 +1339,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> >  		err = pci_for_each_dma_alias(to_pci_dev(dev),
> >  					     iort_pci_iommu_init, &info);
> >  
> > -		fwspec = dev_iommu_fwspec_get(dev);
> > -		if (fwspec && iort_pci_rc_supports_ats(node))
> > +		if (iort_pci_rc_supports_ats(node))
> >  			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
> >  	} else {
> >  		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> > @@ -1350,8 +1347,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
> >  		if (!node)
> >  			return -ENODEV;
> >  
> > -		err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
> > -			      iort_nc_iommu_map(dev, node);
> > +		err = id_in ? iort_nc_iommu_map_id(fwspec, dev, node, id_in) :
> > +			      iort_nc_iommu_map(fwspec, dev, node);
> >  
> >  		if (!err)
> >  			iort_named_component_init(dev, node);
> > diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> > index fbabde001a23a2..1e01a8e0316867 100644
> > --- a/drivers/acpi/scan.c
> > +++ b/drivers/acpi/scan.c
> > @@ -1543,74 +1543,67 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
> >  }
> >  
> >  #ifdef CONFIG_IOMMU_API
> > -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> > -			   struct fwnode_handle *fwnode,
> > -			   const struct iommu_ops *ops)
> > +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> > +			   u32 id, struct fwnode_handle *fwnode,
> > +			   bool iommu_driver_available)
> >  {
> > -	int ret = iommu_fwspec_init(dev, fwnode, ops);
> > +	int ret;
> >  
> > -	if (!ret)
> > -		ret = iommu_fwspec_add_ids(dev, &id, 1);
> > -
> > -	return ret;
> > -}
> > -
> > -static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
> > -{
> > -	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> > -
> > -	return fwspec ? fwspec->ops : NULL;
> > +	ret = iommu_fwspec_assign_iommu(fwspec, dev, fwnode);
> > +	if (ret) {
> > +		if (ret == -EPROBE_DEFER && !iommu_driver_available)
> > +			return -ENODEV;
> > +		return ret;
> > +	}
> > +	return iommu_fwspec_append_ids(fwspec, &id, 1);
> >  }
> >  
> >  static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
> >  {
> >  	int err;
> > -	const struct iommu_ops *ops;
> > +	struct iommu_fwspec *fwspec;
> >  
> > -	/*
> > -	 * If we already translated the fwspec there is nothing left to do,
> > -	 * return the iommu_ops.
> > -	 */
> > -	ops = acpi_iommu_fwspec_ops(dev);
> > -	if (ops)
> > -		return 0;
> > +	fwspec = iommu_fwspec_alloc();
> > +	if (IS_ERR(fwspec))
> > +		return PTR_ERR(fwspec);
> >  
> > -	err = iort_iommu_configure_id(dev, id_in);
> > -	if (err && err != -EPROBE_DEFER)
> > -		err = viot_iommu_configure(dev);
> > +	err = iort_iommu_configure_id(fwspec, dev, id_in);
> > +	if (err == -ENODEV)
> > +		err = viot_iommu_configure(fwspec, dev);
> > +	if (err == -ENODEV || err == -EPROBE_DEFER)
> > +		goto err_free;
> > +	if (err)
> > +		goto err_log;
> >  
> > -	/*
> > -	 * If we have reason to believe the IOMMU driver missed the initial
> > -	 * iommu_probe_device() call for dev, replay it to get things in order.
> > -	 */
> > -	if (!err && dev->bus)
> > -		err = iommu_probe_device(dev);
> > -
> > -	/* Ignore all other errors apart from EPROBE_DEFER */
> > -	if (err == -EPROBE_DEFER) {
> > -		return err;
> > -	} else if (err) {
> > -		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> > -		return -ENODEV;
> > +	err = iommu_probe_device_fwspec(dev, fwspec);
> > +	if (err) {
> > +		/*
> > +		 * Ownership for fwspec always passes into
> > +		 * iommu_probe_device_fwspec()
> > +		 */
> > +		fwspec = NULL;
> > +		goto err_log;
> >  	}
> > -	if (!acpi_iommu_fwspec_ops(dev))
> > -		return -ENODEV;
> > -	return 0;
> > +
> > +err_log:
> > +	dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
> > +err_free:
> > +	iommu_fwspec_dealloc(fwspec);
> > +	return err;
> >  }
> >  
> >  #else /* !CONFIG_IOMMU_API */
> >  
> > -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> > -			   struct fwnode_handle *fwnode,
> > -			   const struct iommu_ops *ops)
> > +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> > +			   u32 id, struct fwnode_handle *fwnode,
> > +			   bool iommu_driver_available)
> >  {
> >  	return -ENODEV;
> >  }
> >  
> > -static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
> > -						       const u32 *id_in)
> > +static const int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
> >  {
> > -	return NULL;
> > +	return -ENODEV;
> >  }
> >  
> >  #endif /* !CONFIG_IOMMU_API */
> > diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
> > index c8025921c129b2..33b511dd202d15 100644
> > --- a/drivers/acpi/viot.c
> > +++ b/drivers/acpi/viot.c
> > @@ -304,11 +304,9 @@ void __init acpi_viot_init(void)
> >  	acpi_put_table(hdr);
> >  }
> >  
> > -static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> > -			       u32 epid)
> > +static int viot_dev_iommu_init(struct iommu_fwspec *fwspec, struct device *dev,
> > +			       struct viot_iommu *viommu, u32 epid)
> >  {
> > -	const struct iommu_ops *ops;
> > -
> >  	if (!viommu)
> >  		return -ENODEV;
> >  
> > @@ -316,19 +314,20 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
> >  	if (device_match_fwnode(dev, viommu->fwnode))
> >  		return -EINVAL;
> >  
> > -	ops = iommu_ops_from_fwnode(viommu->fwnode);
> > -	if (!ops)
> > -		return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
> > -			-EPROBE_DEFER : -ENODEV;
> > -
> > -	return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
> > +	return acpi_iommu_fwspec_init(fwspec, dev, epid, viommu->fwnode,
> > +				      IS_ENABLED(CONFIG_VIRTIO_IOMMU));
> >  }
> >  
> > +struct viot_pci_alias_info {
> > +	struct device *dev;
> > +	struct iommu_fwspec *fwspec;
> > +};
> > +
> >  static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
> >  {
> >  	u32 epid;
> >  	struct viot_endpoint *ep;
> > -	struct device *aliased_dev = data;
> > +	struct viot_pci_alias_info *info = data;
> >  	u32 domain_nr = pci_domain_nr(pdev->bus);
> >  
> >  	list_for_each_entry(ep, &viot_pci_ranges, list) {
> > @@ -339,14 +338,15 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
> >  			epid = ((domain_nr - ep->segment_start) << 16) +
> >  				dev_id - ep->bdf_start + ep->endpoint_id;
> >  
> > -			return viot_dev_iommu_init(aliased_dev, ep->viommu,
> > -						   epid);
> > +			return viot_dev_iommu_init(info->fwspec, info->dev,
> > +						   ep->viommu, epid);
> >  		}
> >  	}
> >  	return -ENODEV;
> >  }
> >  
> > -static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> > +static int viot_mmio_dev_iommu_init(struct iommu_fwspec *fwspec,
> > +				    struct platform_device *pdev)
> >  {
> >  	struct resource *mem;
> >  	struct viot_endpoint *ep;
> > @@ -357,8 +357,8 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> >  
> >  	list_for_each_entry(ep, &viot_mmio_endpoints, list) {
> >  		if (ep->address == mem->start)
> > -			return viot_dev_iommu_init(&pdev->dev, ep->viommu,
> > -						   ep->endpoint_id);
> > +			return viot_dev_iommu_init(fwspec, &pdev->dev,
> > +						   ep->viommu, ep->endpoint_id);
> >  	}
> >  	return -ENODEV;
> >  }
> > @@ -369,12 +369,16 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
> >   *
> >   * Return: 0 on success, <0 on failure
> >   */
> > -int viot_iommu_configure(struct device *dev)
> > +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev)
> >  {
> > -	if (dev_is_pci(dev))
> > +	if (dev_is_pci(dev)) {
> > +		struct viot_pci_alias_info info = { .dev = dev,
> > +						    .fwspec = fwspec };
> >  		return pci_for_each_dma_alias(to_pci_dev(dev),
> > -					      viot_pci_dev_iommu_init, dev);
> > +					      viot_pci_dev_iommu_init, &info);
> > +	}
> >  	else if (dev_is_platform(dev))
> > -		return viot_mmio_dev_iommu_init(to_platform_device(dev));
> > +		return viot_mmio_dev_iommu_init(fwspec,
> > +						to_platform_device(dev));
> >  	return -ENODEV;
> >  }
> > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > index 15dbe2d9eb24c2..9cfba9d12d1400 100644
> > --- a/drivers/iommu/iommu.c
> > +++ b/drivers/iommu/iommu.c
> > @@ -2960,9 +2960,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
> >  	return ops;
> >  }
> >  
> > -static int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec,
> > -				     struct device *dev,
> > -				     struct fwnode_handle *iommu_fwnode)
> > +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> > +			      struct fwnode_handle *iommu_fwnode)
> >  {
> >  	const struct iommu_ops *ops;
> >  
> > diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> > index 254685085c825c..70f97096c776e4 100644
> > --- a/include/acpi/acpi_bus.h
> > +++ b/include/acpi/acpi_bus.h
> > @@ -12,6 +12,8 @@
> >  #include <linux/device.h>
> >  #include <linux/property.h>
> >  
> > +struct iommu_fwspec;
> > +
> >  /* TBD: Make dynamic */
> >  #define ACPI_MAX_HANDLES	10
> >  struct acpi_handle_list {
> > @@ -625,9 +627,9 @@ struct acpi_pci_root {
> >  
> >  bool acpi_dma_supported(const struct acpi_device *adev);
> >  enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> > -int acpi_iommu_fwspec_init(struct device *dev, u32 id,
> > -			   struct fwnode_handle *fwnode,
> > -			   const struct iommu_ops *ops);
> > +int acpi_iommu_fwspec_init(struct iommu_fwspec *fwspec, struct device *dev,
> > +			   u32 id, struct fwnode_handle *fwnode,
> > +			   bool iommu_driver_available);
> >  int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
> >  int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
> >  			   const u32 *input_id);
> > diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> > index 1cb65592c95dd3..80794ec45d1693 100644
> > --- a/include/linux/acpi_iort.h
> > +++ b/include/linux/acpi_iort.h
> > @@ -40,7 +40,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
> >  		       struct list_head *head);
> >  /* IOMMU interface */
> >  int iort_dma_get_ranges(struct device *dev, u64 *size);
> > -int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
> > +int iort_iommu_configure_id(struct iommu_fwspec *fwspec, struct device *dev,
> > +			    const u32 *id_in);
> >  void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
> >  phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
> >  #else
> > diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
> > index a5a12243156377..f1874cb6d43c09 100644
> > --- a/include/linux/acpi_viot.h
> > +++ b/include/linux/acpi_viot.h
> > @@ -8,11 +8,12 @@
> >  #ifdef CONFIG_ACPI_VIOT
> >  void __init acpi_viot_early_init(void);
> >  void __init acpi_viot_init(void);
> > -int viot_iommu_configure(struct device *dev);
> > +int viot_iommu_configure(struct iommu_fwspec *fwspec, struct device *dev);
> >  #else
> >  static inline void acpi_viot_early_init(void) {}
> >  static inline void acpi_viot_init(void) {}
> > -static inline int viot_iommu_configure(struct device *dev)
> > +static inline int viot_iommu_configure(struct iommu_fwspec *fwspec,
> > +				       struct device *dev)
> >  {
> >  	return -ENODEV;
> >  }
> > diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> > index c5a5e2b5e2cc2a..27e4605d498850 100644
> > --- a/include/linux/iommu.h
> > +++ b/include/linux/iommu.h
> > @@ -688,6 +688,8 @@ void iommu_fwspec_dealloc(struct iommu_fwspec *fwspec);
> >  int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
> >  			  struct fwnode_handle *iommu_fwnode,
> >  			  struct of_phandle_args *iommu_spec);
> > +int iommu_fwspec_assign_iommu(struct iommu_fwspec *fwspec, struct device *dev,
> > +			      struct fwnode_handle *iommu_fwnode);
> >  
> >  int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
> >  		      const struct iommu_ops *ops);

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
  2023-11-03 16:44 ` Jason Gunthorpe
  (?)
  (?)
@ 2023-11-14  4:56   ` Zhenhua Huang
  -1 siblings, 0 replies; 242+ messages in thread
From: Zhenhua Huang @ 2023-11-14  4:56 UTC (permalink / raw)
  To: Jason Gunthorpe, acpica-devel, Alyssa Rosenzweig, Albert Ou,
	asahi, Lu Baolu, Catalin Marinas, Dexuan Cui, devicetree,
	David Woodhouse, Frank Rowand, Hanjun Guo, Haiyang Zhang,
	Christoph Hellwig, iommu, Jean-Philippe Brucker, Jonathan Hunter,
	Joerg Roedel, K. Y. Srinivasan, Len Brown, linux-acpi,
	linux-arm-kernel, linux-hyperv, linux-mips, linux-riscv,
	linux-snps-arc, linux-tegra, Russell King, Lorenzo Pieralisi,
	Marek Szyprowski, Hector Martin, Palmer Dabbelt, Paul Walmsley,
	Rafael J. Wysocki, Robert Moore, Rob Herring, Robin Murphy,
	Sudeep Holla, Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon

Thanks Jason.

On 2023/11/4 0:44, Jason Gunthorpe wrote:
> This is a more complete solution that the first attempt here:
> https://lore.kernel.org/r/1698825902-10685-1-git-send-email-quic_zhenhuah@quicinc.com
> 
> I haven't been able to test this on any HW that touches these paths, so if
> some people with HW can help get it in shape it can become non-RFC.

Thank you for addressing it quickly with a thorough way. I have 
backported it to Android common kernel 6.1 and tested basic sanity well.
I will share these to OEMs and see if they can reproduce further, thanks.

Thanks,
Zhenhua

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
@ 2023-11-14  4:56   ` Zhenhua Huang
  0 siblings, 0 replies; 242+ messages in thread
From: Zhenhua Huang @ 2023-11-14  4:56 UTC (permalink / raw)
  To: Jason Gunthorpe, acpica-devel, Alyssa Rosenzweig, Albert Ou,
	asahi, Lu Baolu, Catalin Marinas, Dexuan Cui, devicetree,
	David Woodhouse, Frank Rowand, Hanjun Guo, Haiyang Zhang,
	Christoph Hellwig, iommu, Jean-Philippe Brucker, Jonathan Hunter,
	Joerg Roedel, K. Y. Srinivasan, Len Brown, linux-acpi,
	linux-arm-kernel, linux-hyperv, linux-mips, linux-riscv,
	linux-snps-arc, linux-tegra, Russell King, Lorenzo Pieralisi,
	Marek Szyprowski, Hector Martin, Palmer Dabbelt, Paul Walmsley,
	Rafael J. Wysocki, Robert Moore, Rob Herring, Robin Murphy,
	Sudeep Holla, Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon

Thanks Jason.

On 2023/11/4 0:44, Jason Gunthorpe wrote:
> This is a more complete solution that the first attempt here:
> https://lore.kernel.org/r/1698825902-10685-1-git-send-email-quic_zhenhuah@quicinc.com
> 
> I haven't been able to test this on any HW that touches these paths, so if
> some people with HW can help get it in shape it can become non-RFC.

Thank you for addressing it quickly with a thorough way. I have 
backported it to Android common kernel 6.1 and tested basic sanity well.
I will share these to OEMs and see if they can reproduce further, thanks.

Thanks,
Zhenhua

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
@ 2023-11-14  4:56   ` Zhenhua Huang
  0 siblings, 0 replies; 242+ messages in thread
From: Zhenhua Huang @ 2023-11-14  4:56 UTC (permalink / raw)
  To: Jason Gunthorpe, acpica-devel, Alyssa Rosenzweig, Albert Ou,
	asahi, Lu Baolu, Catalin Marinas, Dexuan Cui, devicetree,
	David Woodhouse, Frank Rowand, Hanjun Guo, Haiyang Zhang,
	Christoph Hellwig, iommu, Jean-Philippe Brucker, Jonathan Hunter,
	Joerg Roedel, K. Y. Srinivasan, Len Brown, linux-acpi,
	linux-arm-kernel, linux-hyperv, linux-mips, linux-riscv,
	linux-snps-arc, linux-tegra, Russell King, Lorenzo Pieralisi,
	Marek Szyprowski, Hector Martin, Palmer Dabbelt, Paul Walmsley,
	Rafael J. Wysocki, Robert Moore, Rob Herring, Robin Murphy,
	Sudeep Holla, Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon

Thanks Jason.

On 2023/11/4 0:44, Jason Gunthorpe wrote:
> This is a more complete solution that the first attempt here:
> https://lore.kernel.org/r/1698825902-10685-1-git-send-email-quic_zhenhuah@quicinc.com
> 
> I haven't been able to test this on any HW that touches these paths, so if
> some people with HW can help get it in shape it can become non-RFC.

Thank you for addressing it quickly with a thorough way. I have 
backported it to Android common kernel 6.1 and tested basic sanity well.
I will share these to OEMs and see if they can reproduce further, thanks.

Thanks,
Zhenhua

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 242+ messages in thread

* Re: [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec
@ 2023-11-14  4:56   ` Zhenhua Huang
  0 siblings, 0 replies; 242+ messages in thread
From: Zhenhua Huang @ 2023-11-14  4:56 UTC (permalink / raw)
  To: Jason Gunthorpe, acpica-devel, Alyssa Rosenzweig, Albert Ou,
	asahi, Lu Baolu, Catalin Marinas, Dexuan Cui, devicetree,
	David Woodhouse, Frank Rowand, Hanjun Guo, Haiyang Zhang,
	Christoph Hellwig, iommu, Jean-Philippe Brucker, Jonathan Hunter,
	Joerg Roedel, K. Y. Srinivasan, Len Brown, linux-acpi,
	linux-arm-kernel, linux-hyperv, linux-mips, linux-riscv,
	linux-snps-arc, linux-tegra, Russell King, Lorenzo Pieralisi,
	Marek Szyprowski, Hector Martin, Palmer Dabbelt, Paul Walmsley,
	Rafael J. Wysocki, Robert Moore, Rob Herring, Robin Murphy,
	Sudeep Holla, Suravee Suthikulpanit, Sven Peter, Thierry Reding,
	Thomas Bogendoerfer, Krishna Reddy, Vineet Gupta, virtualization,
	Wei Liu, Will Deacon

Thanks Jason.

On 2023/11/4 0:44, Jason Gunthorpe wrote:
> This is a more complete solution that the first attempt here:
> https://lore.kernel.org/r/1698825902-10685-1-git-send-email-quic_zhenhuah@quicinc.com
> 
> I haven't been able to test this on any HW that touches these paths, so if
> some people with HW can help get it in shape it can become non-RFC.

Thank you for addressing it quickly with a thorough way. I have 
backported it to Android common kernel 6.1 and tested basic sanity well.
I will share these to OEMs and see if they can reproduce further, thanks.

Thanks,
Zhenhua

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 242+ messages in thread

end of thread, other threads:[~2023-11-14  4:58 UTC | newest]

Thread overview: 242+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-03 16:44 [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec Jason Gunthorpe
2023-11-03 16:44 ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:44 ` Jason Gunthorpe
2023-11-03 16:44 ` Jason Gunthorpe
2023-11-03 16:44 ` Jason Gunthorpe
2023-11-03 16:44 ` [PATCH RFC 01/17] iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops() Jason Gunthorpe
2023-11-03 16:44   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 20:04   ` Jerry Snitselaar
2023-11-03 20:04     ` [Acpica-devel] " Jerry Snitselaar
2023-11-03 20:04     ` Jerry Snitselaar
2023-11-03 20:04     ` Jerry Snitselaar
2023-11-03 20:04     ` Jerry Snitselaar
2023-11-06  7:17   ` Christoph Hellwig
2023-11-06  7:17     ` Christoph Hellwig
2023-11-06  7:17     ` Christoph Hellwig
2023-11-06  7:17     ` Christoph Hellwig
2023-11-06  7:17     ` Christoph Hellwig
2023-11-08  8:01   ` Baolu Lu
2023-11-08  8:01     ` Baolu Lu
2023-11-08  8:01     ` Baolu Lu
2023-11-08  8:01     ` Baolu Lu
2023-11-08 16:18   ` Rob Herring
2023-11-08 16:18     ` Rob Herring
2023-11-08 16:18     ` Rob Herring
2023-11-08 16:18     ` Rob Herring
2023-11-12 17:35   ` Moritz Fischer
2023-11-12 17:35     ` Moritz Fischer
2023-11-12 17:35     ` Moritz Fischer
2023-11-12 17:35     ` Moritz Fischer
2023-11-03 16:44 ` [PATCH RFC 02/17] of: Do not return struct iommu_ops from of_iommu_configure() Jason Gunthorpe
2023-11-03 16:44   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 21:42   ` Jerry Snitselaar
2023-11-03 21:42     ` Jerry Snitselaar
2023-11-03 21:42     ` Jerry Snitselaar
2023-11-03 21:42     ` Jerry Snitselaar
2023-11-03 21:47     ` Jerry Snitselaar
2023-11-03 21:47       ` Jerry Snitselaar
2023-11-03 21:47       ` Jerry Snitselaar
2023-11-03 21:47       ` Jerry Snitselaar
2023-11-05 13:31     ` Jason Gunthorpe
2023-11-05 13:31       ` Jason Gunthorpe
2023-11-05 13:31       ` Jason Gunthorpe
2023-11-05 13:31       ` Jason Gunthorpe
2023-11-08 16:17   ` Rob Herring
2023-11-08 16:17     ` Rob Herring
2023-11-08 16:17     ` Rob Herring
2023-11-08 16:17     ` Rob Herring
2023-11-03 16:44 ` [PATCH RFC 03/17] of: Use -ENODEV consistently in of_iommu_configure() Jason Gunthorpe
2023-11-03 16:44   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 22:03   ` Jerry Snitselaar
2023-11-03 22:03     ` Jerry Snitselaar
2023-11-03 22:03     ` Jerry Snitselaar
2023-11-03 22:03     ` Jerry Snitselaar
2023-11-05 13:26     ` Jason Gunthorpe
2023-11-05 13:26       ` Jason Gunthorpe
2023-11-05 13:26       ` Jason Gunthorpe
2023-11-05 13:26       ` Jason Gunthorpe
2023-11-08 16:11   ` Rob Herring
2023-11-08 16:11     ` Rob Herring
2023-11-08 16:11     ` Rob Herring
2023-11-08 16:11     ` Rob Herring
2023-11-03 16:44 ` [PATCH RFC 04/17] acpi: Do not return struct iommu_ops from acpi_iommu_configure_id() Jason Gunthorpe
2023-11-03 16:44   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-04  0:48   ` Jerry Snitselaar
2023-11-04  0:48     ` Jerry Snitselaar
2023-11-04  0:48     ` Jerry Snitselaar
2023-11-04  0:48     ` Jerry Snitselaar
2023-11-05 13:24     ` Jason Gunthorpe
2023-11-05 13:24       ` Jason Gunthorpe
2023-11-05 13:24       ` Jason Gunthorpe
2023-11-05 13:24       ` Jason Gunthorpe
2023-11-05 17:55       ` Jerry Snitselaar
2023-11-05 17:55         ` Jerry Snitselaar
2023-11-05 17:55         ` Jerry Snitselaar
2023-11-05 17:55         ` Jerry Snitselaar
2023-11-06 14:32   ` Rafael J. Wysocki
2023-11-06 14:32     ` Rafael J. Wysocki
2023-11-06 14:32     ` Rafael J. Wysocki
2023-11-06 14:32     ` Rafael J. Wysocki
2023-11-06 14:32     ` Rafael J. Wysocki
2023-11-03 16:44 ` [PATCH RFC 05/17] iommu: Make iommu_fwspec->ids a distinct allocation Jason Gunthorpe
2023-11-03 16:44   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-13 20:10   ` Jerry Snitselaar
2023-11-13 20:10     ` Jerry Snitselaar
2023-11-13 20:10     ` Jerry Snitselaar
2023-11-13 20:10     ` Jerry Snitselaar
2023-11-03 16:44 ` [PATCH RFC 06/17] iommu: Add iommu_fwspec_alloc/dealloc() Jason Gunthorpe
2023-11-03 16:44   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-13 20:11   ` Jerry Snitselaar
2023-11-13 20:11     ` Jerry Snitselaar
2023-11-13 20:11     ` Jerry Snitselaar
2023-11-13 20:11     ` Jerry Snitselaar
2023-11-03 16:44 ` [PATCH RFC 07/17] iommu: Add iommu_probe_device_fwspec() Jason Gunthorpe
2023-11-03 16:44   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-13 20:11   ` Jerry Snitselaar
2023-11-13 20:11     ` Jerry Snitselaar
2023-11-13 20:11     ` Jerry Snitselaar
2023-11-13 20:11     ` Jerry Snitselaar
2023-11-03 16:44 ` [PATCH RFC 08/17] of: Do not use dev->iommu within of_iommu_configure() Jason Gunthorpe
2023-11-03 16:44   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-13 20:11   ` Jerry Snitselaar
2023-11-13 20:11     ` Jerry Snitselaar
2023-11-13 20:11     ` Jerry Snitselaar
2023-11-13 20:11     ` Jerry Snitselaar
2023-11-03 16:44 ` [PATCH RFC 09/17] iommu: Add iommu_fwspec_append_ids() Jason Gunthorpe
2023-11-03 16:44   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-13 20:12   ` Jerry Snitselaar
2023-11-13 20:12     ` Jerry Snitselaar
2023-11-13 20:12     ` Jerry Snitselaar
2023-11-13 20:12     ` Jerry Snitselaar
2023-11-03 16:44 ` [PATCH RFC 10/17] acpi: Do not use dev->iommu within acpi_iommu_configure() Jason Gunthorpe
2023-11-03 16:44   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-06 14:36   ` Rafael J. Wysocki
2023-11-06 14:36     ` Rafael J. Wysocki
2023-11-06 14:36     ` Rafael J. Wysocki
2023-11-06 14:36     ` Rafael J. Wysocki
2023-11-06 14:36     ` Rafael J. Wysocki
2023-11-12 17:44   ` Moritz Fischer
2023-11-12 17:44     ` Moritz Fischer
2023-11-12 17:44     ` Moritz Fischer
2023-11-12 17:44     ` Moritz Fischer
2023-11-13 22:37     ` Jason Gunthorpe
2023-11-13 22:37       ` Jason Gunthorpe
2023-11-13 22:37       ` Jason Gunthorpe
2023-11-13 22:37       ` Jason Gunthorpe
2023-11-13 20:13   ` Jerry Snitselaar
2023-11-13 20:13     ` Jerry Snitselaar
2023-11-13 20:13     ` Jerry Snitselaar
2023-11-13 20:13     ` Jerry Snitselaar
2023-11-03 16:44 ` [PATCH RFC 11/17] iommu: Hold iommu_probe_device_lock while calling ops->of_xlate Jason Gunthorpe
2023-11-03 16:44   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-13 20:14   ` Jerry Snitselaar
2023-11-13 20:14     ` Jerry Snitselaar
2023-11-13 20:14     ` Jerry Snitselaar
2023-11-13 20:14     ` Jerry Snitselaar
2023-11-03 16:44 ` [PATCH RFC 12/17] iommu: Make iommu_ops_from_fwnode() static Jason Gunthorpe
2023-11-03 16:44   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-08 18:12   ` André Draszik
2023-11-08 18:12     ` André Draszik
2023-11-08 18:12     ` André Draszik
2023-11-08 18:12     ` André Draszik
2023-11-13 20:02   ` Jerry Snitselaar
2023-11-13 20:02     ` Jerry Snitselaar
2023-11-13 20:02     ` Jerry Snitselaar
2023-11-13 20:02     ` Jerry Snitselaar
2023-11-03 16:44 ` [PATCH RFC 13/17] iommu: Remove dev_iommu_fwspec_set() Jason Gunthorpe
2023-11-03 16:44   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-13 20:06   ` Jerry Snitselaar
2023-11-13 20:06     ` Jerry Snitselaar
2023-11-13 20:06     ` Jerry Snitselaar
2023-11-13 20:06     ` Jerry Snitselaar
2023-11-03 16:44 ` [PATCH RFC 14/17] iommu: Remove pointless iommu_fwspec_free() Jason Gunthorpe
2023-11-03 16:44   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-03 16:44   ` Jason Gunthorpe
2023-11-13 20:18   ` Jerry Snitselaar
2023-11-13 20:18     ` Jerry Snitselaar
2023-11-13 20:18     ` Jerry Snitselaar
2023-11-13 20:18     ` Jerry Snitselaar
2023-11-03 16:45 ` [PATCH RFC 15/17] iommu: Add ops->of_xlate_fwspec() Jason Gunthorpe
2023-11-03 16:45   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:45   ` Jason Gunthorpe
2023-11-03 16:45   ` Jason Gunthorpe
2023-11-03 16:45   ` Jason Gunthorpe
2023-11-13 20:23   ` Jerry Snitselaar
2023-11-13 20:23     ` Jerry Snitselaar
2023-11-13 20:23     ` Jerry Snitselaar
2023-11-13 20:23     ` Jerry Snitselaar
2023-11-03 16:45 ` [PATCH RFC 16/17] iommu: Mark dev_iommu_get() with lockdep Jason Gunthorpe
2023-11-03 16:45   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:45   ` Jason Gunthorpe
2023-11-03 16:45   ` Jason Gunthorpe
2023-11-03 16:45   ` Jason Gunthorpe
2023-11-13 20:25   ` Jerry Snitselaar
2023-11-13 20:25     ` Jerry Snitselaar
2023-11-13 20:25     ` Jerry Snitselaar
2023-11-13 20:25     ` Jerry Snitselaar
2023-11-03 16:45 ` [PATCH RFC 17/17] iommu: Mark dev_iommu_priv_set() with a lockdep Jason Gunthorpe
2023-11-03 16:45   ` [Acpica-devel] " Jason Gunthorpe
2023-11-03 16:45   ` Jason Gunthorpe
2023-11-03 16:45   ` Jason Gunthorpe
2023-11-03 16:45   ` Jason Gunthorpe
2023-11-08  8:18   ` Baolu Lu
2023-11-08  8:18     ` Baolu Lu
2023-11-08  8:18     ` Baolu Lu
2023-11-08  8:18     ` Baolu Lu
2023-11-13 20:35   ` Jerry Snitselaar
2023-11-13 20:35     ` Jerry Snitselaar
2023-11-13 20:35     ` Jerry Snitselaar
2023-11-13 20:35     ` Jerry Snitselaar
2023-11-08 18:34 ` [PATCH RFC 00/17] Solve iommu probe races around iommu_fwspec André Draszik
2023-11-08 18:34   ` André Draszik
2023-11-08 18:34   ` André Draszik
2023-11-08 18:34   ` André Draszik
2023-11-08 19:22   ` Jason Gunthorpe
2023-11-08 19:22     ` Jason Gunthorpe
2023-11-08 19:22     ` Jason Gunthorpe
2023-11-08 19:22     ` Jason Gunthorpe
2023-11-14  4:56 ` Zhenhua Huang
2023-11-14  4:56   ` Zhenhua Huang
2023-11-14  4:56   ` Zhenhua Huang
2023-11-14  4:56   ` Zhenhua Huang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.