All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-06  6:19 ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

This is a preparatory series for IOMMUFD v2 patches. It enforces error
code -EMEDIUMTYPE in iommu_attach_device() and iommu_attach_group() when
an IOMMU domain and a device/group are incompatible. It also moves the
domain->ops check into __iommu_attach_device(). These allow VFIO iommu
code to simplify its group attachment routine, by avoiding the extra
IOMMU domain allocations and attach/detach sequences of the old code.

Worths mentioning the exact match for enforce_cache_coherency is removed
with this series, since there's very less value in doing that since KVM
won't be able to take advantage of it -- this just wastes domain memory.
Instead, we rely on Intel IOMMU driver taking care of that internally.

This is on github: https://github.com/nicolinc/iommufd/commits/vfio_iommu_attach

Jason Gunthorpe (1):
  vfio/iommu_type1: Prefer to reuse domains vs match enforced cache
    coherency

Nicolin Chen (4):
  iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
  iommu: Ensure device has the same iommu_ops as the domain
  vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
  vfio/iommu_type1: Simplify group attachment

 drivers/iommu/amd/iommu.c                   |   3 +-
 drivers/iommu/apple-dart.c                  |   5 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |   7 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.c       |   1 +
 drivers/iommu/arm/arm-smmu/qcom_iommu.c     |   3 +-
 drivers/iommu/exynos-iommu.c                |   1 +
 drivers/iommu/fsl_pamu_domain.c             |   1 +
 drivers/iommu/intel/iommu.c                 |   5 +-
 drivers/iommu/iommu.c                       |  26 ++
 drivers/iommu/ipmmu-vmsa.c                  |   3 +-
 drivers/iommu/msm_iommu.c                   |   1 +
 drivers/iommu/mtk_iommu.c                   |   1 +
 drivers/iommu/mtk_iommu_v1.c                |   1 +
 drivers/iommu/omap-iommu.c                  |   3 +-
 drivers/iommu/rockchip-iommu.c              |   1 +
 drivers/iommu/s390-iommu.c                  |   1 +
 drivers/iommu/sprd-iommu.c                  |   1 +
 drivers/iommu/sun50i-iommu.c                |   1 +
 drivers/iommu/tegra-gart.c                  |   1 +
 drivers/iommu/tegra-smmu.c                  |   1 +
 drivers/iommu/virtio-iommu.c                |   3 +-
 drivers/vfio/vfio_iommu_type1.c             | 315 ++++++++++----------
 include/linux/iommu.h                       |   2 +
 23 files changed, 223 insertions(+), 164 deletions(-)

-- 
2.17.1


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

* [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-06  6:19 ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

This is a preparatory series for IOMMUFD v2 patches. It enforces error
code -EMEDIUMTYPE in iommu_attach_device() and iommu_attach_group() when
an IOMMU domain and a device/group are incompatible. It also moves the
domain->ops check into __iommu_attach_device(). These allow VFIO iommu
code to simplify its group attachment routine, by avoiding the extra
IOMMU domain allocations and attach/detach sequences of the old code.

Worths mentioning the exact match for enforce_cache_coherency is removed
with this series, since there's very less value in doing that since KVM
won't be able to take advantage of it -- this just wastes domain memory.
Instead, we rely on Intel IOMMU driver taking care of that internally.

This is on github: https://github.com/nicolinc/iommufd/commits/vfio_iommu_attach

Jason Gunthorpe (1):
  vfio/iommu_type1: Prefer to reuse domains vs match enforced cache
    coherency

Nicolin Chen (4):
  iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
  iommu: Ensure device has the same iommu_ops as the domain
  vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
  vfio/iommu_type1: Simplify group attachment

 drivers/iommu/amd/iommu.c                   |   3 +-
 drivers/iommu/apple-dart.c                  |   5 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |   7 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.c       |   1 +
 drivers/iommu/arm/arm-smmu/qcom_iommu.c     |   3 +-
 drivers/iommu/exynos-iommu.c                |   1 +
 drivers/iommu/fsl_pamu_domain.c             |   1 +
 drivers/iommu/intel/iommu.c                 |   5 +-
 drivers/iommu/iommu.c                       |  26 ++
 drivers/iommu/ipmmu-vmsa.c                  |   3 +-
 drivers/iommu/msm_iommu.c                   |   1 +
 drivers/iommu/mtk_iommu.c                   |   1 +
 drivers/iommu/mtk_iommu_v1.c                |   1 +
 drivers/iommu/omap-iommu.c                  |   3 +-
 drivers/iommu/rockchip-iommu.c              |   1 +
 drivers/iommu/s390-iommu.c                  |   1 +
 drivers/iommu/sprd-iommu.c                  |   1 +
 drivers/iommu/sun50i-iommu.c                |   1 +
 drivers/iommu/tegra-gart.c                  |   1 +
 drivers/iommu/tegra-smmu.c                  |   1 +
 drivers/iommu/virtio-iommu.c                |   3 +-
 drivers/vfio/vfio_iommu_type1.c             | 315 ++++++++++----------
 include/linux/iommu.h                       |   2 +
 23 files changed, 223 insertions(+), 164 deletions(-)

-- 
2.17.1


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

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

* [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-06  6:19 ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen via iommu @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

This is a preparatory series for IOMMUFD v2 patches. It enforces error
code -EMEDIUMTYPE in iommu_attach_device() and iommu_attach_group() when
an IOMMU domain and a device/group are incompatible. It also moves the
domain->ops check into __iommu_attach_device(). These allow VFIO iommu
code to simplify its group attachment routine, by avoiding the extra
IOMMU domain allocations and attach/detach sequences of the old code.

Worths mentioning the exact match for enforce_cache_coherency is removed
with this series, since there's very less value in doing that since KVM
won't be able to take advantage of it -- this just wastes domain memory.
Instead, we rely on Intel IOMMU driver taking care of that internally.

This is on github: https://github.com/nicolinc/iommufd/commits/vfio_iommu_attach

Jason Gunthorpe (1):
  vfio/iommu_type1: Prefer to reuse domains vs match enforced cache
    coherency

Nicolin Chen (4):
  iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
  iommu: Ensure device has the same iommu_ops as the domain
  vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
  vfio/iommu_type1: Simplify group attachment

 drivers/iommu/amd/iommu.c                   |   3 +-
 drivers/iommu/apple-dart.c                  |   5 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |   7 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.c       |   1 +
 drivers/iommu/arm/arm-smmu/qcom_iommu.c     |   3 +-
 drivers/iommu/exynos-iommu.c                |   1 +
 drivers/iommu/fsl_pamu_domain.c             |   1 +
 drivers/iommu/intel/iommu.c                 |   5 +-
 drivers/iommu/iommu.c                       |  26 ++
 drivers/iommu/ipmmu-vmsa.c                  |   3 +-
 drivers/iommu/msm_iommu.c                   |   1 +
 drivers/iommu/mtk_iommu.c                   |   1 +
 drivers/iommu/mtk_iommu_v1.c                |   1 +
 drivers/iommu/omap-iommu.c                  |   3 +-
 drivers/iommu/rockchip-iommu.c              |   1 +
 drivers/iommu/s390-iommu.c                  |   1 +
 drivers/iommu/sprd-iommu.c                  |   1 +
 drivers/iommu/sun50i-iommu.c                |   1 +
 drivers/iommu/tegra-gart.c                  |   1 +
 drivers/iommu/tegra-smmu.c                  |   1 +
 drivers/iommu/virtio-iommu.c                |   3 +-
 drivers/vfio/vfio_iommu_type1.c             | 315 ++++++++++----------
 include/linux/iommu.h                       |   2 +
 23 files changed, 223 insertions(+), 164 deletions(-)

-- 
2.17.1

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

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

* [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-06  6:19 ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

This is a preparatory series for IOMMUFD v2 patches. It enforces error
code -EMEDIUMTYPE in iommu_attach_device() and iommu_attach_group() when
an IOMMU domain and a device/group are incompatible. It also moves the
domain->ops check into __iommu_attach_device(). These allow VFIO iommu
code to simplify its group attachment routine, by avoiding the extra
IOMMU domain allocations and attach/detach sequences of the old code.

Worths mentioning the exact match for enforce_cache_coherency is removed
with this series, since there's very less value in doing that since KVM
won't be able to take advantage of it -- this just wastes domain memory.
Instead, we rely on Intel IOMMU driver taking care of that internally.

This is on github: https://github.com/nicolinc/iommufd/commits/vfio_iommu_attach

Jason Gunthorpe (1):
  vfio/iommu_type1: Prefer to reuse domains vs match enforced cache
    coherency

Nicolin Chen (4):
  iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
  iommu: Ensure device has the same iommu_ops as the domain
  vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
  vfio/iommu_type1: Simplify group attachment

 drivers/iommu/amd/iommu.c                   |   3 +-
 drivers/iommu/apple-dart.c                  |   5 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |   7 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.c       |   1 +
 drivers/iommu/arm/arm-smmu/qcom_iommu.c     |   3 +-
 drivers/iommu/exynos-iommu.c                |   1 +
 drivers/iommu/fsl_pamu_domain.c             |   1 +
 drivers/iommu/intel/iommu.c                 |   5 +-
 drivers/iommu/iommu.c                       |  26 ++
 drivers/iommu/ipmmu-vmsa.c                  |   3 +-
 drivers/iommu/msm_iommu.c                   |   1 +
 drivers/iommu/mtk_iommu.c                   |   1 +
 drivers/iommu/mtk_iommu_v1.c                |   1 +
 drivers/iommu/omap-iommu.c                  |   3 +-
 drivers/iommu/rockchip-iommu.c              |   1 +
 drivers/iommu/s390-iommu.c                  |   1 +
 drivers/iommu/sprd-iommu.c                  |   1 +
 drivers/iommu/sun50i-iommu.c                |   1 +
 drivers/iommu/tegra-gart.c                  |   1 +
 drivers/iommu/tegra-smmu.c                  |   1 +
 drivers/iommu/virtio-iommu.c                |   3 +-
 drivers/vfio/vfio_iommu_type1.c             | 315 ++++++++++----------
 include/linux/iommu.h                       |   2 +
 23 files changed, 223 insertions(+), 164 deletions(-)

-- 
2.17.1


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

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

* [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-06  6:19 ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: mjrosato, virtualization, thierry.reding, alim.akhtar, alyssa,
	linux-s390, linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	yong.wu, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, suravee.suthikulpanit, dwmw2

This is a preparatory series for IOMMUFD v2 patches. It enforces error
code -EMEDIUMTYPE in iommu_attach_device() and iommu_attach_group() when
an IOMMU domain and a device/group are incompatible. It also moves the
domain->ops check into __iommu_attach_device(). These allow VFIO iommu
code to simplify its group attachment routine, by avoiding the extra
IOMMU domain allocations and attach/detach sequences of the old code.

Worths mentioning the exact match for enforce_cache_coherency is removed
with this series, since there's very less value in doing that since KVM
won't be able to take advantage of it -- this just wastes domain memory.
Instead, we rely on Intel IOMMU driver taking care of that internally.

This is on github: https://github.com/nicolinc/iommufd/commits/vfio_iommu_attach

Jason Gunthorpe (1):
  vfio/iommu_type1: Prefer to reuse domains vs match enforced cache
    coherency

Nicolin Chen (4):
  iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
  iommu: Ensure device has the same iommu_ops as the domain
  vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
  vfio/iommu_type1: Simplify group attachment

 drivers/iommu/amd/iommu.c                   |   3 +-
 drivers/iommu/apple-dart.c                  |   5 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |   7 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.c       |   1 +
 drivers/iommu/arm/arm-smmu/qcom_iommu.c     |   3 +-
 drivers/iommu/exynos-iommu.c                |   1 +
 drivers/iommu/fsl_pamu_domain.c             |   1 +
 drivers/iommu/intel/iommu.c                 |   5 +-
 drivers/iommu/iommu.c                       |  26 ++
 drivers/iommu/ipmmu-vmsa.c                  |   3 +-
 drivers/iommu/msm_iommu.c                   |   1 +
 drivers/iommu/mtk_iommu.c                   |   1 +
 drivers/iommu/mtk_iommu_v1.c                |   1 +
 drivers/iommu/omap-iommu.c                  |   3 +-
 drivers/iommu/rockchip-iommu.c              |   1 +
 drivers/iommu/s390-iommu.c                  |   1 +
 drivers/iommu/sprd-iommu.c                  |   1 +
 drivers/iommu/sun50i-iommu.c                |   1 +
 drivers/iommu/tegra-gart.c                  |   1 +
 drivers/iommu/tegra-smmu.c                  |   1 +
 drivers/iommu/virtio-iommu.c                |   3 +-
 drivers/vfio/vfio_iommu_type1.c             | 315 ++++++++++----------
 include/linux/iommu.h                       |   2 +
 23 files changed, 223 insertions(+), 164 deletions(-)

-- 
2.17.1


_______________________________________________
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] 138+ messages in thread

* [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
  2022-06-06  6:19 ` Nicolin Chen
                     ` (2 preceding siblings ...)
  (?)
@ 2022-06-06  6:19   ` Nicolin Chen
  -1 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

Cases like VFIO wish to attach a device to an existing domain that was
not allocated specifically from the device. This raises a condition
where the IOMMU driver can fail the domain attach because the domain and
device are incompatible with each other.

This is a soft failure that can be resolved by using a different domain.

Provide a dedicated errno from the IOMMU driver during attach that the
reason attached failed is because of domain incompatability. EMEDIUMTYPE
is chosen because it is never used within the iommu subsystem today and
evokes a sense that the 'medium' aka the domain is incompatible.

VFIO can use this to know attach is a soft failure and it should continue
searching. Otherwise the attach will be a hard failure and VFIO will
return the code to userspace.

Update all drivers to return EMEDIUMTYPE in their failure paths that are
related to domain incompatability.

Add kdocs describing this behavior.

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/iommu/amd/iommu.c                   |  2 +-
 drivers/iommu/apple-dart.c                  |  4 ++--
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  6 +++---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c     |  2 +-
 drivers/iommu/intel/iommu.c                 |  4 ++--
 drivers/iommu/iommu.c                       | 22 +++++++++++++++++++++
 drivers/iommu/ipmmu-vmsa.c                  |  2 +-
 drivers/iommu/omap-iommu.c                  |  2 +-
 drivers/iommu/virtio-iommu.c                |  2 +-
 9 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 840831d5d2ad..ad499658a6b6 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -1662,7 +1662,7 @@ static int attach_device(struct device *dev,
 	if (domain->flags & PD_IOMMUV2_MASK) {
 		struct iommu_domain *def_domain = iommu_get_dma_domain(dev);
 
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 		if (def_domain->type != IOMMU_DOMAIN_IDENTITY)
 			goto out;
 
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index 8af0242a90d9..e58dc310afd7 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -495,10 +495,10 @@ static int apple_dart_attach_dev(struct iommu_domain *domain,
 
 	if (cfg->stream_maps[0].dart->force_bypass &&
 	    domain->type != IOMMU_DOMAIN_IDENTITY)
-		return -EINVAL;
+		return -EMEDIUMTYPE;
 	if (!cfg->stream_maps[0].dart->supports_bypass &&
 	    domain->type == IOMMU_DOMAIN_IDENTITY)
-		return -EINVAL;
+		return -EMEDIUMTYPE;
 
 	ret = apple_dart_finalize_domain(domain, cfg);
 	if (ret)
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 88817a3376ef..6c393cd84925 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2424,20 +2424,20 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 			"cannot attach to SMMU %s (upstream of %s)\n",
 			dev_name(smmu_domain->smmu->dev),
 			dev_name(smmu->dev));
-		ret = -ENXIO;
+		ret = -EMEDIUMTYPE;
 		goto out_unlock;
 	} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
 		   master->ssid_bits != smmu_domain->s1_cfg.s1cdmax) {
 		dev_err(dev,
 			"cannot attach to incompatible domain (%u SSID bits != %u)\n",
 			smmu_domain->s1_cfg.s1cdmax, master->ssid_bits);
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 		goto out_unlock;
 	} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
 		   smmu_domain->stall_enabled != master->stall_enabled) {
 		dev_err(dev, "cannot attach to stall-%s domain\n",
 			smmu_domain->stall_enabled ? "enabled" : "disabled");
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 		goto out_unlock;
 	}
 
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 4c077c38fbd6..a8b63b855ffb 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -386,7 +386,7 @@ static int qcom_iommu_attach_dev(struct iommu_domain *domain, struct device *dev
 			"attached to domain on IOMMU %s\n",
 			dev_name(qcom_domain->iommu->dev),
 			dev_name(qcom_iommu->dev));
-		return -EINVAL;
+		return -EMEDIUMTYPE;
 	}
 
 	return 0;
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 44016594831d..0813b119d680 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4323,7 +4323,7 @@ static int prepare_domain_attach_device(struct iommu_domain *domain,
 		return -ENODEV;
 
 	if (dmar_domain->force_snooping && !ecap_sc_support(iommu->ecap))
-		return -EOPNOTSUPP;
+		return -EMEDIUMTYPE;
 
 	/* check if this iommu agaw is sufficient for max mapped address */
 	addr_width = agaw_to_width(iommu->agaw);
@@ -4334,7 +4334,7 @@ static int prepare_domain_attach_device(struct iommu_domain *domain,
 		dev_err(dev, "%s: iommu width (%d) is not "
 		        "sufficient for the mapped address (%llx)\n",
 		        __func__, addr_width, dmar_domain->max_addr);
-		return -EFAULT;
+		return -EMEDIUMTYPE;
 	}
 	dmar_domain->gaw = addr_width;
 
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 847ad47a2dfd..19cf28d40ebe 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1972,6 +1972,17 @@ static int __iommu_attach_device(struct iommu_domain *domain,
 	return ret;
 }
 
+/**
+ * iommu_attach_device - Attach a device to an IOMMU domain
+ * @domain: IOMMU domain to attach
+ * @dev: Device that will be attached
+ *
+ * Returns 0 on success and error code on failure
+ *
+ * Specifically, -EMEDIUMTYPE is returned if the domain and the device are
+ * incompatible in some way. This indicates that a caller should try another
+ * existing IOMMU domain or allocate a new one.
+ */
 int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
 {
 	struct iommu_group *group;
@@ -2098,6 +2109,17 @@ static int __iommu_attach_group(struct iommu_domain *domain,
 	return ret;
 }
 
+/**
+ * iommu_attach_group - Attach an IOMMU group to an IOMMU domain
+ * @domain: IOMMU domain to attach
+ * @dev: IOMMU group that will be attached
+ *
+ * Returns 0 on success and error code on failure
+ *
+ * Specifically, -EMEDIUMTYPE is returned if the domain and the group are
+ * incompatible in some way. This indicates that a caller should try another
+ * existing IOMMU domain or allocate a new one.
+ */
 int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group)
 {
 	int ret;
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 8fdb84b3642b..e491e410add5 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -630,7 +630,7 @@ static int ipmmu_attach_device(struct iommu_domain *io_domain,
 		 */
 		dev_err(dev, "Can't attach IPMMU %s to domain on IPMMU %s\n",
 			dev_name(mmu->dev), dev_name(domain->mmu->dev));
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 	} else
 		dev_info(dev, "Reusing IPMMU context %u\n", domain->context_id);
 
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index d9cf2820c02e..bbc6c4cd7aae 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1472,7 +1472,7 @@ omap_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 	/* only a single client device can be attached to a domain */
 	if (omap_domain->dev) {
 		dev_err(dev, "iommu domain is already attached\n");
-		ret = -EBUSY;
+		ret = -EMEDIUMTYPE;
 		goto out;
 	}
 
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 25be4b822aa0..e3b812d8fa96 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -734,7 +734,7 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 		ret = viommu_domain_finalise(vdev, domain);
 	} else if (vdomain->viommu != vdev->viommu) {
 		dev_err(dev, "cannot attach to foreign vIOMMU\n");
-		ret = -EXDEV;
+		ret = -EMEDIUMTYPE;
 	}
 	mutex_unlock(&vdomain->mutex);
 
-- 
2.17.1


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

* [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-06  6:19   ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

Cases like VFIO wish to attach a device to an existing domain that was
not allocated specifically from the device. This raises a condition
where the IOMMU driver can fail the domain attach because the domain and
device are incompatible with each other.

This is a soft failure that can be resolved by using a different domain.

Provide a dedicated errno from the IOMMU driver during attach that the
reason attached failed is because of domain incompatability. EMEDIUMTYPE
is chosen because it is never used within the iommu subsystem today and
evokes a sense that the 'medium' aka the domain is incompatible.

VFIO can use this to know attach is a soft failure and it should continue
searching. Otherwise the attach will be a hard failure and VFIO will
return the code to userspace.

Update all drivers to return EMEDIUMTYPE in their failure paths that are
related to domain incompatability.

Add kdocs describing this behavior.

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/iommu/amd/iommu.c                   |  2 +-
 drivers/iommu/apple-dart.c                  |  4 ++--
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  6 +++---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c     |  2 +-
 drivers/iommu/intel/iommu.c                 |  4 ++--
 drivers/iommu/iommu.c                       | 22 +++++++++++++++++++++
 drivers/iommu/ipmmu-vmsa.c                  |  2 +-
 drivers/iommu/omap-iommu.c                  |  2 +-
 drivers/iommu/virtio-iommu.c                |  2 +-
 9 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 840831d5d2ad..ad499658a6b6 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -1662,7 +1662,7 @@ static int attach_device(struct device *dev,
 	if (domain->flags & PD_IOMMUV2_MASK) {
 		struct iommu_domain *def_domain = iommu_get_dma_domain(dev);
 
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 		if (def_domain->type != IOMMU_DOMAIN_IDENTITY)
 			goto out;
 
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index 8af0242a90d9..e58dc310afd7 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -495,10 +495,10 @@ static int apple_dart_attach_dev(struct iommu_domain *domain,
 
 	if (cfg->stream_maps[0].dart->force_bypass &&
 	    domain->type != IOMMU_DOMAIN_IDENTITY)
-		return -EINVAL;
+		return -EMEDIUMTYPE;
 	if (!cfg->stream_maps[0].dart->supports_bypass &&
 	    domain->type == IOMMU_DOMAIN_IDENTITY)
-		return -EINVAL;
+		return -EMEDIUMTYPE;
 
 	ret = apple_dart_finalize_domain(domain, cfg);
 	if (ret)
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 88817a3376ef..6c393cd84925 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2424,20 +2424,20 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 			"cannot attach to SMMU %s (upstream of %s)\n",
 			dev_name(smmu_domain->smmu->dev),
 			dev_name(smmu->dev));
-		ret = -ENXIO;
+		ret = -EMEDIUMTYPE;
 		goto out_unlock;
 	} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
 		   master->ssid_bits != smmu_domain->s1_cfg.s1cdmax) {
 		dev_err(dev,
 			"cannot attach to incompatible domain (%u SSID bits != %u)\n",
 			smmu_domain->s1_cfg.s1cdmax, master->ssid_bits);
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 		goto out_unlock;
 	} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
 		   smmu_domain->stall_enabled != master->stall_enabled) {
 		dev_err(dev, "cannot attach to stall-%s domain\n",
 			smmu_domain->stall_enabled ? "enabled" : "disabled");
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 		goto out_unlock;
 	}
 
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 4c077c38fbd6..a8b63b855ffb 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -386,7 +386,7 @@ static int qcom_iommu_attach_dev(struct iommu_domain *domain, struct device *dev
 			"attached to domain on IOMMU %s\n",
 			dev_name(qcom_domain->iommu->dev),
 			dev_name(qcom_iommu->dev));
-		return -EINVAL;
+		return -EMEDIUMTYPE;
 	}
 
 	return 0;
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 44016594831d..0813b119d680 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4323,7 +4323,7 @@ static int prepare_domain_attach_device(struct iommu_domain *domain,
 		return -ENODEV;
 
 	if (dmar_domain->force_snooping && !ecap_sc_support(iommu->ecap))
-		return -EOPNOTSUPP;
+		return -EMEDIUMTYPE;
 
 	/* check if this iommu agaw is sufficient for max mapped address */
 	addr_width = agaw_to_width(iommu->agaw);
@@ -4334,7 +4334,7 @@ static int prepare_domain_attach_device(struct iommu_domain *domain,
 		dev_err(dev, "%s: iommu width (%d) is not "
 		        "sufficient for the mapped address (%llx)\n",
 		        __func__, addr_width, dmar_domain->max_addr);
-		return -EFAULT;
+		return -EMEDIUMTYPE;
 	}
 	dmar_domain->gaw = addr_width;
 
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 847ad47a2dfd..19cf28d40ebe 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1972,6 +1972,17 @@ static int __iommu_attach_device(struct iommu_domain *domain,
 	return ret;
 }
 
+/**
+ * iommu_attach_device - Attach a device to an IOMMU domain
+ * @domain: IOMMU domain to attach
+ * @dev: Device that will be attached
+ *
+ * Returns 0 on success and error code on failure
+ *
+ * Specifically, -EMEDIUMTYPE is returned if the domain and the device are
+ * incompatible in some way. This indicates that a caller should try another
+ * existing IOMMU domain or allocate a new one.
+ */
 int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
 {
 	struct iommu_group *group;
@@ -2098,6 +2109,17 @@ static int __iommu_attach_group(struct iommu_domain *domain,
 	return ret;
 }
 
+/**
+ * iommu_attach_group - Attach an IOMMU group to an IOMMU domain
+ * @domain: IOMMU domain to attach
+ * @dev: IOMMU group that will be attached
+ *
+ * Returns 0 on success and error code on failure
+ *
+ * Specifically, -EMEDIUMTYPE is returned if the domain and the group are
+ * incompatible in some way. This indicates that a caller should try another
+ * existing IOMMU domain or allocate a new one.
+ */
 int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group)
 {
 	int ret;
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 8fdb84b3642b..e491e410add5 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -630,7 +630,7 @@ static int ipmmu_attach_device(struct iommu_domain *io_domain,
 		 */
 		dev_err(dev, "Can't attach IPMMU %s to domain on IPMMU %s\n",
 			dev_name(mmu->dev), dev_name(domain->mmu->dev));
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 	} else
 		dev_info(dev, "Reusing IPMMU context %u\n", domain->context_id);
 
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index d9cf2820c02e..bbc6c4cd7aae 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1472,7 +1472,7 @@ omap_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 	/* only a single client device can be attached to a domain */
 	if (omap_domain->dev) {
 		dev_err(dev, "iommu domain is already attached\n");
-		ret = -EBUSY;
+		ret = -EMEDIUMTYPE;
 		goto out;
 	}
 
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 25be4b822aa0..e3b812d8fa96 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -734,7 +734,7 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 		ret = viommu_domain_finalise(vdev, domain);
 	} else if (vdomain->viommu != vdev->viommu) {
 		dev_err(dev, "cannot attach to foreign vIOMMU\n");
-		ret = -EXDEV;
+		ret = -EMEDIUMTYPE;
 	}
 	mutex_unlock(&vdomain->mutex);
 
-- 
2.17.1


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

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

* [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-06  6:19   ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen via iommu @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

Cases like VFIO wish to attach a device to an existing domain that was
not allocated specifically from the device. This raises a condition
where the IOMMU driver can fail the domain attach because the domain and
device are incompatible with each other.

This is a soft failure that can be resolved by using a different domain.

Provide a dedicated errno from the IOMMU driver during attach that the
reason attached failed is because of domain incompatability. EMEDIUMTYPE
is chosen because it is never used within the iommu subsystem today and
evokes a sense that the 'medium' aka the domain is incompatible.

VFIO can use this to know attach is a soft failure and it should continue
searching. Otherwise the attach will be a hard failure and VFIO will
return the code to userspace.

Update all drivers to return EMEDIUMTYPE in their failure paths that are
related to domain incompatability.

Add kdocs describing this behavior.

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/iommu/amd/iommu.c                   |  2 +-
 drivers/iommu/apple-dart.c                  |  4 ++--
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  6 +++---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c     |  2 +-
 drivers/iommu/intel/iommu.c                 |  4 ++--
 drivers/iommu/iommu.c                       | 22 +++++++++++++++++++++
 drivers/iommu/ipmmu-vmsa.c                  |  2 +-
 drivers/iommu/omap-iommu.c                  |  2 +-
 drivers/iommu/virtio-iommu.c                |  2 +-
 9 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 840831d5d2ad..ad499658a6b6 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -1662,7 +1662,7 @@ static int attach_device(struct device *dev,
 	if (domain->flags & PD_IOMMUV2_MASK) {
 		struct iommu_domain *def_domain = iommu_get_dma_domain(dev);
 
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 		if (def_domain->type != IOMMU_DOMAIN_IDENTITY)
 			goto out;
 
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index 8af0242a90d9..e58dc310afd7 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -495,10 +495,10 @@ static int apple_dart_attach_dev(struct iommu_domain *domain,
 
 	if (cfg->stream_maps[0].dart->force_bypass &&
 	    domain->type != IOMMU_DOMAIN_IDENTITY)
-		return -EINVAL;
+		return -EMEDIUMTYPE;
 	if (!cfg->stream_maps[0].dart->supports_bypass &&
 	    domain->type == IOMMU_DOMAIN_IDENTITY)
-		return -EINVAL;
+		return -EMEDIUMTYPE;
 
 	ret = apple_dart_finalize_domain(domain, cfg);
 	if (ret)
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 88817a3376ef..6c393cd84925 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2424,20 +2424,20 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 			"cannot attach to SMMU %s (upstream of %s)\n",
 			dev_name(smmu_domain->smmu->dev),
 			dev_name(smmu->dev));
-		ret = -ENXIO;
+		ret = -EMEDIUMTYPE;
 		goto out_unlock;
 	} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
 		   master->ssid_bits != smmu_domain->s1_cfg.s1cdmax) {
 		dev_err(dev,
 			"cannot attach to incompatible domain (%u SSID bits != %u)\n",
 			smmu_domain->s1_cfg.s1cdmax, master->ssid_bits);
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 		goto out_unlock;
 	} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
 		   smmu_domain->stall_enabled != master->stall_enabled) {
 		dev_err(dev, "cannot attach to stall-%s domain\n",
 			smmu_domain->stall_enabled ? "enabled" : "disabled");
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 		goto out_unlock;
 	}
 
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 4c077c38fbd6..a8b63b855ffb 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -386,7 +386,7 @@ static int qcom_iommu_attach_dev(struct iommu_domain *domain, struct device *dev
 			"attached to domain on IOMMU %s\n",
 			dev_name(qcom_domain->iommu->dev),
 			dev_name(qcom_iommu->dev));
-		return -EINVAL;
+		return -EMEDIUMTYPE;
 	}
 
 	return 0;
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 44016594831d..0813b119d680 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4323,7 +4323,7 @@ static int prepare_domain_attach_device(struct iommu_domain *domain,
 		return -ENODEV;
 
 	if (dmar_domain->force_snooping && !ecap_sc_support(iommu->ecap))
-		return -EOPNOTSUPP;
+		return -EMEDIUMTYPE;
 
 	/* check if this iommu agaw is sufficient for max mapped address */
 	addr_width = agaw_to_width(iommu->agaw);
@@ -4334,7 +4334,7 @@ static int prepare_domain_attach_device(struct iommu_domain *domain,
 		dev_err(dev, "%s: iommu width (%d) is not "
 		        "sufficient for the mapped address (%llx)\n",
 		        __func__, addr_width, dmar_domain->max_addr);
-		return -EFAULT;
+		return -EMEDIUMTYPE;
 	}
 	dmar_domain->gaw = addr_width;
 
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 847ad47a2dfd..19cf28d40ebe 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1972,6 +1972,17 @@ static int __iommu_attach_device(struct iommu_domain *domain,
 	return ret;
 }
 
+/**
+ * iommu_attach_device - Attach a device to an IOMMU domain
+ * @domain: IOMMU domain to attach
+ * @dev: Device that will be attached
+ *
+ * Returns 0 on success and error code on failure
+ *
+ * Specifically, -EMEDIUMTYPE is returned if the domain and the device are
+ * incompatible in some way. This indicates that a caller should try another
+ * existing IOMMU domain or allocate a new one.
+ */
 int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
 {
 	struct iommu_group *group;
@@ -2098,6 +2109,17 @@ static int __iommu_attach_group(struct iommu_domain *domain,
 	return ret;
 }
 
+/**
+ * iommu_attach_group - Attach an IOMMU group to an IOMMU domain
+ * @domain: IOMMU domain to attach
+ * @dev: IOMMU group that will be attached
+ *
+ * Returns 0 on success and error code on failure
+ *
+ * Specifically, -EMEDIUMTYPE is returned if the domain and the group are
+ * incompatible in some way. This indicates that a caller should try another
+ * existing IOMMU domain or allocate a new one.
+ */
 int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group)
 {
 	int ret;
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 8fdb84b3642b..e491e410add5 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -630,7 +630,7 @@ static int ipmmu_attach_device(struct iommu_domain *io_domain,
 		 */
 		dev_err(dev, "Can't attach IPMMU %s to domain on IPMMU %s\n",
 			dev_name(mmu->dev), dev_name(domain->mmu->dev));
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 	} else
 		dev_info(dev, "Reusing IPMMU context %u\n", domain->context_id);
 
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index d9cf2820c02e..bbc6c4cd7aae 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1472,7 +1472,7 @@ omap_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 	/* only a single client device can be attached to a domain */
 	if (omap_domain->dev) {
 		dev_err(dev, "iommu domain is already attached\n");
-		ret = -EBUSY;
+		ret = -EMEDIUMTYPE;
 		goto out;
 	}
 
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 25be4b822aa0..e3b812d8fa96 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -734,7 +734,7 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 		ret = viommu_domain_finalise(vdev, domain);
 	} else if (vdomain->viommu != vdev->viommu) {
 		dev_err(dev, "cannot attach to foreign vIOMMU\n");
-		ret = -EXDEV;
+		ret = -EMEDIUMTYPE;
 	}
 	mutex_unlock(&vdomain->mutex);
 
-- 
2.17.1

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

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

* [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-06  6:19   ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

Cases like VFIO wish to attach a device to an existing domain that was
not allocated specifically from the device. This raises a condition
where the IOMMU driver can fail the domain attach because the domain and
device are incompatible with each other.

This is a soft failure that can be resolved by using a different domain.

Provide a dedicated errno from the IOMMU driver during attach that the
reason attached failed is because of domain incompatability. EMEDIUMTYPE
is chosen because it is never used within the iommu subsystem today and
evokes a sense that the 'medium' aka the domain is incompatible.

VFIO can use this to know attach is a soft failure and it should continue
searching. Otherwise the attach will be a hard failure and VFIO will
return the code to userspace.

Update all drivers to return EMEDIUMTYPE in their failure paths that are
related to domain incompatability.

Add kdocs describing this behavior.

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/iommu/amd/iommu.c                   |  2 +-
 drivers/iommu/apple-dart.c                  |  4 ++--
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  6 +++---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c     |  2 +-
 drivers/iommu/intel/iommu.c                 |  4 ++--
 drivers/iommu/iommu.c                       | 22 +++++++++++++++++++++
 drivers/iommu/ipmmu-vmsa.c                  |  2 +-
 drivers/iommu/omap-iommu.c                  |  2 +-
 drivers/iommu/virtio-iommu.c                |  2 +-
 9 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 840831d5d2ad..ad499658a6b6 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -1662,7 +1662,7 @@ static int attach_device(struct device *dev,
 	if (domain->flags & PD_IOMMUV2_MASK) {
 		struct iommu_domain *def_domain = iommu_get_dma_domain(dev);
 
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 		if (def_domain->type != IOMMU_DOMAIN_IDENTITY)
 			goto out;
 
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index 8af0242a90d9..e58dc310afd7 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -495,10 +495,10 @@ static int apple_dart_attach_dev(struct iommu_domain *domain,
 
 	if (cfg->stream_maps[0].dart->force_bypass &&
 	    domain->type != IOMMU_DOMAIN_IDENTITY)
-		return -EINVAL;
+		return -EMEDIUMTYPE;
 	if (!cfg->stream_maps[0].dart->supports_bypass &&
 	    domain->type == IOMMU_DOMAIN_IDENTITY)
-		return -EINVAL;
+		return -EMEDIUMTYPE;
 
 	ret = apple_dart_finalize_domain(domain, cfg);
 	if (ret)
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 88817a3376ef..6c393cd84925 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2424,20 +2424,20 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 			"cannot attach to SMMU %s (upstream of %s)\n",
 			dev_name(smmu_domain->smmu->dev),
 			dev_name(smmu->dev));
-		ret = -ENXIO;
+		ret = -EMEDIUMTYPE;
 		goto out_unlock;
 	} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
 		   master->ssid_bits != smmu_domain->s1_cfg.s1cdmax) {
 		dev_err(dev,
 			"cannot attach to incompatible domain (%u SSID bits != %u)\n",
 			smmu_domain->s1_cfg.s1cdmax, master->ssid_bits);
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 		goto out_unlock;
 	} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
 		   smmu_domain->stall_enabled != master->stall_enabled) {
 		dev_err(dev, "cannot attach to stall-%s domain\n",
 			smmu_domain->stall_enabled ? "enabled" : "disabled");
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 		goto out_unlock;
 	}
 
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 4c077c38fbd6..a8b63b855ffb 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -386,7 +386,7 @@ static int qcom_iommu_attach_dev(struct iommu_domain *domain, struct device *dev
 			"attached to domain on IOMMU %s\n",
 			dev_name(qcom_domain->iommu->dev),
 			dev_name(qcom_iommu->dev));
-		return -EINVAL;
+		return -EMEDIUMTYPE;
 	}
 
 	return 0;
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 44016594831d..0813b119d680 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4323,7 +4323,7 @@ static int prepare_domain_attach_device(struct iommu_domain *domain,
 		return -ENODEV;
 
 	if (dmar_domain->force_snooping && !ecap_sc_support(iommu->ecap))
-		return -EOPNOTSUPP;
+		return -EMEDIUMTYPE;
 
 	/* check if this iommu agaw is sufficient for max mapped address */
 	addr_width = agaw_to_width(iommu->agaw);
@@ -4334,7 +4334,7 @@ static int prepare_domain_attach_device(struct iommu_domain *domain,
 		dev_err(dev, "%s: iommu width (%d) is not "
 		        "sufficient for the mapped address (%llx)\n",
 		        __func__, addr_width, dmar_domain->max_addr);
-		return -EFAULT;
+		return -EMEDIUMTYPE;
 	}
 	dmar_domain->gaw = addr_width;
 
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 847ad47a2dfd..19cf28d40ebe 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1972,6 +1972,17 @@ static int __iommu_attach_device(struct iommu_domain *domain,
 	return ret;
 }
 
+/**
+ * iommu_attach_device - Attach a device to an IOMMU domain
+ * @domain: IOMMU domain to attach
+ * @dev: Device that will be attached
+ *
+ * Returns 0 on success and error code on failure
+ *
+ * Specifically, -EMEDIUMTYPE is returned if the domain and the device are
+ * incompatible in some way. This indicates that a caller should try another
+ * existing IOMMU domain or allocate a new one.
+ */
 int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
 {
 	struct iommu_group *group;
@@ -2098,6 +2109,17 @@ static int __iommu_attach_group(struct iommu_domain *domain,
 	return ret;
 }
 
+/**
+ * iommu_attach_group - Attach an IOMMU group to an IOMMU domain
+ * @domain: IOMMU domain to attach
+ * @dev: IOMMU group that will be attached
+ *
+ * Returns 0 on success and error code on failure
+ *
+ * Specifically, -EMEDIUMTYPE is returned if the domain and the group are
+ * incompatible in some way. This indicates that a caller should try another
+ * existing IOMMU domain or allocate a new one.
+ */
 int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group)
 {
 	int ret;
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 8fdb84b3642b..e491e410add5 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -630,7 +630,7 @@ static int ipmmu_attach_device(struct iommu_domain *io_domain,
 		 */
 		dev_err(dev, "Can't attach IPMMU %s to domain on IPMMU %s\n",
 			dev_name(mmu->dev), dev_name(domain->mmu->dev));
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 	} else
 		dev_info(dev, "Reusing IPMMU context %u\n", domain->context_id);
 
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index d9cf2820c02e..bbc6c4cd7aae 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1472,7 +1472,7 @@ omap_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 	/* only a single client device can be attached to a domain */
 	if (omap_domain->dev) {
 		dev_err(dev, "iommu domain is already attached\n");
-		ret = -EBUSY;
+		ret = -EMEDIUMTYPE;
 		goto out;
 	}
 
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 25be4b822aa0..e3b812d8fa96 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -734,7 +734,7 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 		ret = viommu_domain_finalise(vdev, domain);
 	} else if (vdomain->viommu != vdev->viommu) {
 		dev_err(dev, "cannot attach to foreign vIOMMU\n");
-		ret = -EXDEV;
+		ret = -EMEDIUMTYPE;
 	}
 	mutex_unlock(&vdomain->mutex);
 
-- 
2.17.1


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

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

* [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-06  6:19   ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: mjrosato, virtualization, thierry.reding, alim.akhtar, alyssa,
	linux-s390, linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	yong.wu, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, suravee.suthikulpanit, dwmw2

Cases like VFIO wish to attach a device to an existing domain that was
not allocated specifically from the device. This raises a condition
where the IOMMU driver can fail the domain attach because the domain and
device are incompatible with each other.

This is a soft failure that can be resolved by using a different domain.

Provide a dedicated errno from the IOMMU driver during attach that the
reason attached failed is because of domain incompatability. EMEDIUMTYPE
is chosen because it is never used within the iommu subsystem today and
evokes a sense that the 'medium' aka the domain is incompatible.

VFIO can use this to know attach is a soft failure and it should continue
searching. Otherwise the attach will be a hard failure and VFIO will
return the code to userspace.

Update all drivers to return EMEDIUMTYPE in their failure paths that are
related to domain incompatability.

Add kdocs describing this behavior.

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/iommu/amd/iommu.c                   |  2 +-
 drivers/iommu/apple-dart.c                  |  4 ++--
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  6 +++---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c     |  2 +-
 drivers/iommu/intel/iommu.c                 |  4 ++--
 drivers/iommu/iommu.c                       | 22 +++++++++++++++++++++
 drivers/iommu/ipmmu-vmsa.c                  |  2 +-
 drivers/iommu/omap-iommu.c                  |  2 +-
 drivers/iommu/virtio-iommu.c                |  2 +-
 9 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 840831d5d2ad..ad499658a6b6 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -1662,7 +1662,7 @@ static int attach_device(struct device *dev,
 	if (domain->flags & PD_IOMMUV2_MASK) {
 		struct iommu_domain *def_domain = iommu_get_dma_domain(dev);
 
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 		if (def_domain->type != IOMMU_DOMAIN_IDENTITY)
 			goto out;
 
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index 8af0242a90d9..e58dc310afd7 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -495,10 +495,10 @@ static int apple_dart_attach_dev(struct iommu_domain *domain,
 
 	if (cfg->stream_maps[0].dart->force_bypass &&
 	    domain->type != IOMMU_DOMAIN_IDENTITY)
-		return -EINVAL;
+		return -EMEDIUMTYPE;
 	if (!cfg->stream_maps[0].dart->supports_bypass &&
 	    domain->type == IOMMU_DOMAIN_IDENTITY)
-		return -EINVAL;
+		return -EMEDIUMTYPE;
 
 	ret = apple_dart_finalize_domain(domain, cfg);
 	if (ret)
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 88817a3376ef..6c393cd84925 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2424,20 +2424,20 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 			"cannot attach to SMMU %s (upstream of %s)\n",
 			dev_name(smmu_domain->smmu->dev),
 			dev_name(smmu->dev));
-		ret = -ENXIO;
+		ret = -EMEDIUMTYPE;
 		goto out_unlock;
 	} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
 		   master->ssid_bits != smmu_domain->s1_cfg.s1cdmax) {
 		dev_err(dev,
 			"cannot attach to incompatible domain (%u SSID bits != %u)\n",
 			smmu_domain->s1_cfg.s1cdmax, master->ssid_bits);
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 		goto out_unlock;
 	} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
 		   smmu_domain->stall_enabled != master->stall_enabled) {
 		dev_err(dev, "cannot attach to stall-%s domain\n",
 			smmu_domain->stall_enabled ? "enabled" : "disabled");
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 		goto out_unlock;
 	}
 
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 4c077c38fbd6..a8b63b855ffb 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -386,7 +386,7 @@ static int qcom_iommu_attach_dev(struct iommu_domain *domain, struct device *dev
 			"attached to domain on IOMMU %s\n",
 			dev_name(qcom_domain->iommu->dev),
 			dev_name(qcom_iommu->dev));
-		return -EINVAL;
+		return -EMEDIUMTYPE;
 	}
 
 	return 0;
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 44016594831d..0813b119d680 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4323,7 +4323,7 @@ static int prepare_domain_attach_device(struct iommu_domain *domain,
 		return -ENODEV;
 
 	if (dmar_domain->force_snooping && !ecap_sc_support(iommu->ecap))
-		return -EOPNOTSUPP;
+		return -EMEDIUMTYPE;
 
 	/* check if this iommu agaw is sufficient for max mapped address */
 	addr_width = agaw_to_width(iommu->agaw);
@@ -4334,7 +4334,7 @@ static int prepare_domain_attach_device(struct iommu_domain *domain,
 		dev_err(dev, "%s: iommu width (%d) is not "
 		        "sufficient for the mapped address (%llx)\n",
 		        __func__, addr_width, dmar_domain->max_addr);
-		return -EFAULT;
+		return -EMEDIUMTYPE;
 	}
 	dmar_domain->gaw = addr_width;
 
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 847ad47a2dfd..19cf28d40ebe 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1972,6 +1972,17 @@ static int __iommu_attach_device(struct iommu_domain *domain,
 	return ret;
 }
 
+/**
+ * iommu_attach_device - Attach a device to an IOMMU domain
+ * @domain: IOMMU domain to attach
+ * @dev: Device that will be attached
+ *
+ * Returns 0 on success and error code on failure
+ *
+ * Specifically, -EMEDIUMTYPE is returned if the domain and the device are
+ * incompatible in some way. This indicates that a caller should try another
+ * existing IOMMU domain or allocate a new one.
+ */
 int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
 {
 	struct iommu_group *group;
@@ -2098,6 +2109,17 @@ static int __iommu_attach_group(struct iommu_domain *domain,
 	return ret;
 }
 
+/**
+ * iommu_attach_group - Attach an IOMMU group to an IOMMU domain
+ * @domain: IOMMU domain to attach
+ * @dev: IOMMU group that will be attached
+ *
+ * Returns 0 on success and error code on failure
+ *
+ * Specifically, -EMEDIUMTYPE is returned if the domain and the group are
+ * incompatible in some way. This indicates that a caller should try another
+ * existing IOMMU domain or allocate a new one.
+ */
 int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group)
 {
 	int ret;
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 8fdb84b3642b..e491e410add5 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -630,7 +630,7 @@ static int ipmmu_attach_device(struct iommu_domain *io_domain,
 		 */
 		dev_err(dev, "Can't attach IPMMU %s to domain on IPMMU %s\n",
 			dev_name(mmu->dev), dev_name(domain->mmu->dev));
-		ret = -EINVAL;
+		ret = -EMEDIUMTYPE;
 	} else
 		dev_info(dev, "Reusing IPMMU context %u\n", domain->context_id);
 
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index d9cf2820c02e..bbc6c4cd7aae 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1472,7 +1472,7 @@ omap_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 	/* only a single client device can be attached to a domain */
 	if (omap_domain->dev) {
 		dev_err(dev, "iommu domain is already attached\n");
-		ret = -EBUSY;
+		ret = -EMEDIUMTYPE;
 		goto out;
 	}
 
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 25be4b822aa0..e3b812d8fa96 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -734,7 +734,7 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 		ret = viommu_domain_finalise(vdev, domain);
 	} else if (vdomain->viommu != vdev->viommu) {
 		dev_err(dev, "cannot attach to foreign vIOMMU\n");
-		ret = -EXDEV;
+		ret = -EMEDIUMTYPE;
 	}
 	mutex_unlock(&vdomain->mutex);
 
-- 
2.17.1


_______________________________________________
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] 138+ messages in thread

* [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
  2022-06-06  6:19 ` Nicolin Chen
                     ` (2 preceding siblings ...)
  (?)
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  -1 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

The core code should not call an iommu driver op with a struct device
parameter unless it knows that the dev_iommu_priv_get() for that struct
device was setup by the same driver. Otherwise in a mixed driver system
the iommu_priv could be casted to the wrong type.

Store the iommu_ops pointer in the iommu_domain and use it as a check to
validate that the struct device is correct before invoking any domain op
that accepts a struct device.

This allows removing the check of the domain op equality in VFIO.

Co-developed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/iommu/amd/iommu.c                   | 1 +
 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/arm/arm-smmu/qcom_iommu.c     | 1 +
 drivers/iommu/exynos-iommu.c                | 1 +
 drivers/iommu/fsl_pamu_domain.c             | 1 +
 drivers/iommu/intel/iommu.c                 | 1 +
 drivers/iommu/iommu.c                       | 4 ++++
 drivers/iommu/ipmmu-vmsa.c                  | 1 +
 drivers/iommu/msm_iommu.c                   | 1 +
 drivers/iommu/mtk_iommu.c                   | 1 +
 drivers/iommu/mtk_iommu_v1.c                | 1 +
 drivers/iommu/omap-iommu.c                  | 1 +
 drivers/iommu/rockchip-iommu.c              | 1 +
 drivers/iommu/s390-iommu.c                  | 1 +
 drivers/iommu/sprd-iommu.c                  | 1 +
 drivers/iommu/sun50i-iommu.c                | 1 +
 drivers/iommu/tegra-gart.c                  | 1 +
 drivers/iommu/tegra-smmu.c                  | 1 +
 drivers/iommu/virtio-iommu.c                | 1 +
 include/linux/iommu.h                       | 2 ++
 22 files changed, 26 insertions(+)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index ad499658a6b6..679f7a265013 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2285,6 +2285,7 @@ const struct iommu_ops amd_iommu_ops = {
 	.pgsize_bitmap	= AMD_IOMMU_PGSIZES,
 	.def_domain_type = amd_iommu_def_domain_type,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &amd_iommu_ops,
 		.attach_dev	= amd_iommu_attach_device,
 		.detach_dev	= amd_iommu_detach_device,
 		.map		= amd_iommu_map,
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index e58dc310afd7..3d36d9a12aa7 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -775,6 +775,7 @@ static const struct iommu_ops apple_dart_iommu_ops = {
 	.pgsize_bitmap = -1UL, /* Restricted during dart probe */
 	.owner = THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &apple_dart_iommu_ops,
 		.attach_dev	= apple_dart_attach_dev,
 		.detach_dev	= apple_dart_detach_dev,
 		.map_pages	= apple_dart_map_pages,
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 6c393cd84925..471ceb60427c 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2859,6 +2859,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &arm_smmu_ops,
 		.attach_dev		= arm_smmu_attach_dev,
 		.map_pages		= arm_smmu_map_pages,
 		.unmap_pages		= arm_smmu_unmap_pages,
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 2ed3594f384e..52c2589a4deb 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1597,6 +1597,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &arm_smmu_ops,
 		.attach_dev		= arm_smmu_attach_dev,
 		.map_pages		= arm_smmu_map_pages,
 		.unmap_pages		= arm_smmu_unmap_pages,
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index a8b63b855ffb..8806a621f81e 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -596,6 +596,7 @@ static const struct iommu_ops qcom_iommu_ops = {
 	.of_xlate	= qcom_iommu_of_xlate,
 	.pgsize_bitmap	= SZ_4K | SZ_64K | SZ_1M | SZ_16M,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &qcom_iommu_ops,
 		.attach_dev	= qcom_iommu_attach_dev,
 		.detach_dev	= qcom_iommu_detach_dev,
 		.map		= qcom_iommu_map,
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 71f2018e23fe..fa93f94313e3 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1315,6 +1315,7 @@ static const struct iommu_ops exynos_iommu_ops = {
 	.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
 	.of_xlate = exynos_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &exynos_iommu_ops,
 		.attach_dev	= exynos_iommu_attach_device,
 		.detach_dev	= exynos_iommu_detach_device,
 		.map		= exynos_iommu_map,
diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index 94b4589dc67c..7bdce4168d2c 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -458,6 +458,7 @@ static const struct iommu_ops fsl_pamu_ops = {
 	.release_device	= fsl_pamu_release_device,
 	.device_group   = fsl_pamu_device_group,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &fsl_pamu_ops,
 		.attach_dev	= fsl_pamu_attach_device,
 		.detach_dev	= fsl_pamu_detach_device,
 		.iova_to_phys	= fsl_pamu_iova_to_phys,
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 0813b119d680..c6022484ca2d 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4925,6 +4925,7 @@ const struct iommu_ops intel_iommu_ops = {
 	.page_response		= intel_svm_page_response,
 #endif
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &intel_iommu_ops,
 		.attach_dev		= intel_iommu_attach_device,
 		.detach_dev		= intel_iommu_detach_device,
 		.map_pages		= intel_iommu_map_pages,
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 19cf28d40ebe..8a1f437a51f2 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1963,6 +1963,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
 {
 	int ret;
 
+	/* Ensure the device was probe'd onto the same driver as the domain */
+	if (dev->bus->iommu_ops != domain->ops->iommu_ops)
+		return -EMEDIUMTYPE;
+
 	if (unlikely(domain->ops->attach_dev == NULL))
 		return -ENODEV;
 
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index e491e410add5..767b93da5800 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -877,6 +877,7 @@ static const struct iommu_ops ipmmu_ops = {
 	.pgsize_bitmap = SZ_1G | SZ_2M | SZ_4K,
 	.of_xlate = ipmmu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &ipmmu_ops,
 		.attach_dev	= ipmmu_attach_device,
 		.detach_dev	= ipmmu_detach_device,
 		.map		= ipmmu_map,
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index f09aedfdd462..29f6a6d5691e 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -682,6 +682,7 @@ static struct iommu_ops msm_iommu_ops = {
 	.pgsize_bitmap = MSM_IOMMU_PGSIZES,
 	.of_xlate = qcom_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &msm_iommu_ops,
 		.attach_dev	= msm_iommu_attach_dev,
 		.detach_dev	= msm_iommu_detach_dev,
 		.map		= msm_iommu_map,
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index bb9dd92c9898..c5c45f65077d 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -937,6 +937,7 @@ static const struct iommu_ops mtk_iommu_ops = {
 	.pgsize_bitmap	= SZ_4K | SZ_64K | SZ_1M | SZ_16M,
 	.owner		= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &mtk_iommu_ops,
 		.attach_dev	= mtk_iommu_attach_device,
 		.detach_dev	= mtk_iommu_detach_device,
 		.map		= mtk_iommu_map,
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index e1cb51b9866c..77c53580f730 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -594,6 +594,7 @@ static const struct iommu_ops mtk_iommu_v1_ops = {
 	.pgsize_bitmap	= ~0UL << MT2701_IOMMU_PAGE_SHIFT,
 	.owner          = THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &mtk_iommu_v1_ops,
 		.attach_dev	= mtk_iommu_v1_attach_device,
 		.detach_dev	= mtk_iommu_v1_detach_device,
 		.map		= mtk_iommu_v1_map,
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index bbc6c4cd7aae..a0bf85ccebcd 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1739,6 +1739,7 @@ static const struct iommu_ops omap_iommu_ops = {
 	.device_group	= omap_iommu_device_group,
 	.pgsize_bitmap	= OMAP_IOMMU_PGSIZES,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &omap_iommu_ops,
 		.attach_dev	= omap_iommu_attach_dev,
 		.detach_dev	= omap_iommu_detach_dev,
 		.map		= omap_iommu_map,
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index ab57c4b8fade..5f5387e902e0 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1193,6 +1193,7 @@ static const struct iommu_ops rk_iommu_ops = {
 	.pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
 	.of_xlate = rk_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &rk_iommu_ops,
 		.attach_dev	= rk_iommu_attach_device,
 		.detach_dev	= rk_iommu_detach_device,
 		.map		= rk_iommu_map,
diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
index c898bcbbce11..62e6d152b0a0 100644
--- a/drivers/iommu/s390-iommu.c
+++ b/drivers/iommu/s390-iommu.c
@@ -377,6 +377,7 @@ static const struct iommu_ops s390_iommu_ops = {
 	.device_group = generic_device_group,
 	.pgsize_bitmap = S390_IOMMU_PGSIZES,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &s390_iommu_ops,
 		.attach_dev	= s390_iommu_attach_device,
 		.detach_dev	= s390_iommu_detach_device,
 		.map		= s390_iommu_map,
diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c
index bd409bab6286..6e8ca34d6a00 100644
--- a/drivers/iommu/sprd-iommu.c
+++ b/drivers/iommu/sprd-iommu.c
@@ -423,6 +423,7 @@ static const struct iommu_ops sprd_iommu_ops = {
 	.pgsize_bitmap	= ~0UL << SPRD_IOMMU_PAGE_SHIFT,
 	.owner		= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &sprd_iommu_ops,
 		.attach_dev	= sprd_iommu_attach_device,
 		.detach_dev	= sprd_iommu_detach_device,
 		.map		= sprd_iommu_map,
diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
index c54ab477b8fd..560cff8e0f04 100644
--- a/drivers/iommu/sun50i-iommu.c
+++ b/drivers/iommu/sun50i-iommu.c
@@ -766,6 +766,7 @@ static const struct iommu_ops sun50i_iommu_ops = {
 	.probe_device	= sun50i_iommu_probe_device,
 	.release_device	= sun50i_iommu_release_device,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &sun50i_iommu_ops,
 		.attach_dev	= sun50i_iommu_attach_device,
 		.detach_dev	= sun50i_iommu_detach_device,
 		.flush_iotlb_all = sun50i_iommu_flush_iotlb_all,
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index a6700a40a6f8..cd4553611cc9 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -278,6 +278,7 @@ static const struct iommu_ops gart_iommu_ops = {
 	.pgsize_bitmap	= GART_IOMMU_PGSIZES,
 	.of_xlate	= gart_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &gart_iommu_ops,
 		.attach_dev	= gart_iommu_attach_dev,
 		.detach_dev	= gart_iommu_detach_dev,
 		.map		= gart_iommu_map,
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 2f2b12033618..67c101d1ad66 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -971,6 +971,7 @@ static const struct iommu_ops tegra_smmu_ops = {
 	.of_xlate = tegra_smmu_of_xlate,
 	.pgsize_bitmap = SZ_4K,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &tegra_smmu_ops,
 		.attach_dev	= tegra_smmu_attach_dev,
 		.detach_dev	= tegra_smmu_detach_dev,
 		.map		= tegra_smmu_map,
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index e3b812d8fa96..703d87922786 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -1017,6 +1017,7 @@ static struct iommu_ops viommu_ops = {
 	.of_xlate		= viommu_of_xlate,
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &viommu_ops,
 		.attach_dev		= viommu_attach_dev,
 		.map			= viommu_map,
 		.unmap			= viommu_unmap,
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 5e1afe169549..77deaf4fc7f8 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -261,6 +261,7 @@ struct iommu_ops {
 
 /**
  * struct iommu_domain_ops - domain specific operations
+ * @iommu_ops: Pointer to the ops associated with compatible devices
  * @attach_dev: attach an iommu domain to a device
  * @detach_dev: detach an iommu domain from a device
  * @map: map a physically contiguous memory region to an iommu domain
@@ -281,6 +282,7 @@ struct iommu_ops {
  * @free: Release the domain after use.
  */
 struct iommu_domain_ops {
+	const struct iommu_ops *iommu_ops;
 	int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
 	void (*detach_dev)(struct iommu_domain *domain, struct device *dev);
 
-- 
2.17.1


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

* [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen via iommu @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

The core code should not call an iommu driver op with a struct device
parameter unless it knows that the dev_iommu_priv_get() for that struct
device was setup by the same driver. Otherwise in a mixed driver system
the iommu_priv could be casted to the wrong type.

Store the iommu_ops pointer in the iommu_domain and use it as a check to
validate that the struct device is correct before invoking any domain op
that accepts a struct device.

This allows removing the check of the domain op equality in VFIO.

Co-developed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/iommu/amd/iommu.c                   | 1 +
 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/arm/arm-smmu/qcom_iommu.c     | 1 +
 drivers/iommu/exynos-iommu.c                | 1 +
 drivers/iommu/fsl_pamu_domain.c             | 1 +
 drivers/iommu/intel/iommu.c                 | 1 +
 drivers/iommu/iommu.c                       | 4 ++++
 drivers/iommu/ipmmu-vmsa.c                  | 1 +
 drivers/iommu/msm_iommu.c                   | 1 +
 drivers/iommu/mtk_iommu.c                   | 1 +
 drivers/iommu/mtk_iommu_v1.c                | 1 +
 drivers/iommu/omap-iommu.c                  | 1 +
 drivers/iommu/rockchip-iommu.c              | 1 +
 drivers/iommu/s390-iommu.c                  | 1 +
 drivers/iommu/sprd-iommu.c                  | 1 +
 drivers/iommu/sun50i-iommu.c                | 1 +
 drivers/iommu/tegra-gart.c                  | 1 +
 drivers/iommu/tegra-smmu.c                  | 1 +
 drivers/iommu/virtio-iommu.c                | 1 +
 include/linux/iommu.h                       | 2 ++
 22 files changed, 26 insertions(+)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index ad499658a6b6..679f7a265013 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2285,6 +2285,7 @@ const struct iommu_ops amd_iommu_ops = {
 	.pgsize_bitmap	= AMD_IOMMU_PGSIZES,
 	.def_domain_type = amd_iommu_def_domain_type,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &amd_iommu_ops,
 		.attach_dev	= amd_iommu_attach_device,
 		.detach_dev	= amd_iommu_detach_device,
 		.map		= amd_iommu_map,
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index e58dc310afd7..3d36d9a12aa7 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -775,6 +775,7 @@ static const struct iommu_ops apple_dart_iommu_ops = {
 	.pgsize_bitmap = -1UL, /* Restricted during dart probe */
 	.owner = THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &apple_dart_iommu_ops,
 		.attach_dev	= apple_dart_attach_dev,
 		.detach_dev	= apple_dart_detach_dev,
 		.map_pages	= apple_dart_map_pages,
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 6c393cd84925..471ceb60427c 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2859,6 +2859,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &arm_smmu_ops,
 		.attach_dev		= arm_smmu_attach_dev,
 		.map_pages		= arm_smmu_map_pages,
 		.unmap_pages		= arm_smmu_unmap_pages,
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 2ed3594f384e..52c2589a4deb 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1597,6 +1597,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &arm_smmu_ops,
 		.attach_dev		= arm_smmu_attach_dev,
 		.map_pages		= arm_smmu_map_pages,
 		.unmap_pages		= arm_smmu_unmap_pages,
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index a8b63b855ffb..8806a621f81e 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -596,6 +596,7 @@ static const struct iommu_ops qcom_iommu_ops = {
 	.of_xlate	= qcom_iommu_of_xlate,
 	.pgsize_bitmap	= SZ_4K | SZ_64K | SZ_1M | SZ_16M,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &qcom_iommu_ops,
 		.attach_dev	= qcom_iommu_attach_dev,
 		.detach_dev	= qcom_iommu_detach_dev,
 		.map		= qcom_iommu_map,
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 71f2018e23fe..fa93f94313e3 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1315,6 +1315,7 @@ static const struct iommu_ops exynos_iommu_ops = {
 	.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
 	.of_xlate = exynos_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &exynos_iommu_ops,
 		.attach_dev	= exynos_iommu_attach_device,
 		.detach_dev	= exynos_iommu_detach_device,
 		.map		= exynos_iommu_map,
diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index 94b4589dc67c..7bdce4168d2c 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -458,6 +458,7 @@ static const struct iommu_ops fsl_pamu_ops = {
 	.release_device	= fsl_pamu_release_device,
 	.device_group   = fsl_pamu_device_group,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &fsl_pamu_ops,
 		.attach_dev	= fsl_pamu_attach_device,
 		.detach_dev	= fsl_pamu_detach_device,
 		.iova_to_phys	= fsl_pamu_iova_to_phys,
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 0813b119d680..c6022484ca2d 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4925,6 +4925,7 @@ const struct iommu_ops intel_iommu_ops = {
 	.page_response		= intel_svm_page_response,
 #endif
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &intel_iommu_ops,
 		.attach_dev		= intel_iommu_attach_device,
 		.detach_dev		= intel_iommu_detach_device,
 		.map_pages		= intel_iommu_map_pages,
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 19cf28d40ebe..8a1f437a51f2 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1963,6 +1963,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
 {
 	int ret;
 
+	/* Ensure the device was probe'd onto the same driver as the domain */
+	if (dev->bus->iommu_ops != domain->ops->iommu_ops)
+		return -EMEDIUMTYPE;
+
 	if (unlikely(domain->ops->attach_dev == NULL))
 		return -ENODEV;
 
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index e491e410add5..767b93da5800 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -877,6 +877,7 @@ static const struct iommu_ops ipmmu_ops = {
 	.pgsize_bitmap = SZ_1G | SZ_2M | SZ_4K,
 	.of_xlate = ipmmu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &ipmmu_ops,
 		.attach_dev	= ipmmu_attach_device,
 		.detach_dev	= ipmmu_detach_device,
 		.map		= ipmmu_map,
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index f09aedfdd462..29f6a6d5691e 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -682,6 +682,7 @@ static struct iommu_ops msm_iommu_ops = {
 	.pgsize_bitmap = MSM_IOMMU_PGSIZES,
 	.of_xlate = qcom_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &msm_iommu_ops,
 		.attach_dev	= msm_iommu_attach_dev,
 		.detach_dev	= msm_iommu_detach_dev,
 		.map		= msm_iommu_map,
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index bb9dd92c9898..c5c45f65077d 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -937,6 +937,7 @@ static const struct iommu_ops mtk_iommu_ops = {
 	.pgsize_bitmap	= SZ_4K | SZ_64K | SZ_1M | SZ_16M,
 	.owner		= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &mtk_iommu_ops,
 		.attach_dev	= mtk_iommu_attach_device,
 		.detach_dev	= mtk_iommu_detach_device,
 		.map		= mtk_iommu_map,
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index e1cb51b9866c..77c53580f730 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -594,6 +594,7 @@ static const struct iommu_ops mtk_iommu_v1_ops = {
 	.pgsize_bitmap	= ~0UL << MT2701_IOMMU_PAGE_SHIFT,
 	.owner          = THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &mtk_iommu_v1_ops,
 		.attach_dev	= mtk_iommu_v1_attach_device,
 		.detach_dev	= mtk_iommu_v1_detach_device,
 		.map		= mtk_iommu_v1_map,
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index bbc6c4cd7aae..a0bf85ccebcd 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1739,6 +1739,7 @@ static const struct iommu_ops omap_iommu_ops = {
 	.device_group	= omap_iommu_device_group,
 	.pgsize_bitmap	= OMAP_IOMMU_PGSIZES,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &omap_iommu_ops,
 		.attach_dev	= omap_iommu_attach_dev,
 		.detach_dev	= omap_iommu_detach_dev,
 		.map		= omap_iommu_map,
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index ab57c4b8fade..5f5387e902e0 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1193,6 +1193,7 @@ static const struct iommu_ops rk_iommu_ops = {
 	.pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
 	.of_xlate = rk_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &rk_iommu_ops,
 		.attach_dev	= rk_iommu_attach_device,
 		.detach_dev	= rk_iommu_detach_device,
 		.map		= rk_iommu_map,
diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
index c898bcbbce11..62e6d152b0a0 100644
--- a/drivers/iommu/s390-iommu.c
+++ b/drivers/iommu/s390-iommu.c
@@ -377,6 +377,7 @@ static const struct iommu_ops s390_iommu_ops = {
 	.device_group = generic_device_group,
 	.pgsize_bitmap = S390_IOMMU_PGSIZES,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &s390_iommu_ops,
 		.attach_dev	= s390_iommu_attach_device,
 		.detach_dev	= s390_iommu_detach_device,
 		.map		= s390_iommu_map,
diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c
index bd409bab6286..6e8ca34d6a00 100644
--- a/drivers/iommu/sprd-iommu.c
+++ b/drivers/iommu/sprd-iommu.c
@@ -423,6 +423,7 @@ static const struct iommu_ops sprd_iommu_ops = {
 	.pgsize_bitmap	= ~0UL << SPRD_IOMMU_PAGE_SHIFT,
 	.owner		= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &sprd_iommu_ops,
 		.attach_dev	= sprd_iommu_attach_device,
 		.detach_dev	= sprd_iommu_detach_device,
 		.map		= sprd_iommu_map,
diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
index c54ab477b8fd..560cff8e0f04 100644
--- a/drivers/iommu/sun50i-iommu.c
+++ b/drivers/iommu/sun50i-iommu.c
@@ -766,6 +766,7 @@ static const struct iommu_ops sun50i_iommu_ops = {
 	.probe_device	= sun50i_iommu_probe_device,
 	.release_device	= sun50i_iommu_release_device,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &sun50i_iommu_ops,
 		.attach_dev	= sun50i_iommu_attach_device,
 		.detach_dev	= sun50i_iommu_detach_device,
 		.flush_iotlb_all = sun50i_iommu_flush_iotlb_all,
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index a6700a40a6f8..cd4553611cc9 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -278,6 +278,7 @@ static const struct iommu_ops gart_iommu_ops = {
 	.pgsize_bitmap	= GART_IOMMU_PGSIZES,
 	.of_xlate	= gart_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &gart_iommu_ops,
 		.attach_dev	= gart_iommu_attach_dev,
 		.detach_dev	= gart_iommu_detach_dev,
 		.map		= gart_iommu_map,
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 2f2b12033618..67c101d1ad66 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -971,6 +971,7 @@ static const struct iommu_ops tegra_smmu_ops = {
 	.of_xlate = tegra_smmu_of_xlate,
 	.pgsize_bitmap = SZ_4K,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &tegra_smmu_ops,
 		.attach_dev	= tegra_smmu_attach_dev,
 		.detach_dev	= tegra_smmu_detach_dev,
 		.map		= tegra_smmu_map,
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index e3b812d8fa96..703d87922786 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -1017,6 +1017,7 @@ static struct iommu_ops viommu_ops = {
 	.of_xlate		= viommu_of_xlate,
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &viommu_ops,
 		.attach_dev		= viommu_attach_dev,
 		.map			= viommu_map,
 		.unmap			= viommu_unmap,
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 5e1afe169549..77deaf4fc7f8 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -261,6 +261,7 @@ struct iommu_ops {
 
 /**
  * struct iommu_domain_ops - domain specific operations
+ * @iommu_ops: Pointer to the ops associated with compatible devices
  * @attach_dev: attach an iommu domain to a device
  * @detach_dev: detach an iommu domain from a device
  * @map: map a physically contiguous memory region to an iommu domain
@@ -281,6 +282,7 @@ struct iommu_ops {
  * @free: Release the domain after use.
  */
 struct iommu_domain_ops {
+	const struct iommu_ops *iommu_ops;
 	int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
 	void (*detach_dev)(struct iommu_domain *domain, struct device *dev);
 
-- 
2.17.1

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

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

* [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

The core code should not call an iommu driver op with a struct device
parameter unless it knows that the dev_iommu_priv_get() for that struct
device was setup by the same driver. Otherwise in a mixed driver system
the iommu_priv could be casted to the wrong type.

Store the iommu_ops pointer in the iommu_domain and use it as a check to
validate that the struct device is correct before invoking any domain op
that accepts a struct device.

This allows removing the check of the domain op equality in VFIO.

Co-developed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/iommu/amd/iommu.c                   | 1 +
 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/arm/arm-smmu/qcom_iommu.c     | 1 +
 drivers/iommu/exynos-iommu.c                | 1 +
 drivers/iommu/fsl_pamu_domain.c             | 1 +
 drivers/iommu/intel/iommu.c                 | 1 +
 drivers/iommu/iommu.c                       | 4 ++++
 drivers/iommu/ipmmu-vmsa.c                  | 1 +
 drivers/iommu/msm_iommu.c                   | 1 +
 drivers/iommu/mtk_iommu.c                   | 1 +
 drivers/iommu/mtk_iommu_v1.c                | 1 +
 drivers/iommu/omap-iommu.c                  | 1 +
 drivers/iommu/rockchip-iommu.c              | 1 +
 drivers/iommu/s390-iommu.c                  | 1 +
 drivers/iommu/sprd-iommu.c                  | 1 +
 drivers/iommu/sun50i-iommu.c                | 1 +
 drivers/iommu/tegra-gart.c                  | 1 +
 drivers/iommu/tegra-smmu.c                  | 1 +
 drivers/iommu/virtio-iommu.c                | 1 +
 include/linux/iommu.h                       | 2 ++
 22 files changed, 26 insertions(+)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index ad499658a6b6..679f7a265013 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2285,6 +2285,7 @@ const struct iommu_ops amd_iommu_ops = {
 	.pgsize_bitmap	= AMD_IOMMU_PGSIZES,
 	.def_domain_type = amd_iommu_def_domain_type,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &amd_iommu_ops,
 		.attach_dev	= amd_iommu_attach_device,
 		.detach_dev	= amd_iommu_detach_device,
 		.map		= amd_iommu_map,
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index e58dc310afd7..3d36d9a12aa7 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -775,6 +775,7 @@ static const struct iommu_ops apple_dart_iommu_ops = {
 	.pgsize_bitmap = -1UL, /* Restricted during dart probe */
 	.owner = THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &apple_dart_iommu_ops,
 		.attach_dev	= apple_dart_attach_dev,
 		.detach_dev	= apple_dart_detach_dev,
 		.map_pages	= apple_dart_map_pages,
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 6c393cd84925..471ceb60427c 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2859,6 +2859,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &arm_smmu_ops,
 		.attach_dev		= arm_smmu_attach_dev,
 		.map_pages		= arm_smmu_map_pages,
 		.unmap_pages		= arm_smmu_unmap_pages,
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 2ed3594f384e..52c2589a4deb 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1597,6 +1597,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &arm_smmu_ops,
 		.attach_dev		= arm_smmu_attach_dev,
 		.map_pages		= arm_smmu_map_pages,
 		.unmap_pages		= arm_smmu_unmap_pages,
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index a8b63b855ffb..8806a621f81e 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -596,6 +596,7 @@ static const struct iommu_ops qcom_iommu_ops = {
 	.of_xlate	= qcom_iommu_of_xlate,
 	.pgsize_bitmap	= SZ_4K | SZ_64K | SZ_1M | SZ_16M,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &qcom_iommu_ops,
 		.attach_dev	= qcom_iommu_attach_dev,
 		.detach_dev	= qcom_iommu_detach_dev,
 		.map		= qcom_iommu_map,
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 71f2018e23fe..fa93f94313e3 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1315,6 +1315,7 @@ static const struct iommu_ops exynos_iommu_ops = {
 	.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
 	.of_xlate = exynos_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &exynos_iommu_ops,
 		.attach_dev	= exynos_iommu_attach_device,
 		.detach_dev	= exynos_iommu_detach_device,
 		.map		= exynos_iommu_map,
diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index 94b4589dc67c..7bdce4168d2c 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -458,6 +458,7 @@ static const struct iommu_ops fsl_pamu_ops = {
 	.release_device	= fsl_pamu_release_device,
 	.device_group   = fsl_pamu_device_group,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &fsl_pamu_ops,
 		.attach_dev	= fsl_pamu_attach_device,
 		.detach_dev	= fsl_pamu_detach_device,
 		.iova_to_phys	= fsl_pamu_iova_to_phys,
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 0813b119d680..c6022484ca2d 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4925,6 +4925,7 @@ const struct iommu_ops intel_iommu_ops = {
 	.page_response		= intel_svm_page_response,
 #endif
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &intel_iommu_ops,
 		.attach_dev		= intel_iommu_attach_device,
 		.detach_dev		= intel_iommu_detach_device,
 		.map_pages		= intel_iommu_map_pages,
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 19cf28d40ebe..8a1f437a51f2 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1963,6 +1963,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
 {
 	int ret;
 
+	/* Ensure the device was probe'd onto the same driver as the domain */
+	if (dev->bus->iommu_ops != domain->ops->iommu_ops)
+		return -EMEDIUMTYPE;
+
 	if (unlikely(domain->ops->attach_dev == NULL))
 		return -ENODEV;
 
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index e491e410add5..767b93da5800 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -877,6 +877,7 @@ static const struct iommu_ops ipmmu_ops = {
 	.pgsize_bitmap = SZ_1G | SZ_2M | SZ_4K,
 	.of_xlate = ipmmu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &ipmmu_ops,
 		.attach_dev	= ipmmu_attach_device,
 		.detach_dev	= ipmmu_detach_device,
 		.map		= ipmmu_map,
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index f09aedfdd462..29f6a6d5691e 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -682,6 +682,7 @@ static struct iommu_ops msm_iommu_ops = {
 	.pgsize_bitmap = MSM_IOMMU_PGSIZES,
 	.of_xlate = qcom_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &msm_iommu_ops,
 		.attach_dev	= msm_iommu_attach_dev,
 		.detach_dev	= msm_iommu_detach_dev,
 		.map		= msm_iommu_map,
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index bb9dd92c9898..c5c45f65077d 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -937,6 +937,7 @@ static const struct iommu_ops mtk_iommu_ops = {
 	.pgsize_bitmap	= SZ_4K | SZ_64K | SZ_1M | SZ_16M,
 	.owner		= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &mtk_iommu_ops,
 		.attach_dev	= mtk_iommu_attach_device,
 		.detach_dev	= mtk_iommu_detach_device,
 		.map		= mtk_iommu_map,
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index e1cb51b9866c..77c53580f730 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -594,6 +594,7 @@ static const struct iommu_ops mtk_iommu_v1_ops = {
 	.pgsize_bitmap	= ~0UL << MT2701_IOMMU_PAGE_SHIFT,
 	.owner          = THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &mtk_iommu_v1_ops,
 		.attach_dev	= mtk_iommu_v1_attach_device,
 		.detach_dev	= mtk_iommu_v1_detach_device,
 		.map		= mtk_iommu_v1_map,
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index bbc6c4cd7aae..a0bf85ccebcd 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1739,6 +1739,7 @@ static const struct iommu_ops omap_iommu_ops = {
 	.device_group	= omap_iommu_device_group,
 	.pgsize_bitmap	= OMAP_IOMMU_PGSIZES,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &omap_iommu_ops,
 		.attach_dev	= omap_iommu_attach_dev,
 		.detach_dev	= omap_iommu_detach_dev,
 		.map		= omap_iommu_map,
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index ab57c4b8fade..5f5387e902e0 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1193,6 +1193,7 @@ static const struct iommu_ops rk_iommu_ops = {
 	.pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
 	.of_xlate = rk_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &rk_iommu_ops,
 		.attach_dev	= rk_iommu_attach_device,
 		.detach_dev	= rk_iommu_detach_device,
 		.map		= rk_iommu_map,
diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
index c898bcbbce11..62e6d152b0a0 100644
--- a/drivers/iommu/s390-iommu.c
+++ b/drivers/iommu/s390-iommu.c
@@ -377,6 +377,7 @@ static const struct iommu_ops s390_iommu_ops = {
 	.device_group = generic_device_group,
 	.pgsize_bitmap = S390_IOMMU_PGSIZES,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &s390_iommu_ops,
 		.attach_dev	= s390_iommu_attach_device,
 		.detach_dev	= s390_iommu_detach_device,
 		.map		= s390_iommu_map,
diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c
index bd409bab6286..6e8ca34d6a00 100644
--- a/drivers/iommu/sprd-iommu.c
+++ b/drivers/iommu/sprd-iommu.c
@@ -423,6 +423,7 @@ static const struct iommu_ops sprd_iommu_ops = {
 	.pgsize_bitmap	= ~0UL << SPRD_IOMMU_PAGE_SHIFT,
 	.owner		= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &sprd_iommu_ops,
 		.attach_dev	= sprd_iommu_attach_device,
 		.detach_dev	= sprd_iommu_detach_device,
 		.map		= sprd_iommu_map,
diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
index c54ab477b8fd..560cff8e0f04 100644
--- a/drivers/iommu/sun50i-iommu.c
+++ b/drivers/iommu/sun50i-iommu.c
@@ -766,6 +766,7 @@ static const struct iommu_ops sun50i_iommu_ops = {
 	.probe_device	= sun50i_iommu_probe_device,
 	.release_device	= sun50i_iommu_release_device,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &sun50i_iommu_ops,
 		.attach_dev	= sun50i_iommu_attach_device,
 		.detach_dev	= sun50i_iommu_detach_device,
 		.flush_iotlb_all = sun50i_iommu_flush_iotlb_all,
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index a6700a40a6f8..cd4553611cc9 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -278,6 +278,7 @@ static const struct iommu_ops gart_iommu_ops = {
 	.pgsize_bitmap	= GART_IOMMU_PGSIZES,
 	.of_xlate	= gart_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &gart_iommu_ops,
 		.attach_dev	= gart_iommu_attach_dev,
 		.detach_dev	= gart_iommu_detach_dev,
 		.map		= gart_iommu_map,
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 2f2b12033618..67c101d1ad66 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -971,6 +971,7 @@ static const struct iommu_ops tegra_smmu_ops = {
 	.of_xlate = tegra_smmu_of_xlate,
 	.pgsize_bitmap = SZ_4K,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &tegra_smmu_ops,
 		.attach_dev	= tegra_smmu_attach_dev,
 		.detach_dev	= tegra_smmu_detach_dev,
 		.map		= tegra_smmu_map,
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index e3b812d8fa96..703d87922786 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -1017,6 +1017,7 @@ static struct iommu_ops viommu_ops = {
 	.of_xlate		= viommu_of_xlate,
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &viommu_ops,
 		.attach_dev		= viommu_attach_dev,
 		.map			= viommu_map,
 		.unmap			= viommu_unmap,
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 5e1afe169549..77deaf4fc7f8 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -261,6 +261,7 @@ struct iommu_ops {
 
 /**
  * struct iommu_domain_ops - domain specific operations
+ * @iommu_ops: Pointer to the ops associated with compatible devices
  * @attach_dev: attach an iommu domain to a device
  * @detach_dev: detach an iommu domain from a device
  * @map: map a physically contiguous memory region to an iommu domain
@@ -281,6 +282,7 @@ struct iommu_ops {
  * @free: Release the domain after use.
  */
 struct iommu_domain_ops {
+	const struct iommu_ops *iommu_ops;
 	int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
 	void (*detach_dev)(struct iommu_domain *domain, struct device *dev);
 
-- 
2.17.1


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

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

* [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

The core code should not call an iommu driver op with a struct device
parameter unless it knows that the dev_iommu_priv_get() for that struct
device was setup by the same driver. Otherwise in a mixed driver system
the iommu_priv could be casted to the wrong type.

Store the iommu_ops pointer in the iommu_domain and use it as a check to
validate that the struct device is correct before invoking any domain op
that accepts a struct device.

This allows removing the check of the domain op equality in VFIO.

Co-developed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/iommu/amd/iommu.c                   | 1 +
 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/arm/arm-smmu/qcom_iommu.c     | 1 +
 drivers/iommu/exynos-iommu.c                | 1 +
 drivers/iommu/fsl_pamu_domain.c             | 1 +
 drivers/iommu/intel/iommu.c                 | 1 +
 drivers/iommu/iommu.c                       | 4 ++++
 drivers/iommu/ipmmu-vmsa.c                  | 1 +
 drivers/iommu/msm_iommu.c                   | 1 +
 drivers/iommu/mtk_iommu.c                   | 1 +
 drivers/iommu/mtk_iommu_v1.c                | 1 +
 drivers/iommu/omap-iommu.c                  | 1 +
 drivers/iommu/rockchip-iommu.c              | 1 +
 drivers/iommu/s390-iommu.c                  | 1 +
 drivers/iommu/sprd-iommu.c                  | 1 +
 drivers/iommu/sun50i-iommu.c                | 1 +
 drivers/iommu/tegra-gart.c                  | 1 +
 drivers/iommu/tegra-smmu.c                  | 1 +
 drivers/iommu/virtio-iommu.c                | 1 +
 include/linux/iommu.h                       | 2 ++
 22 files changed, 26 insertions(+)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index ad499658a6b6..679f7a265013 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2285,6 +2285,7 @@ const struct iommu_ops amd_iommu_ops = {
 	.pgsize_bitmap	= AMD_IOMMU_PGSIZES,
 	.def_domain_type = amd_iommu_def_domain_type,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &amd_iommu_ops,
 		.attach_dev	= amd_iommu_attach_device,
 		.detach_dev	= amd_iommu_detach_device,
 		.map		= amd_iommu_map,
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index e58dc310afd7..3d36d9a12aa7 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -775,6 +775,7 @@ static const struct iommu_ops apple_dart_iommu_ops = {
 	.pgsize_bitmap = -1UL, /* Restricted during dart probe */
 	.owner = THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &apple_dart_iommu_ops,
 		.attach_dev	= apple_dart_attach_dev,
 		.detach_dev	= apple_dart_detach_dev,
 		.map_pages	= apple_dart_map_pages,
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 6c393cd84925..471ceb60427c 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2859,6 +2859,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &arm_smmu_ops,
 		.attach_dev		= arm_smmu_attach_dev,
 		.map_pages		= arm_smmu_map_pages,
 		.unmap_pages		= arm_smmu_unmap_pages,
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 2ed3594f384e..52c2589a4deb 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1597,6 +1597,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &arm_smmu_ops,
 		.attach_dev		= arm_smmu_attach_dev,
 		.map_pages		= arm_smmu_map_pages,
 		.unmap_pages		= arm_smmu_unmap_pages,
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index a8b63b855ffb..8806a621f81e 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -596,6 +596,7 @@ static const struct iommu_ops qcom_iommu_ops = {
 	.of_xlate	= qcom_iommu_of_xlate,
 	.pgsize_bitmap	= SZ_4K | SZ_64K | SZ_1M | SZ_16M,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &qcom_iommu_ops,
 		.attach_dev	= qcom_iommu_attach_dev,
 		.detach_dev	= qcom_iommu_detach_dev,
 		.map		= qcom_iommu_map,
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 71f2018e23fe..fa93f94313e3 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1315,6 +1315,7 @@ static const struct iommu_ops exynos_iommu_ops = {
 	.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
 	.of_xlate = exynos_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &exynos_iommu_ops,
 		.attach_dev	= exynos_iommu_attach_device,
 		.detach_dev	= exynos_iommu_detach_device,
 		.map		= exynos_iommu_map,
diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index 94b4589dc67c..7bdce4168d2c 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -458,6 +458,7 @@ static const struct iommu_ops fsl_pamu_ops = {
 	.release_device	= fsl_pamu_release_device,
 	.device_group   = fsl_pamu_device_group,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &fsl_pamu_ops,
 		.attach_dev	= fsl_pamu_attach_device,
 		.detach_dev	= fsl_pamu_detach_device,
 		.iova_to_phys	= fsl_pamu_iova_to_phys,
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 0813b119d680..c6022484ca2d 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4925,6 +4925,7 @@ const struct iommu_ops intel_iommu_ops = {
 	.page_response		= intel_svm_page_response,
 #endif
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &intel_iommu_ops,
 		.attach_dev		= intel_iommu_attach_device,
 		.detach_dev		= intel_iommu_detach_device,
 		.map_pages		= intel_iommu_map_pages,
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 19cf28d40ebe..8a1f437a51f2 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1963,6 +1963,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
 {
 	int ret;
 
+	/* Ensure the device was probe'd onto the same driver as the domain */
+	if (dev->bus->iommu_ops != domain->ops->iommu_ops)
+		return -EMEDIUMTYPE;
+
 	if (unlikely(domain->ops->attach_dev == NULL))
 		return -ENODEV;
 
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index e491e410add5..767b93da5800 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -877,6 +877,7 @@ static const struct iommu_ops ipmmu_ops = {
 	.pgsize_bitmap = SZ_1G | SZ_2M | SZ_4K,
 	.of_xlate = ipmmu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &ipmmu_ops,
 		.attach_dev	= ipmmu_attach_device,
 		.detach_dev	= ipmmu_detach_device,
 		.map		= ipmmu_map,
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index f09aedfdd462..29f6a6d5691e 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -682,6 +682,7 @@ static struct iommu_ops msm_iommu_ops = {
 	.pgsize_bitmap = MSM_IOMMU_PGSIZES,
 	.of_xlate = qcom_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &msm_iommu_ops,
 		.attach_dev	= msm_iommu_attach_dev,
 		.detach_dev	= msm_iommu_detach_dev,
 		.map		= msm_iommu_map,
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index bb9dd92c9898..c5c45f65077d 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -937,6 +937,7 @@ static const struct iommu_ops mtk_iommu_ops = {
 	.pgsize_bitmap	= SZ_4K | SZ_64K | SZ_1M | SZ_16M,
 	.owner		= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &mtk_iommu_ops,
 		.attach_dev	= mtk_iommu_attach_device,
 		.detach_dev	= mtk_iommu_detach_device,
 		.map		= mtk_iommu_map,
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index e1cb51b9866c..77c53580f730 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -594,6 +594,7 @@ static const struct iommu_ops mtk_iommu_v1_ops = {
 	.pgsize_bitmap	= ~0UL << MT2701_IOMMU_PAGE_SHIFT,
 	.owner          = THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &mtk_iommu_v1_ops,
 		.attach_dev	= mtk_iommu_v1_attach_device,
 		.detach_dev	= mtk_iommu_v1_detach_device,
 		.map		= mtk_iommu_v1_map,
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index bbc6c4cd7aae..a0bf85ccebcd 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1739,6 +1739,7 @@ static const struct iommu_ops omap_iommu_ops = {
 	.device_group	= omap_iommu_device_group,
 	.pgsize_bitmap	= OMAP_IOMMU_PGSIZES,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &omap_iommu_ops,
 		.attach_dev	= omap_iommu_attach_dev,
 		.detach_dev	= omap_iommu_detach_dev,
 		.map		= omap_iommu_map,
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index ab57c4b8fade..5f5387e902e0 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1193,6 +1193,7 @@ static const struct iommu_ops rk_iommu_ops = {
 	.pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
 	.of_xlate = rk_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &rk_iommu_ops,
 		.attach_dev	= rk_iommu_attach_device,
 		.detach_dev	= rk_iommu_detach_device,
 		.map		= rk_iommu_map,
diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
index c898bcbbce11..62e6d152b0a0 100644
--- a/drivers/iommu/s390-iommu.c
+++ b/drivers/iommu/s390-iommu.c
@@ -377,6 +377,7 @@ static const struct iommu_ops s390_iommu_ops = {
 	.device_group = generic_device_group,
 	.pgsize_bitmap = S390_IOMMU_PGSIZES,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &s390_iommu_ops,
 		.attach_dev	= s390_iommu_attach_device,
 		.detach_dev	= s390_iommu_detach_device,
 		.map		= s390_iommu_map,
diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c
index bd409bab6286..6e8ca34d6a00 100644
--- a/drivers/iommu/sprd-iommu.c
+++ b/drivers/iommu/sprd-iommu.c
@@ -423,6 +423,7 @@ static const struct iommu_ops sprd_iommu_ops = {
 	.pgsize_bitmap	= ~0UL << SPRD_IOMMU_PAGE_SHIFT,
 	.owner		= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &sprd_iommu_ops,
 		.attach_dev	= sprd_iommu_attach_device,
 		.detach_dev	= sprd_iommu_detach_device,
 		.map		= sprd_iommu_map,
diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
index c54ab477b8fd..560cff8e0f04 100644
--- a/drivers/iommu/sun50i-iommu.c
+++ b/drivers/iommu/sun50i-iommu.c
@@ -766,6 +766,7 @@ static const struct iommu_ops sun50i_iommu_ops = {
 	.probe_device	= sun50i_iommu_probe_device,
 	.release_device	= sun50i_iommu_release_device,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &sun50i_iommu_ops,
 		.attach_dev	= sun50i_iommu_attach_device,
 		.detach_dev	= sun50i_iommu_detach_device,
 		.flush_iotlb_all = sun50i_iommu_flush_iotlb_all,
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index a6700a40a6f8..cd4553611cc9 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -278,6 +278,7 @@ static const struct iommu_ops gart_iommu_ops = {
 	.pgsize_bitmap	= GART_IOMMU_PGSIZES,
 	.of_xlate	= gart_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &gart_iommu_ops,
 		.attach_dev	= gart_iommu_attach_dev,
 		.detach_dev	= gart_iommu_detach_dev,
 		.map		= gart_iommu_map,
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 2f2b12033618..67c101d1ad66 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -971,6 +971,7 @@ static const struct iommu_ops tegra_smmu_ops = {
 	.of_xlate = tegra_smmu_of_xlate,
 	.pgsize_bitmap = SZ_4K,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &tegra_smmu_ops,
 		.attach_dev	= tegra_smmu_attach_dev,
 		.detach_dev	= tegra_smmu_detach_dev,
 		.map		= tegra_smmu_map,
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index e3b812d8fa96..703d87922786 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -1017,6 +1017,7 @@ static struct iommu_ops viommu_ops = {
 	.of_xlate		= viommu_of_xlate,
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &viommu_ops,
 		.attach_dev		= viommu_attach_dev,
 		.map			= viommu_map,
 		.unmap			= viommu_unmap,
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 5e1afe169549..77deaf4fc7f8 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -261,6 +261,7 @@ struct iommu_ops {
 
 /**
  * struct iommu_domain_ops - domain specific operations
+ * @iommu_ops: Pointer to the ops associated with compatible devices
  * @attach_dev: attach an iommu domain to a device
  * @detach_dev: detach an iommu domain from a device
  * @map: map a physically contiguous memory region to an iommu domain
@@ -281,6 +282,7 @@ struct iommu_ops {
  * @free: Release the domain after use.
  */
 struct iommu_domain_ops {
+	const struct iommu_ops *iommu_ops;
 	int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
 	void (*detach_dev)(struct iommu_domain *domain, struct device *dev);
 
-- 
2.17.1


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

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

* [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: mjrosato, virtualization, thierry.reding, alim.akhtar, alyssa,
	linux-s390, linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	yong.wu, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, suravee.suthikulpanit, dwmw2

The core code should not call an iommu driver op with a struct device
parameter unless it knows that the dev_iommu_priv_get() for that struct
device was setup by the same driver. Otherwise in a mixed driver system
the iommu_priv could be casted to the wrong type.

Store the iommu_ops pointer in the iommu_domain and use it as a check to
validate that the struct device is correct before invoking any domain op
that accepts a struct device.

This allows removing the check of the domain op equality in VFIO.

Co-developed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/iommu/amd/iommu.c                   | 1 +
 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/arm/arm-smmu/qcom_iommu.c     | 1 +
 drivers/iommu/exynos-iommu.c                | 1 +
 drivers/iommu/fsl_pamu_domain.c             | 1 +
 drivers/iommu/intel/iommu.c                 | 1 +
 drivers/iommu/iommu.c                       | 4 ++++
 drivers/iommu/ipmmu-vmsa.c                  | 1 +
 drivers/iommu/msm_iommu.c                   | 1 +
 drivers/iommu/mtk_iommu.c                   | 1 +
 drivers/iommu/mtk_iommu_v1.c                | 1 +
 drivers/iommu/omap-iommu.c                  | 1 +
 drivers/iommu/rockchip-iommu.c              | 1 +
 drivers/iommu/s390-iommu.c                  | 1 +
 drivers/iommu/sprd-iommu.c                  | 1 +
 drivers/iommu/sun50i-iommu.c                | 1 +
 drivers/iommu/tegra-gart.c                  | 1 +
 drivers/iommu/tegra-smmu.c                  | 1 +
 drivers/iommu/virtio-iommu.c                | 1 +
 include/linux/iommu.h                       | 2 ++
 22 files changed, 26 insertions(+)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index ad499658a6b6..679f7a265013 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2285,6 +2285,7 @@ const struct iommu_ops amd_iommu_ops = {
 	.pgsize_bitmap	= AMD_IOMMU_PGSIZES,
 	.def_domain_type = amd_iommu_def_domain_type,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &amd_iommu_ops,
 		.attach_dev	= amd_iommu_attach_device,
 		.detach_dev	= amd_iommu_detach_device,
 		.map		= amd_iommu_map,
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index e58dc310afd7..3d36d9a12aa7 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -775,6 +775,7 @@ static const struct iommu_ops apple_dart_iommu_ops = {
 	.pgsize_bitmap = -1UL, /* Restricted during dart probe */
 	.owner = THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &apple_dart_iommu_ops,
 		.attach_dev	= apple_dart_attach_dev,
 		.detach_dev	= apple_dart_detach_dev,
 		.map_pages	= apple_dart_map_pages,
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 6c393cd84925..471ceb60427c 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2859,6 +2859,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &arm_smmu_ops,
 		.attach_dev		= arm_smmu_attach_dev,
 		.map_pages		= arm_smmu_map_pages,
 		.unmap_pages		= arm_smmu_unmap_pages,
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 2ed3594f384e..52c2589a4deb 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1597,6 +1597,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &arm_smmu_ops,
 		.attach_dev		= arm_smmu_attach_dev,
 		.map_pages		= arm_smmu_map_pages,
 		.unmap_pages		= arm_smmu_unmap_pages,
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index a8b63b855ffb..8806a621f81e 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -596,6 +596,7 @@ static const struct iommu_ops qcom_iommu_ops = {
 	.of_xlate	= qcom_iommu_of_xlate,
 	.pgsize_bitmap	= SZ_4K | SZ_64K | SZ_1M | SZ_16M,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &qcom_iommu_ops,
 		.attach_dev	= qcom_iommu_attach_dev,
 		.detach_dev	= qcom_iommu_detach_dev,
 		.map		= qcom_iommu_map,
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 71f2018e23fe..fa93f94313e3 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1315,6 +1315,7 @@ static const struct iommu_ops exynos_iommu_ops = {
 	.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
 	.of_xlate = exynos_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &exynos_iommu_ops,
 		.attach_dev	= exynos_iommu_attach_device,
 		.detach_dev	= exynos_iommu_detach_device,
 		.map		= exynos_iommu_map,
diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index 94b4589dc67c..7bdce4168d2c 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -458,6 +458,7 @@ static const struct iommu_ops fsl_pamu_ops = {
 	.release_device	= fsl_pamu_release_device,
 	.device_group   = fsl_pamu_device_group,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &fsl_pamu_ops,
 		.attach_dev	= fsl_pamu_attach_device,
 		.detach_dev	= fsl_pamu_detach_device,
 		.iova_to_phys	= fsl_pamu_iova_to_phys,
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 0813b119d680..c6022484ca2d 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4925,6 +4925,7 @@ const struct iommu_ops intel_iommu_ops = {
 	.page_response		= intel_svm_page_response,
 #endif
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &intel_iommu_ops,
 		.attach_dev		= intel_iommu_attach_device,
 		.detach_dev		= intel_iommu_detach_device,
 		.map_pages		= intel_iommu_map_pages,
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 19cf28d40ebe..8a1f437a51f2 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1963,6 +1963,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
 {
 	int ret;
 
+	/* Ensure the device was probe'd onto the same driver as the domain */
+	if (dev->bus->iommu_ops != domain->ops->iommu_ops)
+		return -EMEDIUMTYPE;
+
 	if (unlikely(domain->ops->attach_dev == NULL))
 		return -ENODEV;
 
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index e491e410add5..767b93da5800 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -877,6 +877,7 @@ static const struct iommu_ops ipmmu_ops = {
 	.pgsize_bitmap = SZ_1G | SZ_2M | SZ_4K,
 	.of_xlate = ipmmu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &ipmmu_ops,
 		.attach_dev	= ipmmu_attach_device,
 		.detach_dev	= ipmmu_detach_device,
 		.map		= ipmmu_map,
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index f09aedfdd462..29f6a6d5691e 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -682,6 +682,7 @@ static struct iommu_ops msm_iommu_ops = {
 	.pgsize_bitmap = MSM_IOMMU_PGSIZES,
 	.of_xlate = qcom_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &msm_iommu_ops,
 		.attach_dev	= msm_iommu_attach_dev,
 		.detach_dev	= msm_iommu_detach_dev,
 		.map		= msm_iommu_map,
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index bb9dd92c9898..c5c45f65077d 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -937,6 +937,7 @@ static const struct iommu_ops mtk_iommu_ops = {
 	.pgsize_bitmap	= SZ_4K | SZ_64K | SZ_1M | SZ_16M,
 	.owner		= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &mtk_iommu_ops,
 		.attach_dev	= mtk_iommu_attach_device,
 		.detach_dev	= mtk_iommu_detach_device,
 		.map		= mtk_iommu_map,
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index e1cb51b9866c..77c53580f730 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -594,6 +594,7 @@ static const struct iommu_ops mtk_iommu_v1_ops = {
 	.pgsize_bitmap	= ~0UL << MT2701_IOMMU_PAGE_SHIFT,
 	.owner          = THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &mtk_iommu_v1_ops,
 		.attach_dev	= mtk_iommu_v1_attach_device,
 		.detach_dev	= mtk_iommu_v1_detach_device,
 		.map		= mtk_iommu_v1_map,
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index bbc6c4cd7aae..a0bf85ccebcd 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1739,6 +1739,7 @@ static const struct iommu_ops omap_iommu_ops = {
 	.device_group	= omap_iommu_device_group,
 	.pgsize_bitmap	= OMAP_IOMMU_PGSIZES,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &omap_iommu_ops,
 		.attach_dev	= omap_iommu_attach_dev,
 		.detach_dev	= omap_iommu_detach_dev,
 		.map		= omap_iommu_map,
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index ab57c4b8fade..5f5387e902e0 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1193,6 +1193,7 @@ static const struct iommu_ops rk_iommu_ops = {
 	.pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
 	.of_xlate = rk_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &rk_iommu_ops,
 		.attach_dev	= rk_iommu_attach_device,
 		.detach_dev	= rk_iommu_detach_device,
 		.map		= rk_iommu_map,
diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
index c898bcbbce11..62e6d152b0a0 100644
--- a/drivers/iommu/s390-iommu.c
+++ b/drivers/iommu/s390-iommu.c
@@ -377,6 +377,7 @@ static const struct iommu_ops s390_iommu_ops = {
 	.device_group = generic_device_group,
 	.pgsize_bitmap = S390_IOMMU_PGSIZES,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &s390_iommu_ops,
 		.attach_dev	= s390_iommu_attach_device,
 		.detach_dev	= s390_iommu_detach_device,
 		.map		= s390_iommu_map,
diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c
index bd409bab6286..6e8ca34d6a00 100644
--- a/drivers/iommu/sprd-iommu.c
+++ b/drivers/iommu/sprd-iommu.c
@@ -423,6 +423,7 @@ static const struct iommu_ops sprd_iommu_ops = {
 	.pgsize_bitmap	= ~0UL << SPRD_IOMMU_PAGE_SHIFT,
 	.owner		= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &sprd_iommu_ops,
 		.attach_dev	= sprd_iommu_attach_device,
 		.detach_dev	= sprd_iommu_detach_device,
 		.map		= sprd_iommu_map,
diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
index c54ab477b8fd..560cff8e0f04 100644
--- a/drivers/iommu/sun50i-iommu.c
+++ b/drivers/iommu/sun50i-iommu.c
@@ -766,6 +766,7 @@ static const struct iommu_ops sun50i_iommu_ops = {
 	.probe_device	= sun50i_iommu_probe_device,
 	.release_device	= sun50i_iommu_release_device,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &sun50i_iommu_ops,
 		.attach_dev	= sun50i_iommu_attach_device,
 		.detach_dev	= sun50i_iommu_detach_device,
 		.flush_iotlb_all = sun50i_iommu_flush_iotlb_all,
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index a6700a40a6f8..cd4553611cc9 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -278,6 +278,7 @@ static const struct iommu_ops gart_iommu_ops = {
 	.pgsize_bitmap	= GART_IOMMU_PGSIZES,
 	.of_xlate	= gart_iommu_of_xlate,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &gart_iommu_ops,
 		.attach_dev	= gart_iommu_attach_dev,
 		.detach_dev	= gart_iommu_detach_dev,
 		.map		= gart_iommu_map,
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 2f2b12033618..67c101d1ad66 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -971,6 +971,7 @@ static const struct iommu_ops tegra_smmu_ops = {
 	.of_xlate = tegra_smmu_of_xlate,
 	.pgsize_bitmap = SZ_4K,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops	= &tegra_smmu_ops,
 		.attach_dev	= tegra_smmu_attach_dev,
 		.detach_dev	= tegra_smmu_detach_dev,
 		.map		= tegra_smmu_map,
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index e3b812d8fa96..703d87922786 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -1017,6 +1017,7 @@ static struct iommu_ops viommu_ops = {
 	.of_xlate		= viommu_of_xlate,
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.iommu_ops		= &viommu_ops,
 		.attach_dev		= viommu_attach_dev,
 		.map			= viommu_map,
 		.unmap			= viommu_unmap,
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 5e1afe169549..77deaf4fc7f8 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -261,6 +261,7 @@ struct iommu_ops {
 
 /**
  * struct iommu_domain_ops - domain specific operations
+ * @iommu_ops: Pointer to the ops associated with compatible devices
  * @attach_dev: attach an iommu domain to a device
  * @detach_dev: detach an iommu domain from a device
  * @map: map a physically contiguous memory region to an iommu domain
@@ -281,6 +282,7 @@ struct iommu_ops {
  * @free: Release the domain after use.
  */
 struct iommu_domain_ops {
+	const struct iommu_ops *iommu_ops;
 	int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
 	void (*detach_dev)(struct iommu_domain *domain, struct device *dev);
 
-- 
2.17.1


_______________________________________________
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] 138+ messages in thread

* [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
  2022-06-06  6:19 ` Nicolin Chen
                     ` (2 preceding siblings ...)
  (?)
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  -1 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

From: Jason Gunthorpe <jgg@nvidia.com>

The KVM mechanism for controlling wbinvd is only triggered during
kvm_vfio_group_add(), meaning it is a one-shot test done once the devices
are setup.

So, there is no value in trying to push a device that could do enforced
cache coherency to a dedicated domain vs re-using an existing domain since
KVM won't be able to take advantage of it. This just wastes domain memory.

Simplify this code and eliminate the test. This removes the only logic
that needed to have a dummy domain attached prior to searching for a
matching domain and simplifies the next patches.

If someday we want to try and optimize this further the better approach is
to update the Intel driver so that enforce_cache_coherency() can work on a
domain that already has IOPTEs and then call the enforce_cache_coherency()
after detaching a device from a domain to upgrade the whole domain to
enforced cache coherency mode.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index c13b9290e357..f4e3b423a453 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -2285,9 +2285,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 	 * testing if they're on the same bus_type.
 	 */
 	list_for_each_entry(d, &iommu->domain_list, next) {
-		if (d->domain->ops == domain->domain->ops &&
-		    d->enforce_cache_coherency ==
-			    domain->enforce_cache_coherency) {
+		if (d->domain->ops == domain->domain->ops) {
 			iommu_detach_group(domain->domain, group->iommu_group);
 			if (!iommu_attach_group(d->domain,
 						group->iommu_group)) {
-- 
2.17.1


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

* [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen via iommu @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

From: Jason Gunthorpe <jgg@nvidia.com>

The KVM mechanism for controlling wbinvd is only triggered during
kvm_vfio_group_add(), meaning it is a one-shot test done once the devices
are setup.

So, there is no value in trying to push a device that could do enforced
cache coherency to a dedicated domain vs re-using an existing domain since
KVM won't be able to take advantage of it. This just wastes domain memory.

Simplify this code and eliminate the test. This removes the only logic
that needed to have a dummy domain attached prior to searching for a
matching domain and simplifies the next patches.

If someday we want to try and optimize this further the better approach is
to update the Intel driver so that enforce_cache_coherency() can work on a
domain that already has IOPTEs and then call the enforce_cache_coherency()
after detaching a device from a domain to upgrade the whole domain to
enforced cache coherency mode.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index c13b9290e357..f4e3b423a453 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -2285,9 +2285,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 	 * testing if they're on the same bus_type.
 	 */
 	list_for_each_entry(d, &iommu->domain_list, next) {
-		if (d->domain->ops == domain->domain->ops &&
-		    d->enforce_cache_coherency ==
-			    domain->enforce_cache_coherency) {
+		if (d->domain->ops == domain->domain->ops) {
 			iommu_detach_group(domain->domain, group->iommu_group);
 			if (!iommu_attach_group(d->domain,
 						group->iommu_group)) {
-- 
2.17.1

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

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

* [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

From: Jason Gunthorpe <jgg@nvidia.com>

The KVM mechanism for controlling wbinvd is only triggered during
kvm_vfio_group_add(), meaning it is a one-shot test done once the devices
are setup.

So, there is no value in trying to push a device that could do enforced
cache coherency to a dedicated domain vs re-using an existing domain since
KVM won't be able to take advantage of it. This just wastes domain memory.

Simplify this code and eliminate the test. This removes the only logic
that needed to have a dummy domain attached prior to searching for a
matching domain and simplifies the next patches.

If someday we want to try and optimize this further the better approach is
to update the Intel driver so that enforce_cache_coherency() can work on a
domain that already has IOPTEs and then call the enforce_cache_coherency()
after detaching a device from a domain to upgrade the whole domain to
enforced cache coherency mode.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index c13b9290e357..f4e3b423a453 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -2285,9 +2285,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 	 * testing if they're on the same bus_type.
 	 */
 	list_for_each_entry(d, &iommu->domain_list, next) {
-		if (d->domain->ops == domain->domain->ops &&
-		    d->enforce_cache_coherency ==
-			    domain->enforce_cache_coherency) {
+		if (d->domain->ops == domain->domain->ops) {
 			iommu_detach_group(domain->domain, group->iommu_group);
 			if (!iommu_attach_group(d->domain,
 						group->iommu_group)) {
-- 
2.17.1


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

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

* [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

From: Jason Gunthorpe <jgg@nvidia.com>

The KVM mechanism for controlling wbinvd is only triggered during
kvm_vfio_group_add(), meaning it is a one-shot test done once the devices
are setup.

So, there is no value in trying to push a device that could do enforced
cache coherency to a dedicated domain vs re-using an existing domain since
KVM won't be able to take advantage of it. This just wastes domain memory.

Simplify this code and eliminate the test. This removes the only logic
that needed to have a dummy domain attached prior to searching for a
matching domain and simplifies the next patches.

If someday we want to try and optimize this further the better approach is
to update the Intel driver so that enforce_cache_coherency() can work on a
domain that already has IOPTEs and then call the enforce_cache_coherency()
after detaching a device from a domain to upgrade the whole domain to
enforced cache coherency mode.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index c13b9290e357..f4e3b423a453 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -2285,9 +2285,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 	 * testing if they're on the same bus_type.
 	 */
 	list_for_each_entry(d, &iommu->domain_list, next) {
-		if (d->domain->ops == domain->domain->ops &&
-		    d->enforce_cache_coherency ==
-			    domain->enforce_cache_coherency) {
+		if (d->domain->ops == domain->domain->ops) {
 			iommu_detach_group(domain->domain, group->iommu_group);
 			if (!iommu_attach_group(d->domain,
 						group->iommu_group)) {
-- 
2.17.1


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

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

* [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: mjrosato, virtualization, thierry.reding, alim.akhtar, alyssa,
	linux-s390, linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	yong.wu, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, suravee.suthikulpanit, dwmw2

From: Jason Gunthorpe <jgg@nvidia.com>

The KVM mechanism for controlling wbinvd is only triggered during
kvm_vfio_group_add(), meaning it is a one-shot test done once the devices
are setup.

So, there is no value in trying to push a device that could do enforced
cache coherency to a dedicated domain vs re-using an existing domain since
KVM won't be able to take advantage of it. This just wastes domain memory.

Simplify this code and eliminate the test. This removes the only logic
that needed to have a dummy domain attached prior to searching for a
matching domain and simplifies the next patches.

If someday we want to try and optimize this further the better approach is
to update the Intel driver so that enforce_cache_coherency() can work on a
domain that already has IOPTEs and then call the enforce_cache_coherency()
after detaching a device from a domain to upgrade the whole domain to
enforced cache coherency mode.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index c13b9290e357..f4e3b423a453 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -2285,9 +2285,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 	 * testing if they're on the same bus_type.
 	 */
 	list_for_each_entry(d, &iommu->domain_list, next) {
-		if (d->domain->ops == domain->domain->ops &&
-		    d->enforce_cache_coherency ==
-			    domain->enforce_cache_coherency) {
+		if (d->domain->ops == domain->domain->ops) {
 			iommu_detach_group(domain->domain, group->iommu_group);
 			if (!iommu_attach_group(d->domain,
 						group->iommu_group)) {
-- 
2.17.1


_______________________________________________
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] 138+ messages in thread

* [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
  2022-06-06  6:19 ` Nicolin Chen
                     ` (2 preceding siblings ...)
  (?)
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  -1 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

All devices in emulated_iommu_groups have pinned_page_dirty_scope
set, so the update_dirty_scope in the first list_for_each_entry
is always false. Clean it up, and move the "if update_dirty_scope"
part from the detach_group_done routine to the domain_list part.

Rename the "detach_group_done" goto label accordingly.

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index f4e3b423a453..b45b1cc118ef 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -2463,14 +2463,12 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 	struct vfio_iommu *iommu = iommu_data;
 	struct vfio_domain *domain;
 	struct vfio_iommu_group *group;
-	bool update_dirty_scope = false;
 	LIST_HEAD(iova_copy);
 
 	mutex_lock(&iommu->lock);
 	list_for_each_entry(group, &iommu->emulated_iommu_groups, next) {
 		if (group->iommu_group != iommu_group)
 			continue;
-		update_dirty_scope = !group->pinned_page_dirty_scope;
 		list_del(&group->next);
 		kfree(group);
 
@@ -2479,7 +2477,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 			WARN_ON(iommu->notifier.head);
 			vfio_iommu_unmap_unpin_all(iommu);
 		}
-		goto detach_group_done;
+		goto out_unlock;
 	}
 
 	/*
@@ -2495,9 +2493,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 			continue;
 
 		iommu_detach_group(domain->domain, group->iommu_group);
-		update_dirty_scope = !group->pinned_page_dirty_scope;
 		list_del(&group->next);
-		kfree(group);
 		/*
 		 * Group ownership provides privilege, if the group list is
 		 * empty, the domain goes away. If it's the last domain with
@@ -2519,7 +2515,17 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 			kfree(domain);
 			vfio_iommu_aper_expand(iommu, &iova_copy);
 			vfio_update_pgsize_bitmap(iommu);
+			/*
+			 * Removal of a group without dirty tracking may allow
+			 * the iommu scope to be promoted.
+			 */
+			if (!group->pinned_page_dirty_scope) {
+				iommu->num_non_pinned_groups--;
+				if (iommu->dirty_page_tracking)
+					vfio_iommu_populate_bitmap_full(iommu);
+			}
 		}
+		kfree(group);
 		break;
 	}
 
@@ -2528,16 +2534,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 	else
 		vfio_iommu_iova_free(&iova_copy);
 
-detach_group_done:
-	/*
-	 * Removal of a group without dirty tracking may allow the iommu scope
-	 * to be promoted.
-	 */
-	if (update_dirty_scope) {
-		iommu->num_non_pinned_groups--;
-		if (iommu->dirty_page_tracking)
-			vfio_iommu_populate_bitmap_full(iommu);
-	}
+out_unlock:
 	mutex_unlock(&iommu->lock);
 }
 
-- 
2.17.1


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

* [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen via iommu @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

All devices in emulated_iommu_groups have pinned_page_dirty_scope
set, so the update_dirty_scope in the first list_for_each_entry
is always false. Clean it up, and move the "if update_dirty_scope"
part from the detach_group_done routine to the domain_list part.

Rename the "detach_group_done" goto label accordingly.

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index f4e3b423a453..b45b1cc118ef 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -2463,14 +2463,12 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 	struct vfio_iommu *iommu = iommu_data;
 	struct vfio_domain *domain;
 	struct vfio_iommu_group *group;
-	bool update_dirty_scope = false;
 	LIST_HEAD(iova_copy);
 
 	mutex_lock(&iommu->lock);
 	list_for_each_entry(group, &iommu->emulated_iommu_groups, next) {
 		if (group->iommu_group != iommu_group)
 			continue;
-		update_dirty_scope = !group->pinned_page_dirty_scope;
 		list_del(&group->next);
 		kfree(group);
 
@@ -2479,7 +2477,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 			WARN_ON(iommu->notifier.head);
 			vfio_iommu_unmap_unpin_all(iommu);
 		}
-		goto detach_group_done;
+		goto out_unlock;
 	}
 
 	/*
@@ -2495,9 +2493,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 			continue;
 
 		iommu_detach_group(domain->domain, group->iommu_group);
-		update_dirty_scope = !group->pinned_page_dirty_scope;
 		list_del(&group->next);
-		kfree(group);
 		/*
 		 * Group ownership provides privilege, if the group list is
 		 * empty, the domain goes away. If it's the last domain with
@@ -2519,7 +2515,17 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 			kfree(domain);
 			vfio_iommu_aper_expand(iommu, &iova_copy);
 			vfio_update_pgsize_bitmap(iommu);
+			/*
+			 * Removal of a group without dirty tracking may allow
+			 * the iommu scope to be promoted.
+			 */
+			if (!group->pinned_page_dirty_scope) {
+				iommu->num_non_pinned_groups--;
+				if (iommu->dirty_page_tracking)
+					vfio_iommu_populate_bitmap_full(iommu);
+			}
 		}
+		kfree(group);
 		break;
 	}
 
@@ -2528,16 +2534,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 	else
 		vfio_iommu_iova_free(&iova_copy);
 
-detach_group_done:
-	/*
-	 * Removal of a group without dirty tracking may allow the iommu scope
-	 * to be promoted.
-	 */
-	if (update_dirty_scope) {
-		iommu->num_non_pinned_groups--;
-		if (iommu->dirty_page_tracking)
-			vfio_iommu_populate_bitmap_full(iommu);
-	}
+out_unlock:
 	mutex_unlock(&iommu->lock);
 }
 
-- 
2.17.1

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

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

* [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

All devices in emulated_iommu_groups have pinned_page_dirty_scope
set, so the update_dirty_scope in the first list_for_each_entry
is always false. Clean it up, and move the "if update_dirty_scope"
part from the detach_group_done routine to the domain_list part.

Rename the "detach_group_done" goto label accordingly.

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index f4e3b423a453..b45b1cc118ef 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -2463,14 +2463,12 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 	struct vfio_iommu *iommu = iommu_data;
 	struct vfio_domain *domain;
 	struct vfio_iommu_group *group;
-	bool update_dirty_scope = false;
 	LIST_HEAD(iova_copy);
 
 	mutex_lock(&iommu->lock);
 	list_for_each_entry(group, &iommu->emulated_iommu_groups, next) {
 		if (group->iommu_group != iommu_group)
 			continue;
-		update_dirty_scope = !group->pinned_page_dirty_scope;
 		list_del(&group->next);
 		kfree(group);
 
@@ -2479,7 +2477,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 			WARN_ON(iommu->notifier.head);
 			vfio_iommu_unmap_unpin_all(iommu);
 		}
-		goto detach_group_done;
+		goto out_unlock;
 	}
 
 	/*
@@ -2495,9 +2493,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 			continue;
 
 		iommu_detach_group(domain->domain, group->iommu_group);
-		update_dirty_scope = !group->pinned_page_dirty_scope;
 		list_del(&group->next);
-		kfree(group);
 		/*
 		 * Group ownership provides privilege, if the group list is
 		 * empty, the domain goes away. If it's the last domain with
@@ -2519,7 +2515,17 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 			kfree(domain);
 			vfio_iommu_aper_expand(iommu, &iova_copy);
 			vfio_update_pgsize_bitmap(iommu);
+			/*
+			 * Removal of a group without dirty tracking may allow
+			 * the iommu scope to be promoted.
+			 */
+			if (!group->pinned_page_dirty_scope) {
+				iommu->num_non_pinned_groups--;
+				if (iommu->dirty_page_tracking)
+					vfio_iommu_populate_bitmap_full(iommu);
+			}
 		}
+		kfree(group);
 		break;
 	}
 
@@ -2528,16 +2534,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 	else
 		vfio_iommu_iova_free(&iova_copy);
 
-detach_group_done:
-	/*
-	 * Removal of a group without dirty tracking may allow the iommu scope
-	 * to be promoted.
-	 */
-	if (update_dirty_scope) {
-		iommu->num_non_pinned_groups--;
-		if (iommu->dirty_page_tracking)
-			vfio_iommu_populate_bitmap_full(iommu);
-	}
+out_unlock:
 	mutex_unlock(&iommu->lock);
 }
 
-- 
2.17.1


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

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

* [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

All devices in emulated_iommu_groups have pinned_page_dirty_scope
set, so the update_dirty_scope in the first list_for_each_entry
is always false. Clean it up, and move the "if update_dirty_scope"
part from the detach_group_done routine to the domain_list part.

Rename the "detach_group_done" goto label accordingly.

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index f4e3b423a453..b45b1cc118ef 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -2463,14 +2463,12 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 	struct vfio_iommu *iommu = iommu_data;
 	struct vfio_domain *domain;
 	struct vfio_iommu_group *group;
-	bool update_dirty_scope = false;
 	LIST_HEAD(iova_copy);
 
 	mutex_lock(&iommu->lock);
 	list_for_each_entry(group, &iommu->emulated_iommu_groups, next) {
 		if (group->iommu_group != iommu_group)
 			continue;
-		update_dirty_scope = !group->pinned_page_dirty_scope;
 		list_del(&group->next);
 		kfree(group);
 
@@ -2479,7 +2477,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 			WARN_ON(iommu->notifier.head);
 			vfio_iommu_unmap_unpin_all(iommu);
 		}
-		goto detach_group_done;
+		goto out_unlock;
 	}
 
 	/*
@@ -2495,9 +2493,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 			continue;
 
 		iommu_detach_group(domain->domain, group->iommu_group);
-		update_dirty_scope = !group->pinned_page_dirty_scope;
 		list_del(&group->next);
-		kfree(group);
 		/*
 		 * Group ownership provides privilege, if the group list is
 		 * empty, the domain goes away. If it's the last domain with
@@ -2519,7 +2515,17 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 			kfree(domain);
 			vfio_iommu_aper_expand(iommu, &iova_copy);
 			vfio_update_pgsize_bitmap(iommu);
+			/*
+			 * Removal of a group without dirty tracking may allow
+			 * the iommu scope to be promoted.
+			 */
+			if (!group->pinned_page_dirty_scope) {
+				iommu->num_non_pinned_groups--;
+				if (iommu->dirty_page_tracking)
+					vfio_iommu_populate_bitmap_full(iommu);
+			}
 		}
+		kfree(group);
 		break;
 	}
 
@@ -2528,16 +2534,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 	else
 		vfio_iommu_iova_free(&iova_copy);
 
-detach_group_done:
-	/*
-	 * Removal of a group without dirty tracking may allow the iommu scope
-	 * to be promoted.
-	 */
-	if (update_dirty_scope) {
-		iommu->num_non_pinned_groups--;
-		if (iommu->dirty_page_tracking)
-			vfio_iommu_populate_bitmap_full(iommu);
-	}
+out_unlock:
 	mutex_unlock(&iommu->lock);
 }
 
-- 
2.17.1


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

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

* [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: mjrosato, virtualization, thierry.reding, alim.akhtar, alyssa,
	linux-s390, linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	yong.wu, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, suravee.suthikulpanit, dwmw2

All devices in emulated_iommu_groups have pinned_page_dirty_scope
set, so the update_dirty_scope in the first list_for_each_entry
is always false. Clean it up, and move the "if update_dirty_scope"
part from the detach_group_done routine to the domain_list part.

Rename the "detach_group_done" goto label accordingly.

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index f4e3b423a453..b45b1cc118ef 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -2463,14 +2463,12 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 	struct vfio_iommu *iommu = iommu_data;
 	struct vfio_domain *domain;
 	struct vfio_iommu_group *group;
-	bool update_dirty_scope = false;
 	LIST_HEAD(iova_copy);
 
 	mutex_lock(&iommu->lock);
 	list_for_each_entry(group, &iommu->emulated_iommu_groups, next) {
 		if (group->iommu_group != iommu_group)
 			continue;
-		update_dirty_scope = !group->pinned_page_dirty_scope;
 		list_del(&group->next);
 		kfree(group);
 
@@ -2479,7 +2477,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 			WARN_ON(iommu->notifier.head);
 			vfio_iommu_unmap_unpin_all(iommu);
 		}
-		goto detach_group_done;
+		goto out_unlock;
 	}
 
 	/*
@@ -2495,9 +2493,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 			continue;
 
 		iommu_detach_group(domain->domain, group->iommu_group);
-		update_dirty_scope = !group->pinned_page_dirty_scope;
 		list_del(&group->next);
-		kfree(group);
 		/*
 		 * Group ownership provides privilege, if the group list is
 		 * empty, the domain goes away. If it's the last domain with
@@ -2519,7 +2515,17 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 			kfree(domain);
 			vfio_iommu_aper_expand(iommu, &iova_copy);
 			vfio_update_pgsize_bitmap(iommu);
+			/*
+			 * Removal of a group without dirty tracking may allow
+			 * the iommu scope to be promoted.
+			 */
+			if (!group->pinned_page_dirty_scope) {
+				iommu->num_non_pinned_groups--;
+				if (iommu->dirty_page_tracking)
+					vfio_iommu_populate_bitmap_full(iommu);
+			}
 		}
+		kfree(group);
 		break;
 	}
 
@@ -2528,16 +2534,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 	else
 		vfio_iommu_iova_free(&iova_copy);
 
-detach_group_done:
-	/*
-	 * Removal of a group without dirty tracking may allow the iommu scope
-	 * to be promoted.
-	 */
-	if (update_dirty_scope) {
-		iommu->num_non_pinned_groups--;
-		if (iommu->dirty_page_tracking)
-			vfio_iommu_populate_bitmap_full(iommu);
-	}
+out_unlock:
 	mutex_unlock(&iommu->lock);
 }
 
-- 
2.17.1


_______________________________________________
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] 138+ messages in thread

* [PATCH 5/5] vfio/iommu_type1: Simplify group attachment
  2022-06-06  6:19 ` Nicolin Chen
                     ` (2 preceding siblings ...)
  (?)
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  -1 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

Un-inline the domain specific logic from the attach/detach_group ops into
two paired functions vfio_iommu_alloc_attach_domain() and
vfio_iommu_detach_destroy_domain() that strictly deal with creating and
destroying struct vfio_domains.

Add the logic to check for EMEDIUMTYPE return code of iommu_attach_group()
and avoid the extra domain allocations and attach/detach sequences of the
old code. This allows properly detecting an actual attach error, like
-ENOMEM, vs treating all attach errors as an incompatible domain.

Remove the duplicated domain->ops comparison that is taken care of in the
IOMMU core.

Co-developed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 306 +++++++++++++++++---------------
 1 file changed, 161 insertions(+), 145 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index b45b1cc118ef..c6f937e1d71f 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -86,6 +86,7 @@ struct vfio_domain {
 	struct list_head	group_list;
 	bool			fgsp : 1;	/* Fine-grained super pages */
 	bool			enforce_cache_coherency : 1;
+	bool			msi_cookie : 1;
 };
 
 struct vfio_dma {
@@ -2153,12 +2154,161 @@ static void vfio_iommu_iova_insert_copy(struct vfio_iommu *iommu,
 	list_splice_tail(iova_copy, iova);
 }
 
+static struct vfio_domain *
+vfio_iommu_alloc_attach_domain(struct bus_type *bus, struct vfio_iommu *iommu,
+			       struct vfio_iommu_group *group)
+{
+	struct iommu_domain *new_domain;
+	struct vfio_domain *domain;
+	int ret = 0;
+
+	/* Try to match an existing compatible domain */
+	list_for_each_entry (domain, &iommu->domain_list, next) {
+		ret = iommu_attach_group(domain->domain, group->iommu_group);
+		if (ret == -EMEDIUMTYPE)
+			continue;
+		if (ret)
+			return ERR_PTR(ret);
+		list_add(&group->next, &domain->group_list);
+		return domain;
+	}
+
+	new_domain = iommu_domain_alloc(bus);
+	if (!new_domain)
+		return ERR_PTR(-EIO);
+
+	if (iommu->nesting) {
+		ret = iommu_enable_nesting(new_domain);
+		if (ret)
+			goto out_free_iommu_domain;
+	}
+
+	ret = iommu_attach_group(new_domain, group->iommu_group);
+	if (ret)
+		goto out_free_iommu_domain;
+
+	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+	if (!domain) {
+		ret = -ENOMEM;
+		goto out_detach;
+	}
+
+	domain->domain = new_domain;
+	vfio_test_domain_fgsp(domain);
+
+	/*
+	 * If the IOMMU can block non-coherent operations (ie PCIe TLPs with
+	 * no-snoop set) then VFIO always turns this feature on because on Intel
+	 * platforms it optimizes KVM to disable wbinvd emulation.
+	 */
+	if (new_domain->ops->enforce_cache_coherency)
+		domain->enforce_cache_coherency =
+			new_domain->ops->enforce_cache_coherency(new_domain);
+
+	/* replay mappings on new domains */
+	ret = vfio_iommu_replay(iommu, domain);
+	if (ret)
+		goto out_free_domain;
+
+	/*
+	 * An iommu backed group can dirty memory directly and therefore
+	 * demotes the iommu scope until it declares itself dirty tracking
+	 * capable via the page pinning interface.
+	 */
+	iommu->num_non_pinned_groups++;
+
+	INIT_LIST_HEAD(&domain->group_list);
+	list_add(&group->next, &domain->group_list);
+	list_add(&domain->next, &iommu->domain_list);
+	vfio_update_pgsize_bitmap(iommu);
+	return domain;
+
+out_free_domain:
+	kfree(domain);
+out_detach:
+	iommu_detach_group(domain->domain, group->iommu_group);
+out_free_iommu_domain:
+	iommu_domain_free(new_domain);
+	return ERR_PTR(ret);
+}
+
+static void vfio_iommu_unmap_unpin_all(struct vfio_iommu *iommu)
+{
+	struct rb_node *node;
+
+	while ((node = rb_first(&iommu->dma_list)))
+		vfio_remove_dma(iommu, rb_entry(node, struct vfio_dma, node));
+}
+
+static void vfio_iommu_unmap_unpin_reaccount(struct vfio_iommu *iommu)
+{
+	struct rb_node *n, *p;
+
+	n = rb_first(&iommu->dma_list);
+	for (; n; n = rb_next(n)) {
+		struct vfio_dma *dma;
+		long locked = 0, unlocked = 0;
+
+		dma = rb_entry(n, struct vfio_dma, node);
+		unlocked += vfio_unmap_unpin(iommu, dma, false);
+		p = rb_first(&dma->pfn_list);
+		for (; p; p = rb_next(p)) {
+			struct vfio_pfn *vpfn = rb_entry(p, struct vfio_pfn,
+							 node);
+
+			if (!is_invalid_reserved_pfn(vpfn->pfn))
+				locked++;
+		}
+		vfio_lock_acct(dma, locked - unlocked, true);
+	}
+}
+
+static void vfio_iommu_detach_destroy_domain(struct vfio_domain *domain,
+					     struct vfio_iommu *iommu,
+					     struct vfio_iommu_group *group)
+{
+	iommu_detach_group(domain->domain, group->iommu_group);
+	list_del(&group->next);
+	if (!list_empty(&domain->group_list))
+		return;
+
+	/*
+	 * Group ownership provides privilege, if the group list is empty, the
+	 * domain goes away. If it's the last domain with iommu and external
+	 * domain doesn't exist, then all the mappings go away too. If it's the
+	 * last domain with iommu and external domain exist, update accounting
+	 */
+	if (list_is_singular(&iommu->domain_list)) {
+		if (list_empty(&iommu->emulated_iommu_groups)) {
+			WARN_ON(iommu->notifier.head);
+			vfio_iommu_unmap_unpin_all(iommu);
+		} else {
+			vfio_iommu_unmap_unpin_reaccount(iommu);
+		}
+	}
+	iommu_domain_free(domain->domain);
+	list_del(&domain->next);
+	kfree(domain);
+
+	/*
+	 * Removal of a group without dirty tracking may allow the iommu scope
+	 * to be promoted.
+	 */
+	if (!group->pinned_page_dirty_scope) {
+		iommu->num_non_pinned_groups--;
+		if (iommu->dirty_page_tracking)
+			vfio_iommu_populate_bitmap_full(iommu);
+	}
+
+	vfio_update_pgsize_bitmap(iommu);
+}
+
 static int vfio_iommu_type1_attach_group(void *iommu_data,
 		struct iommu_group *iommu_group, enum vfio_group_type type)
 {
 	struct vfio_iommu *iommu = iommu_data;
 	struct vfio_iommu_group *group;
-	struct vfio_domain *domain, *d;
+	struct vfio_domain *domain;
 	struct bus_type *bus = NULL;
 	bool resv_msi, msi_remap;
 	phys_addr_t resv_msi_base = 0;
@@ -2197,26 +2347,12 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 	if (ret)
 		goto out_free_group;
 
-	ret = -ENOMEM;
-	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
-	if (!domain)
+	domain = vfio_iommu_alloc_attach_domain(bus, iommu, group);
+	if (IS_ERR(domain)) {
+		ret = PTR_ERR(domain);
 		goto out_free_group;
-
-	ret = -EIO;
-	domain->domain = iommu_domain_alloc(bus);
-	if (!domain->domain)
-		goto out_free_domain;
-
-	if (iommu->nesting) {
-		ret = iommu_enable_nesting(domain->domain);
-		if (ret)
-			goto out_domain;
 	}
 
-	ret = iommu_attach_group(domain->domain, group->iommu_group);
-	if (ret)
-		goto out_domain;
-
 	/* Get aperture info */
 	geo = &domain->domain->geometry;
 	if (vfio_iommu_aper_conflict(iommu, geo->aperture_start,
@@ -2254,9 +2390,6 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 
 	resv_msi = vfio_iommu_has_sw_msi(&group_resv_regions, &resv_msi_base);
 
-	INIT_LIST_HEAD(&domain->group_list);
-	list_add(&group->next, &domain->group_list);
-
 	msi_remap = irq_domain_check_msi_remap() ||
 		    iommu_capable(bus, IOMMU_CAP_INTR_REMAP);
 
@@ -2267,117 +2400,32 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 		goto out_detach;
 	}
 
-	/*
-	 * If the IOMMU can block non-coherent operations (ie PCIe TLPs with
-	 * no-snoop set) then VFIO always turns this feature on because on Intel
-	 * platforms it optimizes KVM to disable wbinvd emulation.
-	 */
-	if (domain->domain->ops->enforce_cache_coherency)
-		domain->enforce_cache_coherency =
-			domain->domain->ops->enforce_cache_coherency(
-				domain->domain);
-
-	/*
-	 * Try to match an existing compatible domain.  We don't want to
-	 * preclude an IOMMU driver supporting multiple bus_types and being
-	 * able to include different bus_types in the same IOMMU domain, so
-	 * we test whether the domains use the same iommu_ops rather than
-	 * testing if they're on the same bus_type.
-	 */
-	list_for_each_entry(d, &iommu->domain_list, next) {
-		if (d->domain->ops == domain->domain->ops) {
-			iommu_detach_group(domain->domain, group->iommu_group);
-			if (!iommu_attach_group(d->domain,
-						group->iommu_group)) {
-				list_add(&group->next, &d->group_list);
-				iommu_domain_free(domain->domain);
-				kfree(domain);
-				goto done;
-			}
-
-			ret = iommu_attach_group(domain->domain,
-						 group->iommu_group);
-			if (ret)
-				goto out_domain;
-		}
-	}
-
-	vfio_test_domain_fgsp(domain);
-
-	/* replay mappings on new domains */
-	ret = vfio_iommu_replay(iommu, domain);
-	if (ret)
-		goto out_detach;
-
-	if (resv_msi) {
+	if (resv_msi && !domain->msi_cookie) {
 		ret = iommu_get_msi_cookie(domain->domain, resv_msi_base);
 		if (ret && ret != -ENODEV)
 			goto out_detach;
+		domain->msi_cookie = true;
 	}
 
-	list_add(&domain->next, &iommu->domain_list);
-	vfio_update_pgsize_bitmap(iommu);
-done:
 	/* Delete the old one and insert new iova list */
 	vfio_iommu_iova_insert_copy(iommu, &iova_copy);
 
-	/*
-	 * An iommu backed group can dirty memory directly and therefore
-	 * demotes the iommu scope until it declares itself dirty tracking
-	 * capable via the page pinning interface.
-	 */
-	iommu->num_non_pinned_groups++;
 	mutex_unlock(&iommu->lock);
 	vfio_iommu_resv_free(&group_resv_regions);
 
 	return 0;
 
 out_detach:
-	iommu_detach_group(domain->domain, group->iommu_group);
-out_domain:
-	iommu_domain_free(domain->domain);
-	vfio_iommu_iova_free(&iova_copy);
-	vfio_iommu_resv_free(&group_resv_regions);
-out_free_domain:
-	kfree(domain);
+	vfio_iommu_detach_destroy_domain(domain, iommu, group);
 out_free_group:
 	kfree(group);
 out_unlock:
 	mutex_unlock(&iommu->lock);
+	vfio_iommu_iova_free(&iova_copy);
+	vfio_iommu_resv_free(&group_resv_regions);
 	return ret;
 }
 
-static void vfio_iommu_unmap_unpin_all(struct vfio_iommu *iommu)
-{
-	struct rb_node *node;
-
-	while ((node = rb_first(&iommu->dma_list)))
-		vfio_remove_dma(iommu, rb_entry(node, struct vfio_dma, node));
-}
-
-static void vfio_iommu_unmap_unpin_reaccount(struct vfio_iommu *iommu)
-{
-	struct rb_node *n, *p;
-
-	n = rb_first(&iommu->dma_list);
-	for (; n; n = rb_next(n)) {
-		struct vfio_dma *dma;
-		long locked = 0, unlocked = 0;
-
-		dma = rb_entry(n, struct vfio_dma, node);
-		unlocked += vfio_unmap_unpin(iommu, dma, false);
-		p = rb_first(&dma->pfn_list);
-		for (; p; p = rb_next(p)) {
-			struct vfio_pfn *vpfn = rb_entry(p, struct vfio_pfn,
-							 node);
-
-			if (!is_invalid_reserved_pfn(vpfn->pfn))
-				locked++;
-		}
-		vfio_lock_acct(dma, locked - unlocked, true);
-	}
-}
-
 /*
  * Called when a domain is removed in detach. It is possible that
  * the removed domain decided the iova aperture window. Modify the
@@ -2491,44 +2539,12 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 		group = find_iommu_group(domain, iommu_group);
 		if (!group)
 			continue;
-
-		iommu_detach_group(domain->domain, group->iommu_group);
-		list_del(&group->next);
-		/*
-		 * Group ownership provides privilege, if the group list is
-		 * empty, the domain goes away. If it's the last domain with
-		 * iommu and external domain doesn't exist, then all the
-		 * mappings go away too. If it's the last domain with iommu and
-		 * external domain exist, update accounting
-		 */
-		if (list_empty(&domain->group_list)) {
-			if (list_is_singular(&iommu->domain_list)) {
-				if (list_empty(&iommu->emulated_iommu_groups)) {
-					WARN_ON(iommu->notifier.head);
-					vfio_iommu_unmap_unpin_all(iommu);
-				} else {
-					vfio_iommu_unmap_unpin_reaccount(iommu);
-				}
-			}
-			iommu_domain_free(domain->domain);
-			list_del(&domain->next);
-			kfree(domain);
-			vfio_iommu_aper_expand(iommu, &iova_copy);
-			vfio_update_pgsize_bitmap(iommu);
-			/*
-			 * Removal of a group without dirty tracking may allow
-			 * the iommu scope to be promoted.
-			 */
-			if (!group->pinned_page_dirty_scope) {
-				iommu->num_non_pinned_groups--;
-				if (iommu->dirty_page_tracking)
-					vfio_iommu_populate_bitmap_full(iommu);
-			}
-		}
+		vfio_iommu_detach_destroy_domain(domain, iommu, group);
 		kfree(group);
 		break;
 	}
 
+	vfio_iommu_aper_expand(iommu, &iova_copy);
 	if (!vfio_iommu_resv_refresh(iommu, &iova_copy))
 		vfio_iommu_iova_insert_copy(iommu, &iova_copy);
 	else
-- 
2.17.1


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

* [PATCH 5/5] vfio/iommu_type1: Simplify group attachment
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen via iommu @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

Un-inline the domain specific logic from the attach/detach_group ops into
two paired functions vfio_iommu_alloc_attach_domain() and
vfio_iommu_detach_destroy_domain() that strictly deal with creating and
destroying struct vfio_domains.

Add the logic to check for EMEDIUMTYPE return code of iommu_attach_group()
and avoid the extra domain allocations and attach/detach sequences of the
old code. This allows properly detecting an actual attach error, like
-ENOMEM, vs treating all attach errors as an incompatible domain.

Remove the duplicated domain->ops comparison that is taken care of in the
IOMMU core.

Co-developed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 306 +++++++++++++++++---------------
 1 file changed, 161 insertions(+), 145 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index b45b1cc118ef..c6f937e1d71f 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -86,6 +86,7 @@ struct vfio_domain {
 	struct list_head	group_list;
 	bool			fgsp : 1;	/* Fine-grained super pages */
 	bool			enforce_cache_coherency : 1;
+	bool			msi_cookie : 1;
 };
 
 struct vfio_dma {
@@ -2153,12 +2154,161 @@ static void vfio_iommu_iova_insert_copy(struct vfio_iommu *iommu,
 	list_splice_tail(iova_copy, iova);
 }
 
+static struct vfio_domain *
+vfio_iommu_alloc_attach_domain(struct bus_type *bus, struct vfio_iommu *iommu,
+			       struct vfio_iommu_group *group)
+{
+	struct iommu_domain *new_domain;
+	struct vfio_domain *domain;
+	int ret = 0;
+
+	/* Try to match an existing compatible domain */
+	list_for_each_entry (domain, &iommu->domain_list, next) {
+		ret = iommu_attach_group(domain->domain, group->iommu_group);
+		if (ret == -EMEDIUMTYPE)
+			continue;
+		if (ret)
+			return ERR_PTR(ret);
+		list_add(&group->next, &domain->group_list);
+		return domain;
+	}
+
+	new_domain = iommu_domain_alloc(bus);
+	if (!new_domain)
+		return ERR_PTR(-EIO);
+
+	if (iommu->nesting) {
+		ret = iommu_enable_nesting(new_domain);
+		if (ret)
+			goto out_free_iommu_domain;
+	}
+
+	ret = iommu_attach_group(new_domain, group->iommu_group);
+	if (ret)
+		goto out_free_iommu_domain;
+
+	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+	if (!domain) {
+		ret = -ENOMEM;
+		goto out_detach;
+	}
+
+	domain->domain = new_domain;
+	vfio_test_domain_fgsp(domain);
+
+	/*
+	 * If the IOMMU can block non-coherent operations (ie PCIe TLPs with
+	 * no-snoop set) then VFIO always turns this feature on because on Intel
+	 * platforms it optimizes KVM to disable wbinvd emulation.
+	 */
+	if (new_domain->ops->enforce_cache_coherency)
+		domain->enforce_cache_coherency =
+			new_domain->ops->enforce_cache_coherency(new_domain);
+
+	/* replay mappings on new domains */
+	ret = vfio_iommu_replay(iommu, domain);
+	if (ret)
+		goto out_free_domain;
+
+	/*
+	 * An iommu backed group can dirty memory directly and therefore
+	 * demotes the iommu scope until it declares itself dirty tracking
+	 * capable via the page pinning interface.
+	 */
+	iommu->num_non_pinned_groups++;
+
+	INIT_LIST_HEAD(&domain->group_list);
+	list_add(&group->next, &domain->group_list);
+	list_add(&domain->next, &iommu->domain_list);
+	vfio_update_pgsize_bitmap(iommu);
+	return domain;
+
+out_free_domain:
+	kfree(domain);
+out_detach:
+	iommu_detach_group(domain->domain, group->iommu_group);
+out_free_iommu_domain:
+	iommu_domain_free(new_domain);
+	return ERR_PTR(ret);
+}
+
+static void vfio_iommu_unmap_unpin_all(struct vfio_iommu *iommu)
+{
+	struct rb_node *node;
+
+	while ((node = rb_first(&iommu->dma_list)))
+		vfio_remove_dma(iommu, rb_entry(node, struct vfio_dma, node));
+}
+
+static void vfio_iommu_unmap_unpin_reaccount(struct vfio_iommu *iommu)
+{
+	struct rb_node *n, *p;
+
+	n = rb_first(&iommu->dma_list);
+	for (; n; n = rb_next(n)) {
+		struct vfio_dma *dma;
+		long locked = 0, unlocked = 0;
+
+		dma = rb_entry(n, struct vfio_dma, node);
+		unlocked += vfio_unmap_unpin(iommu, dma, false);
+		p = rb_first(&dma->pfn_list);
+		for (; p; p = rb_next(p)) {
+			struct vfio_pfn *vpfn = rb_entry(p, struct vfio_pfn,
+							 node);
+
+			if (!is_invalid_reserved_pfn(vpfn->pfn))
+				locked++;
+		}
+		vfio_lock_acct(dma, locked - unlocked, true);
+	}
+}
+
+static void vfio_iommu_detach_destroy_domain(struct vfio_domain *domain,
+					     struct vfio_iommu *iommu,
+					     struct vfio_iommu_group *group)
+{
+	iommu_detach_group(domain->domain, group->iommu_group);
+	list_del(&group->next);
+	if (!list_empty(&domain->group_list))
+		return;
+
+	/*
+	 * Group ownership provides privilege, if the group list is empty, the
+	 * domain goes away. If it's the last domain with iommu and external
+	 * domain doesn't exist, then all the mappings go away too. If it's the
+	 * last domain with iommu and external domain exist, update accounting
+	 */
+	if (list_is_singular(&iommu->domain_list)) {
+		if (list_empty(&iommu->emulated_iommu_groups)) {
+			WARN_ON(iommu->notifier.head);
+			vfio_iommu_unmap_unpin_all(iommu);
+		} else {
+			vfio_iommu_unmap_unpin_reaccount(iommu);
+		}
+	}
+	iommu_domain_free(domain->domain);
+	list_del(&domain->next);
+	kfree(domain);
+
+	/*
+	 * Removal of a group without dirty tracking may allow the iommu scope
+	 * to be promoted.
+	 */
+	if (!group->pinned_page_dirty_scope) {
+		iommu->num_non_pinned_groups--;
+		if (iommu->dirty_page_tracking)
+			vfio_iommu_populate_bitmap_full(iommu);
+	}
+
+	vfio_update_pgsize_bitmap(iommu);
+}
+
 static int vfio_iommu_type1_attach_group(void *iommu_data,
 		struct iommu_group *iommu_group, enum vfio_group_type type)
 {
 	struct vfio_iommu *iommu = iommu_data;
 	struct vfio_iommu_group *group;
-	struct vfio_domain *domain, *d;
+	struct vfio_domain *domain;
 	struct bus_type *bus = NULL;
 	bool resv_msi, msi_remap;
 	phys_addr_t resv_msi_base = 0;
@@ -2197,26 +2347,12 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 	if (ret)
 		goto out_free_group;
 
-	ret = -ENOMEM;
-	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
-	if (!domain)
+	domain = vfio_iommu_alloc_attach_domain(bus, iommu, group);
+	if (IS_ERR(domain)) {
+		ret = PTR_ERR(domain);
 		goto out_free_group;
-
-	ret = -EIO;
-	domain->domain = iommu_domain_alloc(bus);
-	if (!domain->domain)
-		goto out_free_domain;
-
-	if (iommu->nesting) {
-		ret = iommu_enable_nesting(domain->domain);
-		if (ret)
-			goto out_domain;
 	}
 
-	ret = iommu_attach_group(domain->domain, group->iommu_group);
-	if (ret)
-		goto out_domain;
-
 	/* Get aperture info */
 	geo = &domain->domain->geometry;
 	if (vfio_iommu_aper_conflict(iommu, geo->aperture_start,
@@ -2254,9 +2390,6 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 
 	resv_msi = vfio_iommu_has_sw_msi(&group_resv_regions, &resv_msi_base);
 
-	INIT_LIST_HEAD(&domain->group_list);
-	list_add(&group->next, &domain->group_list);
-
 	msi_remap = irq_domain_check_msi_remap() ||
 		    iommu_capable(bus, IOMMU_CAP_INTR_REMAP);
 
@@ -2267,117 +2400,32 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 		goto out_detach;
 	}
 
-	/*
-	 * If the IOMMU can block non-coherent operations (ie PCIe TLPs with
-	 * no-snoop set) then VFIO always turns this feature on because on Intel
-	 * platforms it optimizes KVM to disable wbinvd emulation.
-	 */
-	if (domain->domain->ops->enforce_cache_coherency)
-		domain->enforce_cache_coherency =
-			domain->domain->ops->enforce_cache_coherency(
-				domain->domain);
-
-	/*
-	 * Try to match an existing compatible domain.  We don't want to
-	 * preclude an IOMMU driver supporting multiple bus_types and being
-	 * able to include different bus_types in the same IOMMU domain, so
-	 * we test whether the domains use the same iommu_ops rather than
-	 * testing if they're on the same bus_type.
-	 */
-	list_for_each_entry(d, &iommu->domain_list, next) {
-		if (d->domain->ops == domain->domain->ops) {
-			iommu_detach_group(domain->domain, group->iommu_group);
-			if (!iommu_attach_group(d->domain,
-						group->iommu_group)) {
-				list_add(&group->next, &d->group_list);
-				iommu_domain_free(domain->domain);
-				kfree(domain);
-				goto done;
-			}
-
-			ret = iommu_attach_group(domain->domain,
-						 group->iommu_group);
-			if (ret)
-				goto out_domain;
-		}
-	}
-
-	vfio_test_domain_fgsp(domain);
-
-	/* replay mappings on new domains */
-	ret = vfio_iommu_replay(iommu, domain);
-	if (ret)
-		goto out_detach;
-
-	if (resv_msi) {
+	if (resv_msi && !domain->msi_cookie) {
 		ret = iommu_get_msi_cookie(domain->domain, resv_msi_base);
 		if (ret && ret != -ENODEV)
 			goto out_detach;
+		domain->msi_cookie = true;
 	}
 
-	list_add(&domain->next, &iommu->domain_list);
-	vfio_update_pgsize_bitmap(iommu);
-done:
 	/* Delete the old one and insert new iova list */
 	vfio_iommu_iova_insert_copy(iommu, &iova_copy);
 
-	/*
-	 * An iommu backed group can dirty memory directly and therefore
-	 * demotes the iommu scope until it declares itself dirty tracking
-	 * capable via the page pinning interface.
-	 */
-	iommu->num_non_pinned_groups++;
 	mutex_unlock(&iommu->lock);
 	vfio_iommu_resv_free(&group_resv_regions);
 
 	return 0;
 
 out_detach:
-	iommu_detach_group(domain->domain, group->iommu_group);
-out_domain:
-	iommu_domain_free(domain->domain);
-	vfio_iommu_iova_free(&iova_copy);
-	vfio_iommu_resv_free(&group_resv_regions);
-out_free_domain:
-	kfree(domain);
+	vfio_iommu_detach_destroy_domain(domain, iommu, group);
 out_free_group:
 	kfree(group);
 out_unlock:
 	mutex_unlock(&iommu->lock);
+	vfio_iommu_iova_free(&iova_copy);
+	vfio_iommu_resv_free(&group_resv_regions);
 	return ret;
 }
 
-static void vfio_iommu_unmap_unpin_all(struct vfio_iommu *iommu)
-{
-	struct rb_node *node;
-
-	while ((node = rb_first(&iommu->dma_list)))
-		vfio_remove_dma(iommu, rb_entry(node, struct vfio_dma, node));
-}
-
-static void vfio_iommu_unmap_unpin_reaccount(struct vfio_iommu *iommu)
-{
-	struct rb_node *n, *p;
-
-	n = rb_first(&iommu->dma_list);
-	for (; n; n = rb_next(n)) {
-		struct vfio_dma *dma;
-		long locked = 0, unlocked = 0;
-
-		dma = rb_entry(n, struct vfio_dma, node);
-		unlocked += vfio_unmap_unpin(iommu, dma, false);
-		p = rb_first(&dma->pfn_list);
-		for (; p; p = rb_next(p)) {
-			struct vfio_pfn *vpfn = rb_entry(p, struct vfio_pfn,
-							 node);
-
-			if (!is_invalid_reserved_pfn(vpfn->pfn))
-				locked++;
-		}
-		vfio_lock_acct(dma, locked - unlocked, true);
-	}
-}
-
 /*
  * Called when a domain is removed in detach. It is possible that
  * the removed domain decided the iova aperture window. Modify the
@@ -2491,44 +2539,12 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 		group = find_iommu_group(domain, iommu_group);
 		if (!group)
 			continue;
-
-		iommu_detach_group(domain->domain, group->iommu_group);
-		list_del(&group->next);
-		/*
-		 * Group ownership provides privilege, if the group list is
-		 * empty, the domain goes away. If it's the last domain with
-		 * iommu and external domain doesn't exist, then all the
-		 * mappings go away too. If it's the last domain with iommu and
-		 * external domain exist, update accounting
-		 */
-		if (list_empty(&domain->group_list)) {
-			if (list_is_singular(&iommu->domain_list)) {
-				if (list_empty(&iommu->emulated_iommu_groups)) {
-					WARN_ON(iommu->notifier.head);
-					vfio_iommu_unmap_unpin_all(iommu);
-				} else {
-					vfio_iommu_unmap_unpin_reaccount(iommu);
-				}
-			}
-			iommu_domain_free(domain->domain);
-			list_del(&domain->next);
-			kfree(domain);
-			vfio_iommu_aper_expand(iommu, &iova_copy);
-			vfio_update_pgsize_bitmap(iommu);
-			/*
-			 * Removal of a group without dirty tracking may allow
-			 * the iommu scope to be promoted.
-			 */
-			if (!group->pinned_page_dirty_scope) {
-				iommu->num_non_pinned_groups--;
-				if (iommu->dirty_page_tracking)
-					vfio_iommu_populate_bitmap_full(iommu);
-			}
-		}
+		vfio_iommu_detach_destroy_domain(domain, iommu, group);
 		kfree(group);
 		break;
 	}
 
+	vfio_iommu_aper_expand(iommu, &iova_copy);
 	if (!vfio_iommu_resv_refresh(iommu, &iova_copy))
 		vfio_iommu_iova_insert_copy(iommu, &iova_copy);
 	else
-- 
2.17.1

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

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

* [PATCH 5/5] vfio/iommu_type1: Simplify group attachment
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

Un-inline the domain specific logic from the attach/detach_group ops into
two paired functions vfio_iommu_alloc_attach_domain() and
vfio_iommu_detach_destroy_domain() that strictly deal with creating and
destroying struct vfio_domains.

Add the logic to check for EMEDIUMTYPE return code of iommu_attach_group()
and avoid the extra domain allocations and attach/detach sequences of the
old code. This allows properly detecting an actual attach error, like
-ENOMEM, vs treating all attach errors as an incompatible domain.

Remove the duplicated domain->ops comparison that is taken care of in the
IOMMU core.

Co-developed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 306 +++++++++++++++++---------------
 1 file changed, 161 insertions(+), 145 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index b45b1cc118ef..c6f937e1d71f 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -86,6 +86,7 @@ struct vfio_domain {
 	struct list_head	group_list;
 	bool			fgsp : 1;	/* Fine-grained super pages */
 	bool			enforce_cache_coherency : 1;
+	bool			msi_cookie : 1;
 };
 
 struct vfio_dma {
@@ -2153,12 +2154,161 @@ static void vfio_iommu_iova_insert_copy(struct vfio_iommu *iommu,
 	list_splice_tail(iova_copy, iova);
 }
 
+static struct vfio_domain *
+vfio_iommu_alloc_attach_domain(struct bus_type *bus, struct vfio_iommu *iommu,
+			       struct vfio_iommu_group *group)
+{
+	struct iommu_domain *new_domain;
+	struct vfio_domain *domain;
+	int ret = 0;
+
+	/* Try to match an existing compatible domain */
+	list_for_each_entry (domain, &iommu->domain_list, next) {
+		ret = iommu_attach_group(domain->domain, group->iommu_group);
+		if (ret == -EMEDIUMTYPE)
+			continue;
+		if (ret)
+			return ERR_PTR(ret);
+		list_add(&group->next, &domain->group_list);
+		return domain;
+	}
+
+	new_domain = iommu_domain_alloc(bus);
+	if (!new_domain)
+		return ERR_PTR(-EIO);
+
+	if (iommu->nesting) {
+		ret = iommu_enable_nesting(new_domain);
+		if (ret)
+			goto out_free_iommu_domain;
+	}
+
+	ret = iommu_attach_group(new_domain, group->iommu_group);
+	if (ret)
+		goto out_free_iommu_domain;
+
+	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+	if (!domain) {
+		ret = -ENOMEM;
+		goto out_detach;
+	}
+
+	domain->domain = new_domain;
+	vfio_test_domain_fgsp(domain);
+
+	/*
+	 * If the IOMMU can block non-coherent operations (ie PCIe TLPs with
+	 * no-snoop set) then VFIO always turns this feature on because on Intel
+	 * platforms it optimizes KVM to disable wbinvd emulation.
+	 */
+	if (new_domain->ops->enforce_cache_coherency)
+		domain->enforce_cache_coherency =
+			new_domain->ops->enforce_cache_coherency(new_domain);
+
+	/* replay mappings on new domains */
+	ret = vfio_iommu_replay(iommu, domain);
+	if (ret)
+		goto out_free_domain;
+
+	/*
+	 * An iommu backed group can dirty memory directly and therefore
+	 * demotes the iommu scope until it declares itself dirty tracking
+	 * capable via the page pinning interface.
+	 */
+	iommu->num_non_pinned_groups++;
+
+	INIT_LIST_HEAD(&domain->group_list);
+	list_add(&group->next, &domain->group_list);
+	list_add(&domain->next, &iommu->domain_list);
+	vfio_update_pgsize_bitmap(iommu);
+	return domain;
+
+out_free_domain:
+	kfree(domain);
+out_detach:
+	iommu_detach_group(domain->domain, group->iommu_group);
+out_free_iommu_domain:
+	iommu_domain_free(new_domain);
+	return ERR_PTR(ret);
+}
+
+static void vfio_iommu_unmap_unpin_all(struct vfio_iommu *iommu)
+{
+	struct rb_node *node;
+
+	while ((node = rb_first(&iommu->dma_list)))
+		vfio_remove_dma(iommu, rb_entry(node, struct vfio_dma, node));
+}
+
+static void vfio_iommu_unmap_unpin_reaccount(struct vfio_iommu *iommu)
+{
+	struct rb_node *n, *p;
+
+	n = rb_first(&iommu->dma_list);
+	for (; n; n = rb_next(n)) {
+		struct vfio_dma *dma;
+		long locked = 0, unlocked = 0;
+
+		dma = rb_entry(n, struct vfio_dma, node);
+		unlocked += vfio_unmap_unpin(iommu, dma, false);
+		p = rb_first(&dma->pfn_list);
+		for (; p; p = rb_next(p)) {
+			struct vfio_pfn *vpfn = rb_entry(p, struct vfio_pfn,
+							 node);
+
+			if (!is_invalid_reserved_pfn(vpfn->pfn))
+				locked++;
+		}
+		vfio_lock_acct(dma, locked - unlocked, true);
+	}
+}
+
+static void vfio_iommu_detach_destroy_domain(struct vfio_domain *domain,
+					     struct vfio_iommu *iommu,
+					     struct vfio_iommu_group *group)
+{
+	iommu_detach_group(domain->domain, group->iommu_group);
+	list_del(&group->next);
+	if (!list_empty(&domain->group_list))
+		return;
+
+	/*
+	 * Group ownership provides privilege, if the group list is empty, the
+	 * domain goes away. If it's the last domain with iommu and external
+	 * domain doesn't exist, then all the mappings go away too. If it's the
+	 * last domain with iommu and external domain exist, update accounting
+	 */
+	if (list_is_singular(&iommu->domain_list)) {
+		if (list_empty(&iommu->emulated_iommu_groups)) {
+			WARN_ON(iommu->notifier.head);
+			vfio_iommu_unmap_unpin_all(iommu);
+		} else {
+			vfio_iommu_unmap_unpin_reaccount(iommu);
+		}
+	}
+	iommu_domain_free(domain->domain);
+	list_del(&domain->next);
+	kfree(domain);
+
+	/*
+	 * Removal of a group without dirty tracking may allow the iommu scope
+	 * to be promoted.
+	 */
+	if (!group->pinned_page_dirty_scope) {
+		iommu->num_non_pinned_groups--;
+		if (iommu->dirty_page_tracking)
+			vfio_iommu_populate_bitmap_full(iommu);
+	}
+
+	vfio_update_pgsize_bitmap(iommu);
+}
+
 static int vfio_iommu_type1_attach_group(void *iommu_data,
 		struct iommu_group *iommu_group, enum vfio_group_type type)
 {
 	struct vfio_iommu *iommu = iommu_data;
 	struct vfio_iommu_group *group;
-	struct vfio_domain *domain, *d;
+	struct vfio_domain *domain;
 	struct bus_type *bus = NULL;
 	bool resv_msi, msi_remap;
 	phys_addr_t resv_msi_base = 0;
@@ -2197,26 +2347,12 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 	if (ret)
 		goto out_free_group;
 
-	ret = -ENOMEM;
-	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
-	if (!domain)
+	domain = vfio_iommu_alloc_attach_domain(bus, iommu, group);
+	if (IS_ERR(domain)) {
+		ret = PTR_ERR(domain);
 		goto out_free_group;
-
-	ret = -EIO;
-	domain->domain = iommu_domain_alloc(bus);
-	if (!domain->domain)
-		goto out_free_domain;
-
-	if (iommu->nesting) {
-		ret = iommu_enable_nesting(domain->domain);
-		if (ret)
-			goto out_domain;
 	}
 
-	ret = iommu_attach_group(domain->domain, group->iommu_group);
-	if (ret)
-		goto out_domain;
-
 	/* Get aperture info */
 	geo = &domain->domain->geometry;
 	if (vfio_iommu_aper_conflict(iommu, geo->aperture_start,
@@ -2254,9 +2390,6 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 
 	resv_msi = vfio_iommu_has_sw_msi(&group_resv_regions, &resv_msi_base);
 
-	INIT_LIST_HEAD(&domain->group_list);
-	list_add(&group->next, &domain->group_list);
-
 	msi_remap = irq_domain_check_msi_remap() ||
 		    iommu_capable(bus, IOMMU_CAP_INTR_REMAP);
 
@@ -2267,117 +2400,32 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 		goto out_detach;
 	}
 
-	/*
-	 * If the IOMMU can block non-coherent operations (ie PCIe TLPs with
-	 * no-snoop set) then VFIO always turns this feature on because on Intel
-	 * platforms it optimizes KVM to disable wbinvd emulation.
-	 */
-	if (domain->domain->ops->enforce_cache_coherency)
-		domain->enforce_cache_coherency =
-			domain->domain->ops->enforce_cache_coherency(
-				domain->domain);
-
-	/*
-	 * Try to match an existing compatible domain.  We don't want to
-	 * preclude an IOMMU driver supporting multiple bus_types and being
-	 * able to include different bus_types in the same IOMMU domain, so
-	 * we test whether the domains use the same iommu_ops rather than
-	 * testing if they're on the same bus_type.
-	 */
-	list_for_each_entry(d, &iommu->domain_list, next) {
-		if (d->domain->ops == domain->domain->ops) {
-			iommu_detach_group(domain->domain, group->iommu_group);
-			if (!iommu_attach_group(d->domain,
-						group->iommu_group)) {
-				list_add(&group->next, &d->group_list);
-				iommu_domain_free(domain->domain);
-				kfree(domain);
-				goto done;
-			}
-
-			ret = iommu_attach_group(domain->domain,
-						 group->iommu_group);
-			if (ret)
-				goto out_domain;
-		}
-	}
-
-	vfio_test_domain_fgsp(domain);
-
-	/* replay mappings on new domains */
-	ret = vfio_iommu_replay(iommu, domain);
-	if (ret)
-		goto out_detach;
-
-	if (resv_msi) {
+	if (resv_msi && !domain->msi_cookie) {
 		ret = iommu_get_msi_cookie(domain->domain, resv_msi_base);
 		if (ret && ret != -ENODEV)
 			goto out_detach;
+		domain->msi_cookie = true;
 	}
 
-	list_add(&domain->next, &iommu->domain_list);
-	vfio_update_pgsize_bitmap(iommu);
-done:
 	/* Delete the old one and insert new iova list */
 	vfio_iommu_iova_insert_copy(iommu, &iova_copy);
 
-	/*
-	 * An iommu backed group can dirty memory directly and therefore
-	 * demotes the iommu scope until it declares itself dirty tracking
-	 * capable via the page pinning interface.
-	 */
-	iommu->num_non_pinned_groups++;
 	mutex_unlock(&iommu->lock);
 	vfio_iommu_resv_free(&group_resv_regions);
 
 	return 0;
 
 out_detach:
-	iommu_detach_group(domain->domain, group->iommu_group);
-out_domain:
-	iommu_domain_free(domain->domain);
-	vfio_iommu_iova_free(&iova_copy);
-	vfio_iommu_resv_free(&group_resv_regions);
-out_free_domain:
-	kfree(domain);
+	vfio_iommu_detach_destroy_domain(domain, iommu, group);
 out_free_group:
 	kfree(group);
 out_unlock:
 	mutex_unlock(&iommu->lock);
+	vfio_iommu_iova_free(&iova_copy);
+	vfio_iommu_resv_free(&group_resv_regions);
 	return ret;
 }
 
-static void vfio_iommu_unmap_unpin_all(struct vfio_iommu *iommu)
-{
-	struct rb_node *node;
-
-	while ((node = rb_first(&iommu->dma_list)))
-		vfio_remove_dma(iommu, rb_entry(node, struct vfio_dma, node));
-}
-
-static void vfio_iommu_unmap_unpin_reaccount(struct vfio_iommu *iommu)
-{
-	struct rb_node *n, *p;
-
-	n = rb_first(&iommu->dma_list);
-	for (; n; n = rb_next(n)) {
-		struct vfio_dma *dma;
-		long locked = 0, unlocked = 0;
-
-		dma = rb_entry(n, struct vfio_dma, node);
-		unlocked += vfio_unmap_unpin(iommu, dma, false);
-		p = rb_first(&dma->pfn_list);
-		for (; p; p = rb_next(p)) {
-			struct vfio_pfn *vpfn = rb_entry(p, struct vfio_pfn,
-							 node);
-
-			if (!is_invalid_reserved_pfn(vpfn->pfn))
-				locked++;
-		}
-		vfio_lock_acct(dma, locked - unlocked, true);
-	}
-}
-
 /*
  * Called when a domain is removed in detach. It is possible that
  * the removed domain decided the iova aperture window. Modify the
@@ -2491,44 +2539,12 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 		group = find_iommu_group(domain, iommu_group);
 		if (!group)
 			continue;
-
-		iommu_detach_group(domain->domain, group->iommu_group);
-		list_del(&group->next);
-		/*
-		 * Group ownership provides privilege, if the group list is
-		 * empty, the domain goes away. If it's the last domain with
-		 * iommu and external domain doesn't exist, then all the
-		 * mappings go away too. If it's the last domain with iommu and
-		 * external domain exist, update accounting
-		 */
-		if (list_empty(&domain->group_list)) {
-			if (list_is_singular(&iommu->domain_list)) {
-				if (list_empty(&iommu->emulated_iommu_groups)) {
-					WARN_ON(iommu->notifier.head);
-					vfio_iommu_unmap_unpin_all(iommu);
-				} else {
-					vfio_iommu_unmap_unpin_reaccount(iommu);
-				}
-			}
-			iommu_domain_free(domain->domain);
-			list_del(&domain->next);
-			kfree(domain);
-			vfio_iommu_aper_expand(iommu, &iova_copy);
-			vfio_update_pgsize_bitmap(iommu);
-			/*
-			 * Removal of a group without dirty tracking may allow
-			 * the iommu scope to be promoted.
-			 */
-			if (!group->pinned_page_dirty_scope) {
-				iommu->num_non_pinned_groups--;
-				if (iommu->dirty_page_tracking)
-					vfio_iommu_populate_bitmap_full(iommu);
-			}
-		}
+		vfio_iommu_detach_destroy_domain(domain, iommu, group);
 		kfree(group);
 		break;
 	}
 
+	vfio_iommu_aper_expand(iommu, &iova_copy);
 	if (!vfio_iommu_resv_refresh(iommu, &iova_copy))
 		vfio_iommu_iova_insert_copy(iommu, &iova_copy);
 	else
-- 
2.17.1


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

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

* [PATCH 5/5] vfio/iommu_type1: Simplify group attachment
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

Un-inline the domain specific logic from the attach/detach_group ops into
two paired functions vfio_iommu_alloc_attach_domain() and
vfio_iommu_detach_destroy_domain() that strictly deal with creating and
destroying struct vfio_domains.

Add the logic to check for EMEDIUMTYPE return code of iommu_attach_group()
and avoid the extra domain allocations and attach/detach sequences of the
old code. This allows properly detecting an actual attach error, like
-ENOMEM, vs treating all attach errors as an incompatible domain.

Remove the duplicated domain->ops comparison that is taken care of in the
IOMMU core.

Co-developed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 306 +++++++++++++++++---------------
 1 file changed, 161 insertions(+), 145 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index b45b1cc118ef..c6f937e1d71f 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -86,6 +86,7 @@ struct vfio_domain {
 	struct list_head	group_list;
 	bool			fgsp : 1;	/* Fine-grained super pages */
 	bool			enforce_cache_coherency : 1;
+	bool			msi_cookie : 1;
 };
 
 struct vfio_dma {
@@ -2153,12 +2154,161 @@ static void vfio_iommu_iova_insert_copy(struct vfio_iommu *iommu,
 	list_splice_tail(iova_copy, iova);
 }
 
+static struct vfio_domain *
+vfio_iommu_alloc_attach_domain(struct bus_type *bus, struct vfio_iommu *iommu,
+			       struct vfio_iommu_group *group)
+{
+	struct iommu_domain *new_domain;
+	struct vfio_domain *domain;
+	int ret = 0;
+
+	/* Try to match an existing compatible domain */
+	list_for_each_entry (domain, &iommu->domain_list, next) {
+		ret = iommu_attach_group(domain->domain, group->iommu_group);
+		if (ret == -EMEDIUMTYPE)
+			continue;
+		if (ret)
+			return ERR_PTR(ret);
+		list_add(&group->next, &domain->group_list);
+		return domain;
+	}
+
+	new_domain = iommu_domain_alloc(bus);
+	if (!new_domain)
+		return ERR_PTR(-EIO);
+
+	if (iommu->nesting) {
+		ret = iommu_enable_nesting(new_domain);
+		if (ret)
+			goto out_free_iommu_domain;
+	}
+
+	ret = iommu_attach_group(new_domain, group->iommu_group);
+	if (ret)
+		goto out_free_iommu_domain;
+
+	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+	if (!domain) {
+		ret = -ENOMEM;
+		goto out_detach;
+	}
+
+	domain->domain = new_domain;
+	vfio_test_domain_fgsp(domain);
+
+	/*
+	 * If the IOMMU can block non-coherent operations (ie PCIe TLPs with
+	 * no-snoop set) then VFIO always turns this feature on because on Intel
+	 * platforms it optimizes KVM to disable wbinvd emulation.
+	 */
+	if (new_domain->ops->enforce_cache_coherency)
+		domain->enforce_cache_coherency =
+			new_domain->ops->enforce_cache_coherency(new_domain);
+
+	/* replay mappings on new domains */
+	ret = vfio_iommu_replay(iommu, domain);
+	if (ret)
+		goto out_free_domain;
+
+	/*
+	 * An iommu backed group can dirty memory directly and therefore
+	 * demotes the iommu scope until it declares itself dirty tracking
+	 * capable via the page pinning interface.
+	 */
+	iommu->num_non_pinned_groups++;
+
+	INIT_LIST_HEAD(&domain->group_list);
+	list_add(&group->next, &domain->group_list);
+	list_add(&domain->next, &iommu->domain_list);
+	vfio_update_pgsize_bitmap(iommu);
+	return domain;
+
+out_free_domain:
+	kfree(domain);
+out_detach:
+	iommu_detach_group(domain->domain, group->iommu_group);
+out_free_iommu_domain:
+	iommu_domain_free(new_domain);
+	return ERR_PTR(ret);
+}
+
+static void vfio_iommu_unmap_unpin_all(struct vfio_iommu *iommu)
+{
+	struct rb_node *node;
+
+	while ((node = rb_first(&iommu->dma_list)))
+		vfio_remove_dma(iommu, rb_entry(node, struct vfio_dma, node));
+}
+
+static void vfio_iommu_unmap_unpin_reaccount(struct vfio_iommu *iommu)
+{
+	struct rb_node *n, *p;
+
+	n = rb_first(&iommu->dma_list);
+	for (; n; n = rb_next(n)) {
+		struct vfio_dma *dma;
+		long locked = 0, unlocked = 0;
+
+		dma = rb_entry(n, struct vfio_dma, node);
+		unlocked += vfio_unmap_unpin(iommu, dma, false);
+		p = rb_first(&dma->pfn_list);
+		for (; p; p = rb_next(p)) {
+			struct vfio_pfn *vpfn = rb_entry(p, struct vfio_pfn,
+							 node);
+
+			if (!is_invalid_reserved_pfn(vpfn->pfn))
+				locked++;
+		}
+		vfio_lock_acct(dma, locked - unlocked, true);
+	}
+}
+
+static void vfio_iommu_detach_destroy_domain(struct vfio_domain *domain,
+					     struct vfio_iommu *iommu,
+					     struct vfio_iommu_group *group)
+{
+	iommu_detach_group(domain->domain, group->iommu_group);
+	list_del(&group->next);
+	if (!list_empty(&domain->group_list))
+		return;
+
+	/*
+	 * Group ownership provides privilege, if the group list is empty, the
+	 * domain goes away. If it's the last domain with iommu and external
+	 * domain doesn't exist, then all the mappings go away too. If it's the
+	 * last domain with iommu and external domain exist, update accounting
+	 */
+	if (list_is_singular(&iommu->domain_list)) {
+		if (list_empty(&iommu->emulated_iommu_groups)) {
+			WARN_ON(iommu->notifier.head);
+			vfio_iommu_unmap_unpin_all(iommu);
+		} else {
+			vfio_iommu_unmap_unpin_reaccount(iommu);
+		}
+	}
+	iommu_domain_free(domain->domain);
+	list_del(&domain->next);
+	kfree(domain);
+
+	/*
+	 * Removal of a group without dirty tracking may allow the iommu scope
+	 * to be promoted.
+	 */
+	if (!group->pinned_page_dirty_scope) {
+		iommu->num_non_pinned_groups--;
+		if (iommu->dirty_page_tracking)
+			vfio_iommu_populate_bitmap_full(iommu);
+	}
+
+	vfio_update_pgsize_bitmap(iommu);
+}
+
 static int vfio_iommu_type1_attach_group(void *iommu_data,
 		struct iommu_group *iommu_group, enum vfio_group_type type)
 {
 	struct vfio_iommu *iommu = iommu_data;
 	struct vfio_iommu_group *group;
-	struct vfio_domain *domain, *d;
+	struct vfio_domain *domain;
 	struct bus_type *bus = NULL;
 	bool resv_msi, msi_remap;
 	phys_addr_t resv_msi_base = 0;
@@ -2197,26 +2347,12 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 	if (ret)
 		goto out_free_group;
 
-	ret = -ENOMEM;
-	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
-	if (!domain)
+	domain = vfio_iommu_alloc_attach_domain(bus, iommu, group);
+	if (IS_ERR(domain)) {
+		ret = PTR_ERR(domain);
 		goto out_free_group;
-
-	ret = -EIO;
-	domain->domain = iommu_domain_alloc(bus);
-	if (!domain->domain)
-		goto out_free_domain;
-
-	if (iommu->nesting) {
-		ret = iommu_enable_nesting(domain->domain);
-		if (ret)
-			goto out_domain;
 	}
 
-	ret = iommu_attach_group(domain->domain, group->iommu_group);
-	if (ret)
-		goto out_domain;
-
 	/* Get aperture info */
 	geo = &domain->domain->geometry;
 	if (vfio_iommu_aper_conflict(iommu, geo->aperture_start,
@@ -2254,9 +2390,6 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 
 	resv_msi = vfio_iommu_has_sw_msi(&group_resv_regions, &resv_msi_base);
 
-	INIT_LIST_HEAD(&domain->group_list);
-	list_add(&group->next, &domain->group_list);
-
 	msi_remap = irq_domain_check_msi_remap() ||
 		    iommu_capable(bus, IOMMU_CAP_INTR_REMAP);
 
@@ -2267,117 +2400,32 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 		goto out_detach;
 	}
 
-	/*
-	 * If the IOMMU can block non-coherent operations (ie PCIe TLPs with
-	 * no-snoop set) then VFIO always turns this feature on because on Intel
-	 * platforms it optimizes KVM to disable wbinvd emulation.
-	 */
-	if (domain->domain->ops->enforce_cache_coherency)
-		domain->enforce_cache_coherency =
-			domain->domain->ops->enforce_cache_coherency(
-				domain->domain);
-
-	/*
-	 * Try to match an existing compatible domain.  We don't want to
-	 * preclude an IOMMU driver supporting multiple bus_types and being
-	 * able to include different bus_types in the same IOMMU domain, so
-	 * we test whether the domains use the same iommu_ops rather than
-	 * testing if they're on the same bus_type.
-	 */
-	list_for_each_entry(d, &iommu->domain_list, next) {
-		if (d->domain->ops == domain->domain->ops) {
-			iommu_detach_group(domain->domain, group->iommu_group);
-			if (!iommu_attach_group(d->domain,
-						group->iommu_group)) {
-				list_add(&group->next, &d->group_list);
-				iommu_domain_free(domain->domain);
-				kfree(domain);
-				goto done;
-			}
-
-			ret = iommu_attach_group(domain->domain,
-						 group->iommu_group);
-			if (ret)
-				goto out_domain;
-		}
-	}
-
-	vfio_test_domain_fgsp(domain);
-
-	/* replay mappings on new domains */
-	ret = vfio_iommu_replay(iommu, domain);
-	if (ret)
-		goto out_detach;
-
-	if (resv_msi) {
+	if (resv_msi && !domain->msi_cookie) {
 		ret = iommu_get_msi_cookie(domain->domain, resv_msi_base);
 		if (ret && ret != -ENODEV)
 			goto out_detach;
+		domain->msi_cookie = true;
 	}
 
-	list_add(&domain->next, &iommu->domain_list);
-	vfio_update_pgsize_bitmap(iommu);
-done:
 	/* Delete the old one and insert new iova list */
 	vfio_iommu_iova_insert_copy(iommu, &iova_copy);
 
-	/*
-	 * An iommu backed group can dirty memory directly and therefore
-	 * demotes the iommu scope until it declares itself dirty tracking
-	 * capable via the page pinning interface.
-	 */
-	iommu->num_non_pinned_groups++;
 	mutex_unlock(&iommu->lock);
 	vfio_iommu_resv_free(&group_resv_regions);
 
 	return 0;
 
 out_detach:
-	iommu_detach_group(domain->domain, group->iommu_group);
-out_domain:
-	iommu_domain_free(domain->domain);
-	vfio_iommu_iova_free(&iova_copy);
-	vfio_iommu_resv_free(&group_resv_regions);
-out_free_domain:
-	kfree(domain);
+	vfio_iommu_detach_destroy_domain(domain, iommu, group);
 out_free_group:
 	kfree(group);
 out_unlock:
 	mutex_unlock(&iommu->lock);
+	vfio_iommu_iova_free(&iova_copy);
+	vfio_iommu_resv_free(&group_resv_regions);
 	return ret;
 }
 
-static void vfio_iommu_unmap_unpin_all(struct vfio_iommu *iommu)
-{
-	struct rb_node *node;
-
-	while ((node = rb_first(&iommu->dma_list)))
-		vfio_remove_dma(iommu, rb_entry(node, struct vfio_dma, node));
-}
-
-static void vfio_iommu_unmap_unpin_reaccount(struct vfio_iommu *iommu)
-{
-	struct rb_node *n, *p;
-
-	n = rb_first(&iommu->dma_list);
-	for (; n; n = rb_next(n)) {
-		struct vfio_dma *dma;
-		long locked = 0, unlocked = 0;
-
-		dma = rb_entry(n, struct vfio_dma, node);
-		unlocked += vfio_unmap_unpin(iommu, dma, false);
-		p = rb_first(&dma->pfn_list);
-		for (; p; p = rb_next(p)) {
-			struct vfio_pfn *vpfn = rb_entry(p, struct vfio_pfn,
-							 node);
-
-			if (!is_invalid_reserved_pfn(vpfn->pfn))
-				locked++;
-		}
-		vfio_lock_acct(dma, locked - unlocked, true);
-	}
-}
-
 /*
  * Called when a domain is removed in detach. It is possible that
  * the removed domain decided the iova aperture window. Modify the
@@ -2491,44 +2539,12 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 		group = find_iommu_group(domain, iommu_group);
 		if (!group)
 			continue;
-
-		iommu_detach_group(domain->domain, group->iommu_group);
-		list_del(&group->next);
-		/*
-		 * Group ownership provides privilege, if the group list is
-		 * empty, the domain goes away. If it's the last domain with
-		 * iommu and external domain doesn't exist, then all the
-		 * mappings go away too. If it's the last domain with iommu and
-		 * external domain exist, update accounting
-		 */
-		if (list_empty(&domain->group_list)) {
-			if (list_is_singular(&iommu->domain_list)) {
-				if (list_empty(&iommu->emulated_iommu_groups)) {
-					WARN_ON(iommu->notifier.head);
-					vfio_iommu_unmap_unpin_all(iommu);
-				} else {
-					vfio_iommu_unmap_unpin_reaccount(iommu);
-				}
-			}
-			iommu_domain_free(domain->domain);
-			list_del(&domain->next);
-			kfree(domain);
-			vfio_iommu_aper_expand(iommu, &iova_copy);
-			vfio_update_pgsize_bitmap(iommu);
-			/*
-			 * Removal of a group without dirty tracking may allow
-			 * the iommu scope to be promoted.
-			 */
-			if (!group->pinned_page_dirty_scope) {
-				iommu->num_non_pinned_groups--;
-				if (iommu->dirty_page_tracking)
-					vfio_iommu_populate_bitmap_full(iommu);
-			}
-		}
+		vfio_iommu_detach_destroy_domain(domain, iommu, group);
 		kfree(group);
 		break;
 	}
 
+	vfio_iommu_aper_expand(iommu, &iova_copy);
 	if (!vfio_iommu_resv_refresh(iommu, &iova_copy))
 		vfio_iommu_iova_insert_copy(iommu, &iova_copy);
 	else
-- 
2.17.1


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

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

* [PATCH 5/5] vfio/iommu_type1: Simplify group attachment
@ 2022-06-06  6:19   ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06  6:19 UTC (permalink / raw)
  To: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: mjrosato, virtualization, thierry.reding, alim.akhtar, alyssa,
	linux-s390, linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	yong.wu, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, suravee.suthikulpanit, dwmw2

Un-inline the domain specific logic from the attach/detach_group ops into
two paired functions vfio_iommu_alloc_attach_domain() and
vfio_iommu_detach_destroy_domain() that strictly deal with creating and
destroying struct vfio_domains.

Add the logic to check for EMEDIUMTYPE return code of iommu_attach_group()
and avoid the extra domain allocations and attach/detach sequences of the
old code. This allows properly detecting an actual attach error, like
-ENOMEM, vs treating all attach errors as an incompatible domain.

Remove the duplicated domain->ops comparison that is taken care of in the
IOMMU core.

Co-developed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 306 +++++++++++++++++---------------
 1 file changed, 161 insertions(+), 145 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index b45b1cc118ef..c6f937e1d71f 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -86,6 +86,7 @@ struct vfio_domain {
 	struct list_head	group_list;
 	bool			fgsp : 1;	/* Fine-grained super pages */
 	bool			enforce_cache_coherency : 1;
+	bool			msi_cookie : 1;
 };
 
 struct vfio_dma {
@@ -2153,12 +2154,161 @@ static void vfio_iommu_iova_insert_copy(struct vfio_iommu *iommu,
 	list_splice_tail(iova_copy, iova);
 }
 
+static struct vfio_domain *
+vfio_iommu_alloc_attach_domain(struct bus_type *bus, struct vfio_iommu *iommu,
+			       struct vfio_iommu_group *group)
+{
+	struct iommu_domain *new_domain;
+	struct vfio_domain *domain;
+	int ret = 0;
+
+	/* Try to match an existing compatible domain */
+	list_for_each_entry (domain, &iommu->domain_list, next) {
+		ret = iommu_attach_group(domain->domain, group->iommu_group);
+		if (ret == -EMEDIUMTYPE)
+			continue;
+		if (ret)
+			return ERR_PTR(ret);
+		list_add(&group->next, &domain->group_list);
+		return domain;
+	}
+
+	new_domain = iommu_domain_alloc(bus);
+	if (!new_domain)
+		return ERR_PTR(-EIO);
+
+	if (iommu->nesting) {
+		ret = iommu_enable_nesting(new_domain);
+		if (ret)
+			goto out_free_iommu_domain;
+	}
+
+	ret = iommu_attach_group(new_domain, group->iommu_group);
+	if (ret)
+		goto out_free_iommu_domain;
+
+	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+	if (!domain) {
+		ret = -ENOMEM;
+		goto out_detach;
+	}
+
+	domain->domain = new_domain;
+	vfio_test_domain_fgsp(domain);
+
+	/*
+	 * If the IOMMU can block non-coherent operations (ie PCIe TLPs with
+	 * no-snoop set) then VFIO always turns this feature on because on Intel
+	 * platforms it optimizes KVM to disable wbinvd emulation.
+	 */
+	if (new_domain->ops->enforce_cache_coherency)
+		domain->enforce_cache_coherency =
+			new_domain->ops->enforce_cache_coherency(new_domain);
+
+	/* replay mappings on new domains */
+	ret = vfio_iommu_replay(iommu, domain);
+	if (ret)
+		goto out_free_domain;
+
+	/*
+	 * An iommu backed group can dirty memory directly and therefore
+	 * demotes the iommu scope until it declares itself dirty tracking
+	 * capable via the page pinning interface.
+	 */
+	iommu->num_non_pinned_groups++;
+
+	INIT_LIST_HEAD(&domain->group_list);
+	list_add(&group->next, &domain->group_list);
+	list_add(&domain->next, &iommu->domain_list);
+	vfio_update_pgsize_bitmap(iommu);
+	return domain;
+
+out_free_domain:
+	kfree(domain);
+out_detach:
+	iommu_detach_group(domain->domain, group->iommu_group);
+out_free_iommu_domain:
+	iommu_domain_free(new_domain);
+	return ERR_PTR(ret);
+}
+
+static void vfio_iommu_unmap_unpin_all(struct vfio_iommu *iommu)
+{
+	struct rb_node *node;
+
+	while ((node = rb_first(&iommu->dma_list)))
+		vfio_remove_dma(iommu, rb_entry(node, struct vfio_dma, node));
+}
+
+static void vfio_iommu_unmap_unpin_reaccount(struct vfio_iommu *iommu)
+{
+	struct rb_node *n, *p;
+
+	n = rb_first(&iommu->dma_list);
+	for (; n; n = rb_next(n)) {
+		struct vfio_dma *dma;
+		long locked = 0, unlocked = 0;
+
+		dma = rb_entry(n, struct vfio_dma, node);
+		unlocked += vfio_unmap_unpin(iommu, dma, false);
+		p = rb_first(&dma->pfn_list);
+		for (; p; p = rb_next(p)) {
+			struct vfio_pfn *vpfn = rb_entry(p, struct vfio_pfn,
+							 node);
+
+			if (!is_invalid_reserved_pfn(vpfn->pfn))
+				locked++;
+		}
+		vfio_lock_acct(dma, locked - unlocked, true);
+	}
+}
+
+static void vfio_iommu_detach_destroy_domain(struct vfio_domain *domain,
+					     struct vfio_iommu *iommu,
+					     struct vfio_iommu_group *group)
+{
+	iommu_detach_group(domain->domain, group->iommu_group);
+	list_del(&group->next);
+	if (!list_empty(&domain->group_list))
+		return;
+
+	/*
+	 * Group ownership provides privilege, if the group list is empty, the
+	 * domain goes away. If it's the last domain with iommu and external
+	 * domain doesn't exist, then all the mappings go away too. If it's the
+	 * last domain with iommu and external domain exist, update accounting
+	 */
+	if (list_is_singular(&iommu->domain_list)) {
+		if (list_empty(&iommu->emulated_iommu_groups)) {
+			WARN_ON(iommu->notifier.head);
+			vfio_iommu_unmap_unpin_all(iommu);
+		} else {
+			vfio_iommu_unmap_unpin_reaccount(iommu);
+		}
+	}
+	iommu_domain_free(domain->domain);
+	list_del(&domain->next);
+	kfree(domain);
+
+	/*
+	 * Removal of a group without dirty tracking may allow the iommu scope
+	 * to be promoted.
+	 */
+	if (!group->pinned_page_dirty_scope) {
+		iommu->num_non_pinned_groups--;
+		if (iommu->dirty_page_tracking)
+			vfio_iommu_populate_bitmap_full(iommu);
+	}
+
+	vfio_update_pgsize_bitmap(iommu);
+}
+
 static int vfio_iommu_type1_attach_group(void *iommu_data,
 		struct iommu_group *iommu_group, enum vfio_group_type type)
 {
 	struct vfio_iommu *iommu = iommu_data;
 	struct vfio_iommu_group *group;
-	struct vfio_domain *domain, *d;
+	struct vfio_domain *domain;
 	struct bus_type *bus = NULL;
 	bool resv_msi, msi_remap;
 	phys_addr_t resv_msi_base = 0;
@@ -2197,26 +2347,12 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 	if (ret)
 		goto out_free_group;
 
-	ret = -ENOMEM;
-	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
-	if (!domain)
+	domain = vfio_iommu_alloc_attach_domain(bus, iommu, group);
+	if (IS_ERR(domain)) {
+		ret = PTR_ERR(domain);
 		goto out_free_group;
-
-	ret = -EIO;
-	domain->domain = iommu_domain_alloc(bus);
-	if (!domain->domain)
-		goto out_free_domain;
-
-	if (iommu->nesting) {
-		ret = iommu_enable_nesting(domain->domain);
-		if (ret)
-			goto out_domain;
 	}
 
-	ret = iommu_attach_group(domain->domain, group->iommu_group);
-	if (ret)
-		goto out_domain;
-
 	/* Get aperture info */
 	geo = &domain->domain->geometry;
 	if (vfio_iommu_aper_conflict(iommu, geo->aperture_start,
@@ -2254,9 +2390,6 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 
 	resv_msi = vfio_iommu_has_sw_msi(&group_resv_regions, &resv_msi_base);
 
-	INIT_LIST_HEAD(&domain->group_list);
-	list_add(&group->next, &domain->group_list);
-
 	msi_remap = irq_domain_check_msi_remap() ||
 		    iommu_capable(bus, IOMMU_CAP_INTR_REMAP);
 
@@ -2267,117 +2400,32 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 		goto out_detach;
 	}
 
-	/*
-	 * If the IOMMU can block non-coherent operations (ie PCIe TLPs with
-	 * no-snoop set) then VFIO always turns this feature on because on Intel
-	 * platforms it optimizes KVM to disable wbinvd emulation.
-	 */
-	if (domain->domain->ops->enforce_cache_coherency)
-		domain->enforce_cache_coherency =
-			domain->domain->ops->enforce_cache_coherency(
-				domain->domain);
-
-	/*
-	 * Try to match an existing compatible domain.  We don't want to
-	 * preclude an IOMMU driver supporting multiple bus_types and being
-	 * able to include different bus_types in the same IOMMU domain, so
-	 * we test whether the domains use the same iommu_ops rather than
-	 * testing if they're on the same bus_type.
-	 */
-	list_for_each_entry(d, &iommu->domain_list, next) {
-		if (d->domain->ops == domain->domain->ops) {
-			iommu_detach_group(domain->domain, group->iommu_group);
-			if (!iommu_attach_group(d->domain,
-						group->iommu_group)) {
-				list_add(&group->next, &d->group_list);
-				iommu_domain_free(domain->domain);
-				kfree(domain);
-				goto done;
-			}
-
-			ret = iommu_attach_group(domain->domain,
-						 group->iommu_group);
-			if (ret)
-				goto out_domain;
-		}
-	}
-
-	vfio_test_domain_fgsp(domain);
-
-	/* replay mappings on new domains */
-	ret = vfio_iommu_replay(iommu, domain);
-	if (ret)
-		goto out_detach;
-
-	if (resv_msi) {
+	if (resv_msi && !domain->msi_cookie) {
 		ret = iommu_get_msi_cookie(domain->domain, resv_msi_base);
 		if (ret && ret != -ENODEV)
 			goto out_detach;
+		domain->msi_cookie = true;
 	}
 
-	list_add(&domain->next, &iommu->domain_list);
-	vfio_update_pgsize_bitmap(iommu);
-done:
 	/* Delete the old one and insert new iova list */
 	vfio_iommu_iova_insert_copy(iommu, &iova_copy);
 
-	/*
-	 * An iommu backed group can dirty memory directly and therefore
-	 * demotes the iommu scope until it declares itself dirty tracking
-	 * capable via the page pinning interface.
-	 */
-	iommu->num_non_pinned_groups++;
 	mutex_unlock(&iommu->lock);
 	vfio_iommu_resv_free(&group_resv_regions);
 
 	return 0;
 
 out_detach:
-	iommu_detach_group(domain->domain, group->iommu_group);
-out_domain:
-	iommu_domain_free(domain->domain);
-	vfio_iommu_iova_free(&iova_copy);
-	vfio_iommu_resv_free(&group_resv_regions);
-out_free_domain:
-	kfree(domain);
+	vfio_iommu_detach_destroy_domain(domain, iommu, group);
 out_free_group:
 	kfree(group);
 out_unlock:
 	mutex_unlock(&iommu->lock);
+	vfio_iommu_iova_free(&iova_copy);
+	vfio_iommu_resv_free(&group_resv_regions);
 	return ret;
 }
 
-static void vfio_iommu_unmap_unpin_all(struct vfio_iommu *iommu)
-{
-	struct rb_node *node;
-
-	while ((node = rb_first(&iommu->dma_list)))
-		vfio_remove_dma(iommu, rb_entry(node, struct vfio_dma, node));
-}
-
-static void vfio_iommu_unmap_unpin_reaccount(struct vfio_iommu *iommu)
-{
-	struct rb_node *n, *p;
-
-	n = rb_first(&iommu->dma_list);
-	for (; n; n = rb_next(n)) {
-		struct vfio_dma *dma;
-		long locked = 0, unlocked = 0;
-
-		dma = rb_entry(n, struct vfio_dma, node);
-		unlocked += vfio_unmap_unpin(iommu, dma, false);
-		p = rb_first(&dma->pfn_list);
-		for (; p; p = rb_next(p)) {
-			struct vfio_pfn *vpfn = rb_entry(p, struct vfio_pfn,
-							 node);
-
-			if (!is_invalid_reserved_pfn(vpfn->pfn))
-				locked++;
-		}
-		vfio_lock_acct(dma, locked - unlocked, true);
-	}
-}
-
 /*
  * Called when a domain is removed in detach. It is possible that
  * the removed domain decided the iova aperture window. Modify the
@@ -2491,44 +2539,12 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
 		group = find_iommu_group(domain, iommu_group);
 		if (!group)
 			continue;
-
-		iommu_detach_group(domain->domain, group->iommu_group);
-		list_del(&group->next);
-		/*
-		 * Group ownership provides privilege, if the group list is
-		 * empty, the domain goes away. If it's the last domain with
-		 * iommu and external domain doesn't exist, then all the
-		 * mappings go away too. If it's the last domain with iommu and
-		 * external domain exist, update accounting
-		 */
-		if (list_empty(&domain->group_list)) {
-			if (list_is_singular(&iommu->domain_list)) {
-				if (list_empty(&iommu->emulated_iommu_groups)) {
-					WARN_ON(iommu->notifier.head);
-					vfio_iommu_unmap_unpin_all(iommu);
-				} else {
-					vfio_iommu_unmap_unpin_reaccount(iommu);
-				}
-			}
-			iommu_domain_free(domain->domain);
-			list_del(&domain->next);
-			kfree(domain);
-			vfio_iommu_aper_expand(iommu, &iova_copy);
-			vfio_update_pgsize_bitmap(iommu);
-			/*
-			 * Removal of a group without dirty tracking may allow
-			 * the iommu scope to be promoted.
-			 */
-			if (!group->pinned_page_dirty_scope) {
-				iommu->num_non_pinned_groups--;
-				if (iommu->dirty_page_tracking)
-					vfio_iommu_populate_bitmap_full(iommu);
-			}
-		}
+		vfio_iommu_detach_destroy_domain(domain, iommu, group);
 		kfree(group);
 		break;
 	}
 
+	vfio_iommu_aper_expand(iommu, &iova_copy);
 	if (!vfio_iommu_resv_refresh(iommu, &iova_copy))
 		vfio_iommu_iova_insert_copy(iommu, &iova_copy);
 	else
-- 
2.17.1


_______________________________________________
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] 138+ messages in thread

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
  2022-06-06  6:19   ` Nicolin Chen via iommu
                       ` (3 preceding siblings ...)
  (?)
@ 2022-06-06 14:33     ` Robin Murphy
  -1 siblings, 0 replies; 138+ messages in thread
From: Robin Murphy @ 2022-06-06 14:33 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On 2022-06-06 07:19, Nicolin Chen wrote:
> The core code should not call an iommu driver op with a struct device
> parameter unless it knows that the dev_iommu_priv_get() for that struct
> device was setup by the same driver. Otherwise in a mixed driver system
> the iommu_priv could be casted to the wrong type.

We don't have mixed-driver systems, and there are plenty more 
significant problems than this one to solve before we can (but thanks 
for pointing it out - I hadn't got as far as auditing the public 
interfaces yet). Once domains are allocated via a particular device's 
IOMMU instance in the first place, there will be ample opportunity for 
the core to stash suitable identifying information in the domain for 
itself. TBH even the current code could do it without needing the 
weirdly invasive changes here.

> Store the iommu_ops pointer in the iommu_domain and use it as a check to
> validate that the struct device is correct before invoking any domain op
> that accepts a struct device.

In fact this even describes exactly that - "Store the iommu_ops pointer 
in the iommu_domain", vs. the "Store the iommu_ops pointer in the 
iommu_domain_ops" which the patch is actually doing :/

[...]
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 19cf28d40ebe..8a1f437a51f2 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -1963,6 +1963,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
>   {
>   	int ret;
>   
> +	/* Ensure the device was probe'd onto the same driver as the domain */
> +	if (dev->bus->iommu_ops != domain->ops->iommu_ops)

Nope, dev_iommu_ops(dev) please. Furthermore I think the logical place 
to put this is in iommu_group_do_attach_device(), since that's the 
gateway for the public interfaces - we shouldn't need to second-guess 
ourselves for internal default-domain-related calls.

Thanks,
Robin.

> +		return -EMEDIUMTYPE;
> +
>   	if (unlikely(domain->ops->attach_dev == NULL))
>   		return -ENODEV;

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 14:33     ` Robin Murphy
  0 siblings, 0 replies; 138+ messages in thread
From: Robin Murphy @ 2022-06-06 14:33 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On 2022-06-06 07:19, Nicolin Chen wrote:
> The core code should not call an iommu driver op with a struct device
> parameter unless it knows that the dev_iommu_priv_get() for that struct
> device was setup by the same driver. Otherwise in a mixed driver system
> the iommu_priv could be casted to the wrong type.

We don't have mixed-driver systems, and there are plenty more 
significant problems than this one to solve before we can (but thanks 
for pointing it out - I hadn't got as far as auditing the public 
interfaces yet). Once domains are allocated via a particular device's 
IOMMU instance in the first place, there will be ample opportunity for 
the core to stash suitable identifying information in the domain for 
itself. TBH even the current code could do it without needing the 
weirdly invasive changes here.

> Store the iommu_ops pointer in the iommu_domain and use it as a check to
> validate that the struct device is correct before invoking any domain op
> that accepts a struct device.

In fact this even describes exactly that - "Store the iommu_ops pointer 
in the iommu_domain", vs. the "Store the iommu_ops pointer in the 
iommu_domain_ops" which the patch is actually doing :/

[...]
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 19cf28d40ebe..8a1f437a51f2 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -1963,6 +1963,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
>   {
>   	int ret;
>   
> +	/* Ensure the device was probe'd onto the same driver as the domain */
> +	if (dev->bus->iommu_ops != domain->ops->iommu_ops)

Nope, dev_iommu_ops(dev) please. Furthermore I think the logical place 
to put this is in iommu_group_do_attach_device(), since that's the 
gateway for the public interfaces - we shouldn't need to second-guess 
ourselves for internal default-domain-related calls.

Thanks,
Robin.

> +		return -EMEDIUMTYPE;
> +
>   	if (unlikely(domain->ops->attach_dev == NULL))
>   		return -ENODEV;

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

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 14:33     ` Robin Murphy
  0 siblings, 0 replies; 138+ messages in thread
From: Robin Murphy @ 2022-06-06 14:33 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

On 2022-06-06 07:19, Nicolin Chen wrote:
> The core code should not call an iommu driver op with a struct device
> parameter unless it knows that the dev_iommu_priv_get() for that struct
> device was setup by the same driver. Otherwise in a mixed driver system
> the iommu_priv could be casted to the wrong type.

We don't have mixed-driver systems, and there are plenty more 
significant problems than this one to solve before we can (but thanks 
for pointing it out - I hadn't got as far as auditing the public 
interfaces yet). Once domains are allocated via a particular device's 
IOMMU instance in the first place, there will be ample opportunity for 
the core to stash suitable identifying information in the domain for 
itself. TBH even the current code could do it without needing the 
weirdly invasive changes here.

> Store the iommu_ops pointer in the iommu_domain and use it as a check to
> validate that the struct device is correct before invoking any domain op
> that accepts a struct device.

In fact this even describes exactly that - "Store the iommu_ops pointer 
in the iommu_domain", vs. the "Store the iommu_ops pointer in the 
iommu_domain_ops" which the patch is actually doing :/

[...]
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 19cf28d40ebe..8a1f437a51f2 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -1963,6 +1963,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
>   {
>   	int ret;
>   
> +	/* Ensure the device was probe'd onto the same driver as the domain */
> +	if (dev->bus->iommu_ops != domain->ops->iommu_ops)

Nope, dev_iommu_ops(dev) please. Furthermore I think the logical place 
to put this is in iommu_group_do_attach_device(), since that's the 
gateway for the public interfaces - we shouldn't need to second-guess 
ourselves for internal default-domain-related calls.

Thanks,
Robin.

> +		return -EMEDIUMTYPE;
> +
>   	if (unlikely(domain->ops->attach_dev == NULL))
>   		return -ENODEV;
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 14:33     ` Robin Murphy
  0 siblings, 0 replies; 138+ messages in thread
From: Robin Murphy @ 2022-06-06 14:33 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On 2022-06-06 07:19, Nicolin Chen wrote:
> The core code should not call an iommu driver op with a struct device
> parameter unless it knows that the dev_iommu_priv_get() for that struct
> device was setup by the same driver. Otherwise in a mixed driver system
> the iommu_priv could be casted to the wrong type.

We don't have mixed-driver systems, and there are plenty more 
significant problems than this one to solve before we can (but thanks 
for pointing it out - I hadn't got as far as auditing the public 
interfaces yet). Once domains are allocated via a particular device's 
IOMMU instance in the first place, there will be ample opportunity for 
the core to stash suitable identifying information in the domain for 
itself. TBH even the current code could do it without needing the 
weirdly invasive changes here.

> Store the iommu_ops pointer in the iommu_domain and use it as a check to
> validate that the struct device is correct before invoking any domain op
> that accepts a struct device.

In fact this even describes exactly that - "Store the iommu_ops pointer 
in the iommu_domain", vs. the "Store the iommu_ops pointer in the 
iommu_domain_ops" which the patch is actually doing :/

[...]
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 19cf28d40ebe..8a1f437a51f2 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -1963,6 +1963,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
>   {
>   	int ret;
>   
> +	/* Ensure the device was probe'd onto the same driver as the domain */
> +	if (dev->bus->iommu_ops != domain->ops->iommu_ops)

Nope, dev_iommu_ops(dev) please. Furthermore I think the logical place 
to put this is in iommu_group_do_attach_device(), since that's the 
gateway for the public interfaces - we shouldn't need to second-guess 
ourselves for internal default-domain-related calls.

Thanks,
Robin.

> +		return -EMEDIUMTYPE;
> +
>   	if (unlikely(domain->ops->attach_dev == NULL))
>   		return -ENODEV;

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

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 14:33     ` Robin Murphy
  0 siblings, 0 replies; 138+ messages in thread
From: Robin Murphy @ 2022-06-06 14:33 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: mjrosato, virtualization, thierry.reding, alim.akhtar, alyssa,
	linux-s390, linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	yong.wu, gerald.schaefer, linux-sunxi, linux-arm-msm, vdumpa,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, suravee.suthikulpanit, dwmw2

On 2022-06-06 07:19, Nicolin Chen wrote:
> The core code should not call an iommu driver op with a struct device
> parameter unless it knows that the dev_iommu_priv_get() for that struct
> device was setup by the same driver. Otherwise in a mixed driver system
> the iommu_priv could be casted to the wrong type.

We don't have mixed-driver systems, and there are plenty more 
significant problems than this one to solve before we can (but thanks 
for pointing it out - I hadn't got as far as auditing the public 
interfaces yet). Once domains are allocated via a particular device's 
IOMMU instance in the first place, there will be ample opportunity for 
the core to stash suitable identifying information in the domain for 
itself. TBH even the current code could do it without needing the 
weirdly invasive changes here.

> Store the iommu_ops pointer in the iommu_domain and use it as a check to
> validate that the struct device is correct before invoking any domain op
> that accepts a struct device.

In fact this even describes exactly that - "Store the iommu_ops pointer 
in the iommu_domain", vs. the "Store the iommu_ops pointer in the 
iommu_domain_ops" which the patch is actually doing :/

[...]
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 19cf28d40ebe..8a1f437a51f2 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -1963,6 +1963,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
>   {
>   	int ret;
>   
> +	/* Ensure the device was probe'd onto the same driver as the domain */
> +	if (dev->bus->iommu_ops != domain->ops->iommu_ops)

Nope, dev_iommu_ops(dev) please. Furthermore I think the logical place 
to put this is in iommu_group_do_attach_device(), since that's the 
gateway for the public interfaces - we shouldn't need to second-guess 
ourselves for internal default-domain-related calls.

Thanks,
Robin.

> +		return -EMEDIUMTYPE;
> +
>   	if (unlikely(domain->ops->attach_dev == NULL))
>   		return -ENODEV;
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 14:33     ` Robin Murphy
  0 siblings, 0 replies; 138+ messages in thread
From: Robin Murphy @ 2022-06-06 14:33 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: mjrosato, virtualization, thierry.reding, alim.akhtar, alyssa,
	linux-s390, linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	yong.wu, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, suravee.suthikulpanit, dwmw2

On 2022-06-06 07:19, Nicolin Chen wrote:
> The core code should not call an iommu driver op with a struct device
> parameter unless it knows that the dev_iommu_priv_get() for that struct
> device was setup by the same driver. Otherwise in a mixed driver system
> the iommu_priv could be casted to the wrong type.

We don't have mixed-driver systems, and there are plenty more 
significant problems than this one to solve before we can (but thanks 
for pointing it out - I hadn't got as far as auditing the public 
interfaces yet). Once domains are allocated via a particular device's 
IOMMU instance in the first place, there will be ample opportunity for 
the core to stash suitable identifying information in the domain for 
itself. TBH even the current code could do it without needing the 
weirdly invasive changes here.

> Store the iommu_ops pointer in the iommu_domain and use it as a check to
> validate that the struct device is correct before invoking any domain op
> that accepts a struct device.

In fact this even describes exactly that - "Store the iommu_ops pointer 
in the iommu_domain", vs. the "Store the iommu_ops pointer in the 
iommu_domain_ops" which the patch is actually doing :/

[...]
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 19cf28d40ebe..8a1f437a51f2 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -1963,6 +1963,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
>   {
>   	int ret;
>   
> +	/* Ensure the device was probe'd onto the same driver as the domain */
> +	if (dev->bus->iommu_ops != domain->ops->iommu_ops)

Nope, dev_iommu_ops(dev) please. Furthermore I think the logical place 
to put this is in iommu_group_do_attach_device(), since that's the 
gateway for the public interfaces - we shouldn't need to second-guess 
ourselves for internal default-domain-related calls.

Thanks,
Robin.

> +		return -EMEDIUMTYPE;
> +
>   	if (unlikely(domain->ops->attach_dev == NULL))
>   		return -ENODEV;

_______________________________________________
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] 138+ messages in thread

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
  2022-06-06 14:33     ` Robin Murphy
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-06 16:51       ` Nicolin Chen via iommu
  -1 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06 16:51 UTC (permalink / raw)
  To: Robin Murphy
  Cc: jgg, joro, will, marcan, sven, robdclark, m.szyprowski,
	krzysztof.kozlowski, baolu.lu, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

Hi Robin,

On Mon, Jun 06, 2022 at 03:33:42PM +0100, Robin Murphy wrote:
> On 2022-06-06 07:19, Nicolin Chen wrote:
> > The core code should not call an iommu driver op with a struct device
> > parameter unless it knows that the dev_iommu_priv_get() for that struct
> > device was setup by the same driver. Otherwise in a mixed driver system
> > the iommu_priv could be casted to the wrong type.
> 
> We don't have mixed-driver systems, and there are plenty more
> significant problems than this one to solve before we can (but thanks
> for pointing it out - I hadn't got as far as auditing the public
> interfaces yet). Once domains are allocated via a particular device's
> IOMMU instance in the first place, there will be ample opportunity for
> the core to stash suitable identifying information in the domain for
> itself. TBH even the current code could do it without needing the
> weirdly invasive changes here.

Do you have an alternative and less invasive solution in mind?

> > Store the iommu_ops pointer in the iommu_domain and use it as a check to
> > validate that the struct device is correct before invoking any domain op
> > that accepts a struct device.
> 
> In fact this even describes exactly that - "Store the iommu_ops pointer
> in the iommu_domain", vs. the "Store the iommu_ops pointer in the
> iommu_domain_ops" which the patch is actually doing :/

Will fix that.

> [...]
> > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > index 19cf28d40ebe..8a1f437a51f2 100644
> > --- a/drivers/iommu/iommu.c
> > +++ b/drivers/iommu/iommu.c
> > @@ -1963,6 +1963,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
> >   {
> >       int ret;
> > 
> > +     /* Ensure the device was probe'd onto the same driver as the domain */
> > +     if (dev->bus->iommu_ops != domain->ops->iommu_ops)
> 
> Nope, dev_iommu_ops(dev) please. Furthermore I think the logical place
> to put this is in iommu_group_do_attach_device(), since that's the
> gateway for the public interfaces - we shouldn't need to second-guess
> ourselves for internal default-domain-related calls.

Will move to iommu_group_do_attach_device and change to dev_iommu_ops.

Thanks!
Nic

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 16:51       ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen via iommu @ 2022-06-06 16:51 UTC (permalink / raw)
  To: Robin Murphy
  Cc: cohuck, heiko, linux-tegra, thierry.reding, alim.akhtar, will,
	alyssa, jean-philippe, linux-samsung-soc, kvm, samuel,
	zhang.lyra, jernej.skrabec, jonathanh, linux-rockchip, wens,
	agross, linux-arm-kernel, jgg, orsonzhai, gerald.schaefer,
	linux-sunxi, linux-arm-msm, alex.williamson, iommu,
	linux-mediatek, matthias.bgg, virtualization, linux-s390, marcan,
	linux-kernel, krzysztof.kozlowski, baolin.wang7, dwmw2

Hi Robin,

On Mon, Jun 06, 2022 at 03:33:42PM +0100, Robin Murphy wrote:
> On 2022-06-06 07:19, Nicolin Chen wrote:
> > The core code should not call an iommu driver op with a struct device
> > parameter unless it knows that the dev_iommu_priv_get() for that struct
> > device was setup by the same driver. Otherwise in a mixed driver system
> > the iommu_priv could be casted to the wrong type.
> 
> We don't have mixed-driver systems, and there are plenty more
> significant problems than this one to solve before we can (but thanks
> for pointing it out - I hadn't got as far as auditing the public
> interfaces yet). Once domains are allocated via a particular device's
> IOMMU instance in the first place, there will be ample opportunity for
> the core to stash suitable identifying information in the domain for
> itself. TBH even the current code could do it without needing the
> weirdly invasive changes here.

Do you have an alternative and less invasive solution in mind?

> > Store the iommu_ops pointer in the iommu_domain and use it as a check to
> > validate that the struct device is correct before invoking any domain op
> > that accepts a struct device.
> 
> In fact this even describes exactly that - "Store the iommu_ops pointer
> in the iommu_domain", vs. the "Store the iommu_ops pointer in the
> iommu_domain_ops" which the patch is actually doing :/

Will fix that.

> [...]
> > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > index 19cf28d40ebe..8a1f437a51f2 100644
> > --- a/drivers/iommu/iommu.c
> > +++ b/drivers/iommu/iommu.c
> > @@ -1963,6 +1963,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
> >   {
> >       int ret;
> > 
> > +     /* Ensure the device was probe'd onto the same driver as the domain */
> > +     if (dev->bus->iommu_ops != domain->ops->iommu_ops)
> 
> Nope, dev_iommu_ops(dev) please. Furthermore I think the logical place
> to put this is in iommu_group_do_attach_device(), since that's the
> gateway for the public interfaces - we shouldn't need to second-guess
> ourselves for internal default-domain-related calls.

Will move to iommu_group_do_attach_device and change to dev_iommu_ops.

Thanks!
Nic
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 16:51       ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06 16:51 UTC (permalink / raw)
  To: Robin Murphy
  Cc: jgg, joro, will, marcan, sven, robdclark, m.szyprowski,
	krzysztof.kozlowski, baolu.lu, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

Hi Robin,

On Mon, Jun 06, 2022 at 03:33:42PM +0100, Robin Murphy wrote:
> On 2022-06-06 07:19, Nicolin Chen wrote:
> > The core code should not call an iommu driver op with a struct device
> > parameter unless it knows that the dev_iommu_priv_get() for that struct
> > device was setup by the same driver. Otherwise in a mixed driver system
> > the iommu_priv could be casted to the wrong type.
> 
> We don't have mixed-driver systems, and there are plenty more
> significant problems than this one to solve before we can (but thanks
> for pointing it out - I hadn't got as far as auditing the public
> interfaces yet). Once domains are allocated via a particular device's
> IOMMU instance in the first place, there will be ample opportunity for
> the core to stash suitable identifying information in the domain for
> itself. TBH even the current code could do it without needing the
> weirdly invasive changes here.

Do you have an alternative and less invasive solution in mind?

> > Store the iommu_ops pointer in the iommu_domain and use it as a check to
> > validate that the struct device is correct before invoking any domain op
> > that accepts a struct device.
> 
> In fact this even describes exactly that - "Store the iommu_ops pointer
> in the iommu_domain", vs. the "Store the iommu_ops pointer in the
> iommu_domain_ops" which the patch is actually doing :/

Will fix that.

> [...]
> > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > index 19cf28d40ebe..8a1f437a51f2 100644
> > --- a/drivers/iommu/iommu.c
> > +++ b/drivers/iommu/iommu.c
> > @@ -1963,6 +1963,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
> >   {
> >       int ret;
> > 
> > +     /* Ensure the device was probe'd onto the same driver as the domain */
> > +     if (dev->bus->iommu_ops != domain->ops->iommu_ops)
> 
> Nope, dev_iommu_ops(dev) please. Furthermore I think the logical place
> to put this is in iommu_group_do_attach_device(), since that's the
> gateway for the public interfaces - we shouldn't need to second-guess
> ourselves for internal default-domain-related calls.

Will move to iommu_group_do_attach_device and change to dev_iommu_ops.

Thanks!
Nic

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

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 16:51       ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06 16:51 UTC (permalink / raw)
  To: Robin Murphy
  Cc: jgg, joro, will, marcan, sven, robdclark, m.szyprowski,
	krzysztof.kozlowski, baolu.lu, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

Hi Robin,

On Mon, Jun 06, 2022 at 03:33:42PM +0100, Robin Murphy wrote:
> On 2022-06-06 07:19, Nicolin Chen wrote:
> > The core code should not call an iommu driver op with a struct device
> > parameter unless it knows that the dev_iommu_priv_get() for that struct
> > device was setup by the same driver. Otherwise in a mixed driver system
> > the iommu_priv could be casted to the wrong type.
> 
> We don't have mixed-driver systems, and there are plenty more
> significant problems than this one to solve before we can (but thanks
> for pointing it out - I hadn't got as far as auditing the public
> interfaces yet). Once domains are allocated via a particular device's
> IOMMU instance in the first place, there will be ample opportunity for
> the core to stash suitable identifying information in the domain for
> itself. TBH even the current code could do it without needing the
> weirdly invasive changes here.

Do you have an alternative and less invasive solution in mind?

> > Store the iommu_ops pointer in the iommu_domain and use it as a check to
> > validate that the struct device is correct before invoking any domain op
> > that accepts a struct device.
> 
> In fact this even describes exactly that - "Store the iommu_ops pointer
> in the iommu_domain", vs. the "Store the iommu_ops pointer in the
> iommu_domain_ops" which the patch is actually doing :/

Will fix that.

> [...]
> > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > index 19cf28d40ebe..8a1f437a51f2 100644
> > --- a/drivers/iommu/iommu.c
> > +++ b/drivers/iommu/iommu.c
> > @@ -1963,6 +1963,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
> >   {
> >       int ret;
> > 
> > +     /* Ensure the device was probe'd onto the same driver as the domain */
> > +     if (dev->bus->iommu_ops != domain->ops->iommu_ops)
> 
> Nope, dev_iommu_ops(dev) please. Furthermore I think the logical place
> to put this is in iommu_group_do_attach_device(), since that's the
> gateway for the public interfaces - we shouldn't need to second-guess
> ourselves for internal default-domain-related calls.

Will move to iommu_group_do_attach_device and change to dev_iommu_ops.

Thanks!
Nic

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

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 16:51       ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06 16:51 UTC (permalink / raw)
  To: Robin Murphy
  Cc: cohuck, heiko, mjrosato, bjorn.andersson, linux-tegra,
	thierry.reding, alim.akhtar, will, alyssa, m.szyprowski,
	jean-philippe, linux-samsung-soc, kvm, samuel, zhang.lyra, joro,
	robdclark, jernej.skrabec, jonathanh, linux-rockchip, wens,
	agross, linux-arm-kernel, jgg, orsonzhai, gerald.schaefer,
	linux-sunxi, sven, linux-arm-msm, alex.williamson, iommu,
	linux-mediatek, matthias.bgg, virtualization, yong.wu,
	linux-s390, marcan, linux-kernel, krzysztof.kozlowski,
	suravee.suthikulpanit, baolin.wang7, dwmw2, baolu.lu

Hi Robin,

On Mon, Jun 06, 2022 at 03:33:42PM +0100, Robin Murphy wrote:
> On 2022-06-06 07:19, Nicolin Chen wrote:
> > The core code should not call an iommu driver op with a struct device
> > parameter unless it knows that the dev_iommu_priv_get() for that struct
> > device was setup by the same driver. Otherwise in a mixed driver system
> > the iommu_priv could be casted to the wrong type.
> 
> We don't have mixed-driver systems, and there are plenty more
> significant problems than this one to solve before we can (but thanks
> for pointing it out - I hadn't got as far as auditing the public
> interfaces yet). Once domains are allocated via a particular device's
> IOMMU instance in the first place, there will be ample opportunity for
> the core to stash suitable identifying information in the domain for
> itself. TBH even the current code could do it without needing the
> weirdly invasive changes here.

Do you have an alternative and less invasive solution in mind?

> > Store the iommu_ops pointer in the iommu_domain and use it as a check to
> > validate that the struct device is correct before invoking any domain op
> > that accepts a struct device.
> 
> In fact this even describes exactly that - "Store the iommu_ops pointer
> in the iommu_domain", vs. the "Store the iommu_ops pointer in the
> iommu_domain_ops" which the patch is actually doing :/

Will fix that.

> [...]
> > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > index 19cf28d40ebe..8a1f437a51f2 100644
> > --- a/drivers/iommu/iommu.c
> > +++ b/drivers/iommu/iommu.c
> > @@ -1963,6 +1963,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
> >   {
> >       int ret;
> > 
> > +     /* Ensure the device was probe'd onto the same driver as the domain */
> > +     if (dev->bus->iommu_ops != domain->ops->iommu_ops)
> 
> Nope, dev_iommu_ops(dev) please. Furthermore I think the logical place
> to put this is in iommu_group_do_attach_device(), since that's the
> gateway for the public interfaces - we shouldn't need to second-guess
> ourselves for internal default-domain-related calls.

Will move to iommu_group_do_attach_device and change to dev_iommu_ops.

Thanks!
Nic

_______________________________________________
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] 138+ messages in thread

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
  2022-06-06 16:51       ` Nicolin Chen via iommu
                           ` (3 preceding siblings ...)
  (?)
@ 2022-06-06 17:50         ` Robin Murphy
  -1 siblings, 0 replies; 138+ messages in thread
From: Robin Murphy @ 2022-06-06 17:50 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: jgg, joro, will, marcan, sven, robdclark, m.szyprowski,
	krzysztof.kozlowski, baolu.lu, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On 2022-06-06 17:51, Nicolin Chen wrote:
> Hi Robin,
> 
> On Mon, Jun 06, 2022 at 03:33:42PM +0100, Robin Murphy wrote:
>> On 2022-06-06 07:19, Nicolin Chen wrote:
>>> The core code should not call an iommu driver op with a struct device
>>> parameter unless it knows that the dev_iommu_priv_get() for that struct
>>> device was setup by the same driver. Otherwise in a mixed driver system
>>> the iommu_priv could be casted to the wrong type.
>>
>> We don't have mixed-driver systems, and there are plenty more
>> significant problems than this one to solve before we can (but thanks
>> for pointing it out - I hadn't got as far as auditing the public
>> interfaces yet). Once domains are allocated via a particular device's
>> IOMMU instance in the first place, there will be ample opportunity for
>> the core to stash suitable identifying information in the domain for
>> itself. TBH even the current code could do it without needing the
>> weirdly invasive changes here.
> 
> Do you have an alternative and less invasive solution in mind?
> 
>>> Store the iommu_ops pointer in the iommu_domain and use it as a check to
>>> validate that the struct device is correct before invoking any domain op
>>> that accepts a struct device.
>>
>> In fact this even describes exactly that - "Store the iommu_ops pointer
>> in the iommu_domain", vs. the "Store the iommu_ops pointer in the
>> iommu_domain_ops" which the patch is actually doing :/
> 
> Will fix that.

Well, as before I'd prefer to make the code match the commit message - 
if I really need to spell it out, see below - since I can't imagine that 
we should ever have need to identify a set of iommu_domain_ops in 
isolation, therefore I think it's considerably clearer to use the 
iommu_domain itself. However, either way we really don't need this yet, 
so we may as well just go ahead and remove the redundant test from VFIO 
anyway, and I can add some form of this patch to my dev branch for now.

Thanks,
Robin.

----->8-----
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index cde2e1d6ab9b..72990edc9314 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1902,6 +1902,7 @@ static struct iommu_domain 
*__iommu_domain_alloc(struct device *dev,
  	domain->type = type;
  	/* Assume all sizes by default; the driver may override this later */
  	domain->pgsize_bitmap = ops->pgsize_bitmap;
+	domain->owner = ops;
  	if (!domain->ops)
  		domain->ops = ops->default_domain_ops;

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 6f64cbbc6721..79e557207f53 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -89,6 +89,7 @@ struct iommu_domain_geometry {

  struct iommu_domain {
  	unsigned type;
+	const struct iommu_ops *owner; /* Who allocated this domain */
  	const struct iommu_domain_ops *ops;
  	unsigned long pgsize_bitmap;	/* Bitmap of page sizes in use */
  	iommu_fault_handler_t handler;

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 17:50         ` Robin Murphy
  0 siblings, 0 replies; 138+ messages in thread
From: Robin Murphy @ 2022-06-06 17:50 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: jgg, joro, will, marcan, sven, robdclark, m.szyprowski,
	krzysztof.kozlowski, baolu.lu, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On 2022-06-06 17:51, Nicolin Chen wrote:
> Hi Robin,
> 
> On Mon, Jun 06, 2022 at 03:33:42PM +0100, Robin Murphy wrote:
>> On 2022-06-06 07:19, Nicolin Chen wrote:
>>> The core code should not call an iommu driver op with a struct device
>>> parameter unless it knows that the dev_iommu_priv_get() for that struct
>>> device was setup by the same driver. Otherwise in a mixed driver system
>>> the iommu_priv could be casted to the wrong type.
>>
>> We don't have mixed-driver systems, and there are plenty more
>> significant problems than this one to solve before we can (but thanks
>> for pointing it out - I hadn't got as far as auditing the public
>> interfaces yet). Once domains are allocated via a particular device's
>> IOMMU instance in the first place, there will be ample opportunity for
>> the core to stash suitable identifying information in the domain for
>> itself. TBH even the current code could do it without needing the
>> weirdly invasive changes here.
> 
> Do you have an alternative and less invasive solution in mind?
> 
>>> Store the iommu_ops pointer in the iommu_domain and use it as a check to
>>> validate that the struct device is correct before invoking any domain op
>>> that accepts a struct device.
>>
>> In fact this even describes exactly that - "Store the iommu_ops pointer
>> in the iommu_domain", vs. the "Store the iommu_ops pointer in the
>> iommu_domain_ops" which the patch is actually doing :/
> 
> Will fix that.

Well, as before I'd prefer to make the code match the commit message - 
if I really need to spell it out, see below - since I can't imagine that 
we should ever have need to identify a set of iommu_domain_ops in 
isolation, therefore I think it's considerably clearer to use the 
iommu_domain itself. However, either way we really don't need this yet, 
so we may as well just go ahead and remove the redundant test from VFIO 
anyway, and I can add some form of this patch to my dev branch for now.

Thanks,
Robin.

----->8-----
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index cde2e1d6ab9b..72990edc9314 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1902,6 +1902,7 @@ static struct iommu_domain 
*__iommu_domain_alloc(struct device *dev,
  	domain->type = type;
  	/* Assume all sizes by default; the driver may override this later */
  	domain->pgsize_bitmap = ops->pgsize_bitmap;
+	domain->owner = ops;
  	if (!domain->ops)
  		domain->ops = ops->default_domain_ops;

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 6f64cbbc6721..79e557207f53 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -89,6 +89,7 @@ struct iommu_domain_geometry {

  struct iommu_domain {
  	unsigned type;
+	const struct iommu_ops *owner; /* Who allocated this domain */
  	const struct iommu_domain_ops *ops;
  	unsigned long pgsize_bitmap;	/* Bitmap of page sizes in use */
  	iommu_fault_handler_t handler;

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

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 17:50         ` Robin Murphy
  0 siblings, 0 replies; 138+ messages in thread
From: Robin Murphy @ 2022-06-06 17:50 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: cohuck, heiko, linux-tegra, thierry.reding, alim.akhtar, will,
	alyssa, jean-philippe, linux-samsung-soc, kvm, samuel,
	zhang.lyra, jernej.skrabec, jonathanh, linux-rockchip, wens,
	agross, linux-arm-kernel, jgg, orsonzhai, gerald.schaefer,
	linux-sunxi, linux-arm-msm, alex.williamson, iommu,
	linux-mediatek, matthias.bgg, virtualization, linux-s390, marcan,
	linux-kernel, krzysztof.kozlowski, baolin.wang7, dwmw2

On 2022-06-06 17:51, Nicolin Chen wrote:
> Hi Robin,
> 
> On Mon, Jun 06, 2022 at 03:33:42PM +0100, Robin Murphy wrote:
>> On 2022-06-06 07:19, Nicolin Chen wrote:
>>> The core code should not call an iommu driver op with a struct device
>>> parameter unless it knows that the dev_iommu_priv_get() for that struct
>>> device was setup by the same driver. Otherwise in a mixed driver system
>>> the iommu_priv could be casted to the wrong type.
>>
>> We don't have mixed-driver systems, and there are plenty more
>> significant problems than this one to solve before we can (but thanks
>> for pointing it out - I hadn't got as far as auditing the public
>> interfaces yet). Once domains are allocated via a particular device's
>> IOMMU instance in the first place, there will be ample opportunity for
>> the core to stash suitable identifying information in the domain for
>> itself. TBH even the current code could do it without needing the
>> weirdly invasive changes here.
> 
> Do you have an alternative and less invasive solution in mind?
> 
>>> Store the iommu_ops pointer in the iommu_domain and use it as a check to
>>> validate that the struct device is correct before invoking any domain op
>>> that accepts a struct device.
>>
>> In fact this even describes exactly that - "Store the iommu_ops pointer
>> in the iommu_domain", vs. the "Store the iommu_ops pointer in the
>> iommu_domain_ops" which the patch is actually doing :/
> 
> Will fix that.

Well, as before I'd prefer to make the code match the commit message - 
if I really need to spell it out, see below - since I can't imagine that 
we should ever have need to identify a set of iommu_domain_ops in 
isolation, therefore I think it's considerably clearer to use the 
iommu_domain itself. However, either way we really don't need this yet, 
so we may as well just go ahead and remove the redundant test from VFIO 
anyway, and I can add some form of this patch to my dev branch for now.

Thanks,
Robin.

----->8-----
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index cde2e1d6ab9b..72990edc9314 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1902,6 +1902,7 @@ static struct iommu_domain 
*__iommu_domain_alloc(struct device *dev,
  	domain->type = type;
  	/* Assume all sizes by default; the driver may override this later */
  	domain->pgsize_bitmap = ops->pgsize_bitmap;
+	domain->owner = ops;
  	if (!domain->ops)
  		domain->ops = ops->default_domain_ops;

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 6f64cbbc6721..79e557207f53 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -89,6 +89,7 @@ struct iommu_domain_geometry {

  struct iommu_domain {
  	unsigned type;
+	const struct iommu_ops *owner; /* Who allocated this domain */
  	const struct iommu_domain_ops *ops;
  	unsigned long pgsize_bitmap;	/* Bitmap of page sizes in use */
  	iommu_fault_handler_t handler;
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 17:50         ` Robin Murphy
  0 siblings, 0 replies; 138+ messages in thread
From: Robin Murphy @ 2022-06-06 17:50 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: jgg, joro, will, marcan, sven, robdclark, m.szyprowski,
	krzysztof.kozlowski, baolu.lu, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On 2022-06-06 17:51, Nicolin Chen wrote:
> Hi Robin,
> 
> On Mon, Jun 06, 2022 at 03:33:42PM +0100, Robin Murphy wrote:
>> On 2022-06-06 07:19, Nicolin Chen wrote:
>>> The core code should not call an iommu driver op with a struct device
>>> parameter unless it knows that the dev_iommu_priv_get() for that struct
>>> device was setup by the same driver. Otherwise in a mixed driver system
>>> the iommu_priv could be casted to the wrong type.
>>
>> We don't have mixed-driver systems, and there are plenty more
>> significant problems than this one to solve before we can (but thanks
>> for pointing it out - I hadn't got as far as auditing the public
>> interfaces yet). Once domains are allocated via a particular device's
>> IOMMU instance in the first place, there will be ample opportunity for
>> the core to stash suitable identifying information in the domain for
>> itself. TBH even the current code could do it without needing the
>> weirdly invasive changes here.
> 
> Do you have an alternative and less invasive solution in mind?
> 
>>> Store the iommu_ops pointer in the iommu_domain and use it as a check to
>>> validate that the struct device is correct before invoking any domain op
>>> that accepts a struct device.
>>
>> In fact this even describes exactly that - "Store the iommu_ops pointer
>> in the iommu_domain", vs. the "Store the iommu_ops pointer in the
>> iommu_domain_ops" which the patch is actually doing :/
> 
> Will fix that.

Well, as before I'd prefer to make the code match the commit message - 
if I really need to spell it out, see below - since I can't imagine that 
we should ever have need to identify a set of iommu_domain_ops in 
isolation, therefore I think it's considerably clearer to use the 
iommu_domain itself. However, either way we really don't need this yet, 
so we may as well just go ahead and remove the redundant test from VFIO 
anyway, and I can add some form of this patch to my dev branch for now.

Thanks,
Robin.

----->8-----
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index cde2e1d6ab9b..72990edc9314 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1902,6 +1902,7 @@ static struct iommu_domain 
*__iommu_domain_alloc(struct device *dev,
  	domain->type = type;
  	/* Assume all sizes by default; the driver may override this later */
  	domain->pgsize_bitmap = ops->pgsize_bitmap;
+	domain->owner = ops;
  	if (!domain->ops)
  		domain->ops = ops->default_domain_ops;

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 6f64cbbc6721..79e557207f53 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -89,6 +89,7 @@ struct iommu_domain_geometry {

  struct iommu_domain {
  	unsigned type;
+	const struct iommu_ops *owner; /* Who allocated this domain */
  	const struct iommu_domain_ops *ops;
  	unsigned long pgsize_bitmap;	/* Bitmap of page sizes in use */
  	iommu_fault_handler_t handler;

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

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 17:50         ` Robin Murphy
  0 siblings, 0 replies; 138+ messages in thread
From: Robin Murphy @ 2022-06-06 17:50 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: cohuck, heiko, mjrosato, bjorn.andersson, linux-tegra,
	thierry.reding, alim.akhtar, will, alyssa, m.szyprowski,
	jean-philippe, linux-samsung-soc, kvm, samuel, zhang.lyra, joro,
	robdclark, jernej.skrabec, jonathanh, linux-rockchip, wens,
	agross, linux-arm-kernel, jgg, orsonzhai, gerald.schaefer,
	linux-sunxi, sven, linux-arm-msm, iommu, linux-mediatek,
	matthias.bgg, virtualization, yong.wu, linux-s390, marcan,
	vdumpa, linux-kernel, krzysztof.kozlowski, suravee.suthikulpanit,
	baolin.wang7, dwmw2, baolu.lu

On 2022-06-06 17:51, Nicolin Chen wrote:
> Hi Robin,
> 
> On Mon, Jun 06, 2022 at 03:33:42PM +0100, Robin Murphy wrote:
>> On 2022-06-06 07:19, Nicolin Chen wrote:
>>> The core code should not call an iommu driver op with a struct device
>>> parameter unless it knows that the dev_iommu_priv_get() for that struct
>>> device was setup by the same driver. Otherwise in a mixed driver system
>>> the iommu_priv could be casted to the wrong type.
>>
>> We don't have mixed-driver systems, and there are plenty more
>> significant problems than this one to solve before we can (but thanks
>> for pointing it out - I hadn't got as far as auditing the public
>> interfaces yet). Once domains are allocated via a particular device's
>> IOMMU instance in the first place, there will be ample opportunity for
>> the core to stash suitable identifying information in the domain for
>> itself. TBH even the current code could do it without needing the
>> weirdly invasive changes here.
> 
> Do you have an alternative and less invasive solution in mind?
> 
>>> Store the iommu_ops pointer in the iommu_domain and use it as a check to
>>> validate that the struct device is correct before invoking any domain op
>>> that accepts a struct device.
>>
>> In fact this even describes exactly that - "Store the iommu_ops pointer
>> in the iommu_domain", vs. the "Store the iommu_ops pointer in the
>> iommu_domain_ops" which the patch is actually doing :/
> 
> Will fix that.

Well, as before I'd prefer to make the code match the commit message - 
if I really need to spell it out, see below - since I can't imagine that 
we should ever have need to identify a set of iommu_domain_ops in 
isolation, therefore I think it's considerably clearer to use the 
iommu_domain itself. However, either way we really don't need this yet, 
so we may as well just go ahead and remove the redundant test from VFIO 
anyway, and I can add some form of this patch to my dev branch for now.

Thanks,
Robin.

----->8-----
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index cde2e1d6ab9b..72990edc9314 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1902,6 +1902,7 @@ static struct iommu_domain 
*__iommu_domain_alloc(struct device *dev,
  	domain->type = type;
  	/* Assume all sizes by default; the driver may override this later */
  	domain->pgsize_bitmap = ops->pgsize_bitmap;
+	domain->owner = ops;
  	if (!domain->ops)
  		domain->ops = ops->default_domain_ops;

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 6f64cbbc6721..79e557207f53 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -89,6 +89,7 @@ struct iommu_domain_geometry {

  struct iommu_domain {
  	unsigned type;
+	const struct iommu_ops *owner; /* Who allocated this domain */
  	const struct iommu_domain_ops *ops;
  	unsigned long pgsize_bitmap;	/* Bitmap of page sizes in use */
  	iommu_fault_handler_t handler;
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 17:50         ` Robin Murphy
  0 siblings, 0 replies; 138+ messages in thread
From: Robin Murphy @ 2022-06-06 17:50 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: cohuck, heiko, mjrosato, bjorn.andersson, linux-tegra,
	thierry.reding, alim.akhtar, will, alyssa, m.szyprowski,
	jean-philippe, linux-samsung-soc, kvm, samuel, zhang.lyra, joro,
	robdclark, jernej.skrabec, jonathanh, linux-rockchip, wens,
	agross, linux-arm-kernel, jgg, orsonzhai, gerald.schaefer,
	linux-sunxi, sven, linux-arm-msm, alex.williamson, iommu,
	linux-mediatek, matthias.bgg, virtualization, yong.wu,
	linux-s390, marcan, linux-kernel, krzysztof.kozlowski,
	suravee.suthikulpanit, baolin.wang7, dwmw2, baolu.lu

On 2022-06-06 17:51, Nicolin Chen wrote:
> Hi Robin,
> 
> On Mon, Jun 06, 2022 at 03:33:42PM +0100, Robin Murphy wrote:
>> On 2022-06-06 07:19, Nicolin Chen wrote:
>>> The core code should not call an iommu driver op with a struct device
>>> parameter unless it knows that the dev_iommu_priv_get() for that struct
>>> device was setup by the same driver. Otherwise in a mixed driver system
>>> the iommu_priv could be casted to the wrong type.
>>
>> We don't have mixed-driver systems, and there are plenty more
>> significant problems than this one to solve before we can (but thanks
>> for pointing it out - I hadn't got as far as auditing the public
>> interfaces yet). Once domains are allocated via a particular device's
>> IOMMU instance in the first place, there will be ample opportunity for
>> the core to stash suitable identifying information in the domain for
>> itself. TBH even the current code could do it without needing the
>> weirdly invasive changes here.
> 
> Do you have an alternative and less invasive solution in mind?
> 
>>> Store the iommu_ops pointer in the iommu_domain and use it as a check to
>>> validate that the struct device is correct before invoking any domain op
>>> that accepts a struct device.
>>
>> In fact this even describes exactly that - "Store the iommu_ops pointer
>> in the iommu_domain", vs. the "Store the iommu_ops pointer in the
>> iommu_domain_ops" which the patch is actually doing :/
> 
> Will fix that.

Well, as before I'd prefer to make the code match the commit message - 
if I really need to spell it out, see below - since I can't imagine that 
we should ever have need to identify a set of iommu_domain_ops in 
isolation, therefore I think it's considerably clearer to use the 
iommu_domain itself. However, either way we really don't need this yet, 
so we may as well just go ahead and remove the redundant test from VFIO 
anyway, and I can add some form of this patch to my dev branch for now.

Thanks,
Robin.

----->8-----
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index cde2e1d6ab9b..72990edc9314 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1902,6 +1902,7 @@ static struct iommu_domain 
*__iommu_domain_alloc(struct device *dev,
  	domain->type = type;
  	/* Assume all sizes by default; the driver may override this later */
  	domain->pgsize_bitmap = ops->pgsize_bitmap;
+	domain->owner = ops;
  	if (!domain->ops)
  		domain->ops = ops->default_domain_ops;

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 6f64cbbc6721..79e557207f53 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -89,6 +89,7 @@ struct iommu_domain_geometry {

  struct iommu_domain {
  	unsigned type;
+	const struct iommu_ops *owner; /* Who allocated this domain */
  	const struct iommu_domain_ops *ops;
  	unsigned long pgsize_bitmap;	/* Bitmap of page sizes in use */
  	iommu_fault_handler_t handler;

_______________________________________________
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] 138+ messages in thread

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
  2022-06-06 17:50         ` Robin Murphy
                             ` (2 preceding siblings ...)
  (?)
@ 2022-06-06 18:28           ` Nicolin Chen
  -1 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06 18:28 UTC (permalink / raw)
  To: Robin Murphy
  Cc: jgg, joro, will, marcan, sven, robdclark, m.szyprowski,
	krzysztof.kozlowski, baolu.lu, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On Mon, Jun 06, 2022 at 06:50:33PM +0100, Robin Murphy wrote:
> External email: Use caution opening links or attachments
> 
> 
> On 2022-06-06 17:51, Nicolin Chen wrote:
> > Hi Robin,
> > 
> > On Mon, Jun 06, 2022 at 03:33:42PM +0100, Robin Murphy wrote:
> > > On 2022-06-06 07:19, Nicolin Chen wrote:
> > > > The core code should not call an iommu driver op with a struct device
> > > > parameter unless it knows that the dev_iommu_priv_get() for that struct
> > > > device was setup by the same driver. Otherwise in a mixed driver system
> > > > the iommu_priv could be casted to the wrong type.
> > > 
> > > We don't have mixed-driver systems, and there are plenty more
> > > significant problems than this one to solve before we can (but thanks
> > > for pointing it out - I hadn't got as far as auditing the public
> > > interfaces yet). Once domains are allocated via a particular device's
> > > IOMMU instance in the first place, there will be ample opportunity for
> > > the core to stash suitable identifying information in the domain for
> > > itself. TBH even the current code could do it without needing the
> > > weirdly invasive changes here.
> > 
> > Do you have an alternative and less invasive solution in mind?
> > 
> > > > Store the iommu_ops pointer in the iommu_domain and use it as a check to
> > > > validate that the struct device is correct before invoking any domain op
> > > > that accepts a struct device.
> > > 
> > > In fact this even describes exactly that - "Store the iommu_ops pointer
> > > in the iommu_domain", vs. the "Store the iommu_ops pointer in the
> > > iommu_domain_ops" which the patch is actually doing :/
> > 
> > Will fix that.
> 
> Well, as before I'd prefer to make the code match the commit message -
> if I really need to spell it out, see below - since I can't imagine that
> we should ever have need to identify a set of iommu_domain_ops in
> isolation, therefore I think it's considerably clearer to use the
> iommu_domain itself. However, either way we really don't need this yet,
> so we may as well just go ahead and remove the redundant test from VFIO
> anyway, and I can add some form of this patch to my dev branch for now.

I see. The version below is much cleaner. Yet, it'd become having a
common pointer per iommu_domain vs. one pointer per driver. Jason
pointed it out to me earlier that by doing so memory waste would be
unnecessary on platforms that have considerable numbers of masters.

Since we know that it'd be safe to exclude this single change from
this series, I can drop it in next version, if you don't like the
change.

Thanks!
Nic

> ----->8-----
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index cde2e1d6ab9b..72990edc9314 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -1902,6 +1902,7 @@ static struct iommu_domain
> *__iommu_domain_alloc(struct device *dev,
>        domain->type = type;
>        /* Assume all sizes by default; the driver may override this later */
>        domain->pgsize_bitmap = ops->pgsize_bitmap;
> +       domain->owner = ops;
>        if (!domain->ops)
>                domain->ops = ops->default_domain_ops;
> 
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 6f64cbbc6721..79e557207f53 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -89,6 +89,7 @@ struct iommu_domain_geometry {
> 
>  struct iommu_domain {
>        unsigned type;
> +       const struct iommu_ops *owner; /* Who allocated this domain */
>        const struct iommu_domain_ops *ops;
>        unsigned long pgsize_bitmap;    /* Bitmap of page sizes in use */
>        iommu_fault_handler_t handler;

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 18:28           ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06 18:28 UTC (permalink / raw)
  To: Robin Murphy
  Cc: jgg, joro, will, marcan, sven, robdclark, m.szyprowski,
	krzysztof.kozlowski, baolu.lu, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On Mon, Jun 06, 2022 at 06:50:33PM +0100, Robin Murphy wrote:
> External email: Use caution opening links or attachments
> 
> 
> On 2022-06-06 17:51, Nicolin Chen wrote:
> > Hi Robin,
> > 
> > On Mon, Jun 06, 2022 at 03:33:42PM +0100, Robin Murphy wrote:
> > > On 2022-06-06 07:19, Nicolin Chen wrote:
> > > > The core code should not call an iommu driver op with a struct device
> > > > parameter unless it knows that the dev_iommu_priv_get() for that struct
> > > > device was setup by the same driver. Otherwise in a mixed driver system
> > > > the iommu_priv could be casted to the wrong type.
> > > 
> > > We don't have mixed-driver systems, and there are plenty more
> > > significant problems than this one to solve before we can (but thanks
> > > for pointing it out - I hadn't got as far as auditing the public
> > > interfaces yet). Once domains are allocated via a particular device's
> > > IOMMU instance in the first place, there will be ample opportunity for
> > > the core to stash suitable identifying information in the domain for
> > > itself. TBH even the current code could do it without needing the
> > > weirdly invasive changes here.
> > 
> > Do you have an alternative and less invasive solution in mind?
> > 
> > > > Store the iommu_ops pointer in the iommu_domain and use it as a check to
> > > > validate that the struct device is correct before invoking any domain op
> > > > that accepts a struct device.
> > > 
> > > In fact this even describes exactly that - "Store the iommu_ops pointer
> > > in the iommu_domain", vs. the "Store the iommu_ops pointer in the
> > > iommu_domain_ops" which the patch is actually doing :/
> > 
> > Will fix that.
> 
> Well, as before I'd prefer to make the code match the commit message -
> if I really need to spell it out, see below - since I can't imagine that
> we should ever have need to identify a set of iommu_domain_ops in
> isolation, therefore I think it's considerably clearer to use the
> iommu_domain itself. However, either way we really don't need this yet,
> so we may as well just go ahead and remove the redundant test from VFIO
> anyway, and I can add some form of this patch to my dev branch for now.

I see. The version below is much cleaner. Yet, it'd become having a
common pointer per iommu_domain vs. one pointer per driver. Jason
pointed it out to me earlier that by doing so memory waste would be
unnecessary on platforms that have considerable numbers of masters.

Since we know that it'd be safe to exclude this single change from
this series, I can drop it in next version, if you don't like the
change.

Thanks!
Nic

> ----->8-----
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index cde2e1d6ab9b..72990edc9314 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -1902,6 +1902,7 @@ static struct iommu_domain
> *__iommu_domain_alloc(struct device *dev,
>        domain->type = type;
>        /* Assume all sizes by default; the driver may override this later */
>        domain->pgsize_bitmap = ops->pgsize_bitmap;
> +       domain->owner = ops;
>        if (!domain->ops)
>                domain->ops = ops->default_domain_ops;
> 
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 6f64cbbc6721..79e557207f53 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -89,6 +89,7 @@ struct iommu_domain_geometry {
> 
>  struct iommu_domain {
>        unsigned type;
> +       const struct iommu_ops *owner; /* Who allocated this domain */
>        const struct iommu_domain_ops *ops;
>        unsigned long pgsize_bitmap;    /* Bitmap of page sizes in use */
>        iommu_fault_handler_t handler;

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

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 18:28           ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen via iommu @ 2022-06-06 18:28 UTC (permalink / raw)
  To: Robin Murphy
  Cc: cohuck, heiko, linux-tegra, thierry.reding, alim.akhtar, will,
	alyssa, jean-philippe, linux-samsung-soc, kvm, samuel,
	zhang.lyra, jernej.skrabec, jonathanh, linux-rockchip, wens,
	agross, linux-arm-kernel, jgg, orsonzhai, gerald.schaefer,
	linux-sunxi, linux-arm-msm, alex.williamson, iommu,
	linux-mediatek, matthias.bgg, virtualization, linux-s390, marcan,
	linux-kernel, krzysztof.kozlowski, baolin.wang7, dwmw2

On Mon, Jun 06, 2022 at 06:50:33PM +0100, Robin Murphy wrote:
> External email: Use caution opening links or attachments
> 
> 
> On 2022-06-06 17:51, Nicolin Chen wrote:
> > Hi Robin,
> > 
> > On Mon, Jun 06, 2022 at 03:33:42PM +0100, Robin Murphy wrote:
> > > On 2022-06-06 07:19, Nicolin Chen wrote:
> > > > The core code should not call an iommu driver op with a struct device
> > > > parameter unless it knows that the dev_iommu_priv_get() for that struct
> > > > device was setup by the same driver. Otherwise in a mixed driver system
> > > > the iommu_priv could be casted to the wrong type.
> > > 
> > > We don't have mixed-driver systems, and there are plenty more
> > > significant problems than this one to solve before we can (but thanks
> > > for pointing it out - I hadn't got as far as auditing the public
> > > interfaces yet). Once domains are allocated via a particular device's
> > > IOMMU instance in the first place, there will be ample opportunity for
> > > the core to stash suitable identifying information in the domain for
> > > itself. TBH even the current code could do it without needing the
> > > weirdly invasive changes here.
> > 
> > Do you have an alternative and less invasive solution in mind?
> > 
> > > > Store the iommu_ops pointer in the iommu_domain and use it as a check to
> > > > validate that the struct device is correct before invoking any domain op
> > > > that accepts a struct device.
> > > 
> > > In fact this even describes exactly that - "Store the iommu_ops pointer
> > > in the iommu_domain", vs. the "Store the iommu_ops pointer in the
> > > iommu_domain_ops" which the patch is actually doing :/
> > 
> > Will fix that.
> 
> Well, as before I'd prefer to make the code match the commit message -
> if I really need to spell it out, see below - since I can't imagine that
> we should ever have need to identify a set of iommu_domain_ops in
> isolation, therefore I think it's considerably clearer to use the
> iommu_domain itself. However, either way we really don't need this yet,
> so we may as well just go ahead and remove the redundant test from VFIO
> anyway, and I can add some form of this patch to my dev branch for now.

I see. The version below is much cleaner. Yet, it'd become having a
common pointer per iommu_domain vs. one pointer per driver. Jason
pointed it out to me earlier that by doing so memory waste would be
unnecessary on platforms that have considerable numbers of masters.

Since we know that it'd be safe to exclude this single change from
this series, I can drop it in next version, if you don't like the
change.

Thanks!
Nic

> ----->8-----
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index cde2e1d6ab9b..72990edc9314 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -1902,6 +1902,7 @@ static struct iommu_domain
> *__iommu_domain_alloc(struct device *dev,
>        domain->type = type;
>        /* Assume all sizes by default; the driver may override this later */
>        domain->pgsize_bitmap = ops->pgsize_bitmap;
> +       domain->owner = ops;
>        if (!domain->ops)
>                domain->ops = ops->default_domain_ops;
> 
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 6f64cbbc6721..79e557207f53 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -89,6 +89,7 @@ struct iommu_domain_geometry {
> 
>  struct iommu_domain {
>        unsigned type;
> +       const struct iommu_ops *owner; /* Who allocated this domain */
>        const struct iommu_domain_ops *ops;
>        unsigned long pgsize_bitmap;    /* Bitmap of page sizes in use */
>        iommu_fault_handler_t handler;
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 18:28           ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06 18:28 UTC (permalink / raw)
  To: Robin Murphy
  Cc: jgg, joro, will, marcan, sven, robdclark, m.szyprowski,
	krzysztof.kozlowski, baolu.lu, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On Mon, Jun 06, 2022 at 06:50:33PM +0100, Robin Murphy wrote:
> External email: Use caution opening links or attachments
> 
> 
> On 2022-06-06 17:51, Nicolin Chen wrote:
> > Hi Robin,
> > 
> > On Mon, Jun 06, 2022 at 03:33:42PM +0100, Robin Murphy wrote:
> > > On 2022-06-06 07:19, Nicolin Chen wrote:
> > > > The core code should not call an iommu driver op with a struct device
> > > > parameter unless it knows that the dev_iommu_priv_get() for that struct
> > > > device was setup by the same driver. Otherwise in a mixed driver system
> > > > the iommu_priv could be casted to the wrong type.
> > > 
> > > We don't have mixed-driver systems, and there are plenty more
> > > significant problems than this one to solve before we can (but thanks
> > > for pointing it out - I hadn't got as far as auditing the public
> > > interfaces yet). Once domains are allocated via a particular device's
> > > IOMMU instance in the first place, there will be ample opportunity for
> > > the core to stash suitable identifying information in the domain for
> > > itself. TBH even the current code could do it without needing the
> > > weirdly invasive changes here.
> > 
> > Do you have an alternative and less invasive solution in mind?
> > 
> > > > Store the iommu_ops pointer in the iommu_domain and use it as a check to
> > > > validate that the struct device is correct before invoking any domain op
> > > > that accepts a struct device.
> > > 
> > > In fact this even describes exactly that - "Store the iommu_ops pointer
> > > in the iommu_domain", vs. the "Store the iommu_ops pointer in the
> > > iommu_domain_ops" which the patch is actually doing :/
> > 
> > Will fix that.
> 
> Well, as before I'd prefer to make the code match the commit message -
> if I really need to spell it out, see below - since I can't imagine that
> we should ever have need to identify a set of iommu_domain_ops in
> isolation, therefore I think it's considerably clearer to use the
> iommu_domain itself. However, either way we really don't need this yet,
> so we may as well just go ahead and remove the redundant test from VFIO
> anyway, and I can add some form of this patch to my dev branch for now.

I see. The version below is much cleaner. Yet, it'd become having a
common pointer per iommu_domain vs. one pointer per driver. Jason
pointed it out to me earlier that by doing so memory waste would be
unnecessary on platforms that have considerable numbers of masters.

Since we know that it'd be safe to exclude this single change from
this series, I can drop it in next version, if you don't like the
change.

Thanks!
Nic

> ----->8-----
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index cde2e1d6ab9b..72990edc9314 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -1902,6 +1902,7 @@ static struct iommu_domain
> *__iommu_domain_alloc(struct device *dev,
>        domain->type = type;
>        /* Assume all sizes by default; the driver may override this later */
>        domain->pgsize_bitmap = ops->pgsize_bitmap;
> +       domain->owner = ops;
>        if (!domain->ops)
>                domain->ops = ops->default_domain_ops;
> 
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 6f64cbbc6721..79e557207f53 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -89,6 +89,7 @@ struct iommu_domain_geometry {
> 
>  struct iommu_domain {
>        unsigned type;
> +       const struct iommu_ops *owner; /* Who allocated this domain */
>        const struct iommu_domain_ops *ops;
>        unsigned long pgsize_bitmap;    /* Bitmap of page sizes in use */
>        iommu_fault_handler_t handler;

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

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 18:28           ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-06 18:28 UTC (permalink / raw)
  To: Robin Murphy
  Cc: cohuck, heiko, mjrosato, bjorn.andersson, linux-tegra,
	thierry.reding, alim.akhtar, will, alyssa, m.szyprowski,
	jean-philippe, linux-samsung-soc, kvm, samuel, zhang.lyra, joro,
	robdclark, jernej.skrabec, jonathanh, linux-rockchip, wens,
	agross, linux-arm-kernel, jgg, orsonzhai, gerald.schaefer,
	linux-sunxi, sven, linux-arm-msm, alex.williamson, iommu,
	linux-mediatek, matthias.bgg, virtualization, yong.wu,
	linux-s390, marcan, linux-kernel, krzysztof.kozlowski,
	suravee.suthikulpanit, baolin.wang7, dwmw2, baolu.lu

On Mon, Jun 06, 2022 at 06:50:33PM +0100, Robin Murphy wrote:
> External email: Use caution opening links or attachments
> 
> 
> On 2022-06-06 17:51, Nicolin Chen wrote:
> > Hi Robin,
> > 
> > On Mon, Jun 06, 2022 at 03:33:42PM +0100, Robin Murphy wrote:
> > > On 2022-06-06 07:19, Nicolin Chen wrote:
> > > > The core code should not call an iommu driver op with a struct device
> > > > parameter unless it knows that the dev_iommu_priv_get() for that struct
> > > > device was setup by the same driver. Otherwise in a mixed driver system
> > > > the iommu_priv could be casted to the wrong type.
> > > 
> > > We don't have mixed-driver systems, and there are plenty more
> > > significant problems than this one to solve before we can (but thanks
> > > for pointing it out - I hadn't got as far as auditing the public
> > > interfaces yet). Once domains are allocated via a particular device's
> > > IOMMU instance in the first place, there will be ample opportunity for
> > > the core to stash suitable identifying information in the domain for
> > > itself. TBH even the current code could do it without needing the
> > > weirdly invasive changes here.
> > 
> > Do you have an alternative and less invasive solution in mind?
> > 
> > > > Store the iommu_ops pointer in the iommu_domain and use it as a check to
> > > > validate that the struct device is correct before invoking any domain op
> > > > that accepts a struct device.
> > > 
> > > In fact this even describes exactly that - "Store the iommu_ops pointer
> > > in the iommu_domain", vs. the "Store the iommu_ops pointer in the
> > > iommu_domain_ops" which the patch is actually doing :/
> > 
> > Will fix that.
> 
> Well, as before I'd prefer to make the code match the commit message -
> if I really need to spell it out, see below - since I can't imagine that
> we should ever have need to identify a set of iommu_domain_ops in
> isolation, therefore I think it's considerably clearer to use the
> iommu_domain itself. However, either way we really don't need this yet,
> so we may as well just go ahead and remove the redundant test from VFIO
> anyway, and I can add some form of this patch to my dev branch for now.

I see. The version below is much cleaner. Yet, it'd become having a
common pointer per iommu_domain vs. one pointer per driver. Jason
pointed it out to me earlier that by doing so memory waste would be
unnecessary on platforms that have considerable numbers of masters.

Since we know that it'd be safe to exclude this single change from
this series, I can drop it in next version, if you don't like the
change.

Thanks!
Nic

> ----->8-----
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index cde2e1d6ab9b..72990edc9314 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -1902,6 +1902,7 @@ static struct iommu_domain
> *__iommu_domain_alloc(struct device *dev,
>        domain->type = type;
>        /* Assume all sizes by default; the driver may override this later */
>        domain->pgsize_bitmap = ops->pgsize_bitmap;
> +       domain->owner = ops;
>        if (!domain->ops)
>                domain->ops = ops->default_domain_ops;
> 
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 6f64cbbc6721..79e557207f53 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -89,6 +89,7 @@ struct iommu_domain_geometry {
> 
>  struct iommu_domain {
>        unsigned type;
> +       const struct iommu_ops *owner; /* Who allocated this domain */
>        const struct iommu_domain_ops *ops;
>        unsigned long pgsize_bitmap;    /* Bitmap of page sizes in use */
>        iommu_fault_handler_t handler;

_______________________________________________
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] 138+ messages in thread

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
  2022-06-06 18:28           ` Nicolin Chen
                               ` (2 preceding siblings ...)
  (?)
@ 2022-06-06 18:52             ` Jason Gunthorpe via iommu
  -1 siblings, 0 replies; 138+ messages in thread
From: Jason Gunthorpe @ 2022-06-06 18:52 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: Robin Murphy, joro, will, marcan, sven, robdclark, m.szyprowski,
	krzysztof.kozlowski, baolu.lu, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On Mon, Jun 06, 2022 at 11:28:49AM -0700, Nicolin Chen wrote:

> > Well, as before I'd prefer to make the code match the commit message -
> > if I really need to spell it out, see below - since I can't imagine that
> > we should ever have need to identify a set of iommu_domain_ops in
> > isolation, therefore I think it's considerably clearer to use the
> > iommu_domain itself. However, either way we really don't need this yet,
> > so we may as well just go ahead and remove the redundant test from VFIO
> > anyway, and I can add some form of this patch to my dev branch for now.
> 
> I see. The version below is much cleaner. Yet, it'd become having a
> common pointer per iommu_domain vs. one pointer per driver. Jason
> pointed it out to me earlier that by doing so memory waste would be
> unnecessary on platforms that have considerable numbers of masters.

I had ment using struct iommu_domain when there is a simple solution
to use rodata doesn't seem ideal.

I don't quite understand the reluctance to make small changes to
drivers, it was the same logic with the default_domain_ops thing too.

> Since we know that it'd be safe to exclude this single change from
> this series, I can drop it in next version, if you don't like the
> change.

But this is fine too, that really is half the point of this series..

Jason

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 18:52             ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Jason Gunthorpe via iommu @ 2022-06-06 18:52 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: linux-s390, cohuck, heiko, linux-tegra, thierry.reding,
	alim.akhtar, will, alyssa, jean-philippe, linux-samsung-soc, kvm,
	samuel, zhang.lyra, jernej.skrabec, jonathanh, linux-rockchip,
	wens, agross, linux-arm-kernel, orsonzhai, gerald.schaefer,
	linux-sunxi, linux-arm-msm, alex.williamson, iommu,
	linux-mediatek, matthias.bgg, virtualization, dwmw2, marcan,
	linux-kernel, krzysztof.kozlowski, baolin.wang7, Robin Murphy

On Mon, Jun 06, 2022 at 11:28:49AM -0700, Nicolin Chen wrote:

> > Well, as before I'd prefer to make the code match the commit message -
> > if I really need to spell it out, see below - since I can't imagine that
> > we should ever have need to identify a set of iommu_domain_ops in
> > isolation, therefore I think it's considerably clearer to use the
> > iommu_domain itself. However, either way we really don't need this yet,
> > so we may as well just go ahead and remove the redundant test from VFIO
> > anyway, and I can add some form of this patch to my dev branch for now.
> 
> I see. The version below is much cleaner. Yet, it'd become having a
> common pointer per iommu_domain vs. one pointer per driver. Jason
> pointed it out to me earlier that by doing so memory waste would be
> unnecessary on platforms that have considerable numbers of masters.

I had ment using struct iommu_domain when there is a simple solution
to use rodata doesn't seem ideal.

I don't quite understand the reluctance to make small changes to
drivers, it was the same logic with the default_domain_ops thing too.

> Since we know that it'd be safe to exclude this single change from
> this series, I can drop it in next version, if you don't like the
> change.

But this is fine too, that really is half the point of this series..

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

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 18:52             ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Jason Gunthorpe @ 2022-06-06 18:52 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: Robin Murphy, joro, will, marcan, sven, robdclark, m.szyprowski,
	krzysztof.kozlowski, baolu.lu, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On Mon, Jun 06, 2022 at 11:28:49AM -0700, Nicolin Chen wrote:

> > Well, as before I'd prefer to make the code match the commit message -
> > if I really need to spell it out, see below - since I can't imagine that
> > we should ever have need to identify a set of iommu_domain_ops in
> > isolation, therefore I think it's considerably clearer to use the
> > iommu_domain itself. However, either way we really don't need this yet,
> > so we may as well just go ahead and remove the redundant test from VFIO
> > anyway, and I can add some form of this patch to my dev branch for now.
> 
> I see. The version below is much cleaner. Yet, it'd become having a
> common pointer per iommu_domain vs. one pointer per driver. Jason
> pointed it out to me earlier that by doing so memory waste would be
> unnecessary on platforms that have considerable numbers of masters.

I had ment using struct iommu_domain when there is a simple solution
to use rodata doesn't seem ideal.

I don't quite understand the reluctance to make small changes to
drivers, it was the same logic with the default_domain_ops thing too.

> Since we know that it'd be safe to exclude this single change from
> this series, I can drop it in next version, if you don't like the
> change.

But this is fine too, that really is half the point of this series..

Jason

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

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 18:52             ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Jason Gunthorpe @ 2022-06-06 18:52 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: Robin Murphy, joro, will, marcan, sven, robdclark, m.szyprowski,
	krzysztof.kozlowski, baolu.lu, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On Mon, Jun 06, 2022 at 11:28:49AM -0700, Nicolin Chen wrote:

> > Well, as before I'd prefer to make the code match the commit message -
> > if I really need to spell it out, see below - since I can't imagine that
> > we should ever have need to identify a set of iommu_domain_ops in
> > isolation, therefore I think it's considerably clearer to use the
> > iommu_domain itself. However, either way we really don't need this yet,
> > so we may as well just go ahead and remove the redundant test from VFIO
> > anyway, and I can add some form of this patch to my dev branch for now.
> 
> I see. The version below is much cleaner. Yet, it'd become having a
> common pointer per iommu_domain vs. one pointer per driver. Jason
> pointed it out to me earlier that by doing so memory waste would be
> unnecessary on platforms that have considerable numbers of masters.

I had ment using struct iommu_domain when there is a simple solution
to use rodata doesn't seem ideal.

I don't quite understand the reluctance to make small changes to
drivers, it was the same logic with the default_domain_ops thing too.

> Since we know that it'd be safe to exclude this single change from
> this series, I can drop it in next version, if you don't like the
> change.

But this is fine too, that really is half the point of this series..

Jason

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

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

* Re: [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain
@ 2022-06-06 18:52             ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Jason Gunthorpe @ 2022-06-06 18:52 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: linux-s390, cohuck, heiko, mjrosato, bjorn.andersson,
	linux-tegra, thierry.reding, alim.akhtar, will, alyssa,
	m.szyprowski, jean-philippe, linux-samsung-soc, kvm, samuel,
	zhang.lyra, joro, robdclark, jernej.skrabec, jonathanh,
	linux-rockchip, wens, agross, linux-arm-kernel, orsonzhai,
	gerald.schaefer, linux-sunxi, sven, linux-arm-msm,
	alex.williamson, iommu, linux-mediatek, matthias.bgg,
	virtualization, yong.wu, dwmw2, marcan, linux-kernel,
	krzysztof.kozlowski, suravee.suthikulpanit, baolin.wang7,
	Robin Murphy, baolu.lu

On Mon, Jun 06, 2022 at 11:28:49AM -0700, Nicolin Chen wrote:

> > Well, as before I'd prefer to make the code match the commit message -
> > if I really need to spell it out, see below - since I can't imagine that
> > we should ever have need to identify a set of iommu_domain_ops in
> > isolation, therefore I think it's considerably clearer to use the
> > iommu_domain itself. However, either way we really don't need this yet,
> > so we may as well just go ahead and remove the redundant test from VFIO
> > anyway, and I can add some form of this patch to my dev branch for now.
> 
> I see. The version below is much cleaner. Yet, it'd become having a
> common pointer per iommu_domain vs. one pointer per driver. Jason
> pointed it out to me earlier that by doing so memory waste would be
> unnecessary on platforms that have considerable numbers of masters.

I had ment using struct iommu_domain when there is a simple solution
to use rodata doesn't seem ideal.

I don't quite understand the reluctance to make small changes to
drivers, it was the same logic with the default_domain_ops thing too.

> Since we know that it'd be safe to exclude this single change from
> this series, I can drop it in next version, if you don't like the
> change.

But this is fine too, that really is half the point of this series..

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] 138+ messages in thread

* Re: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
  2022-06-06  6:19   ` Nicolin Chen
                       ` (2 preceding siblings ...)
  (?)
@ 2022-06-07  3:23     ` Baolu Lu
  -1 siblings, 0 replies; 138+ messages in thread
From: Baolu Lu @ 2022-06-07  3:23 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

On 2022/6/6 14:19, Nicolin Chen wrote:
> +/**
> + * iommu_attach_group - Attach an IOMMU group to an IOMMU domain
> + * @domain: IOMMU domain to attach
> + * @dev: IOMMU group that will be attached

Nit: @group: ...

> + *
> + * Returns 0 on success and error code on failure
> + *
> + * Specifically, -EMEDIUMTYPE is returned if the domain and the group are
> + * incompatible in some way. This indicates that a caller should try another
> + * existing IOMMU domain or allocate a new one.
> + */
>   int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group)
>   {
>   	int ret;

Best regards,
baolu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-07  3:23     ` Baolu Lu
  0 siblings, 0 replies; 138+ messages in thread
From: Baolu Lu @ 2022-06-07  3:23 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: baolu.lu, suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2,
	yong.wu, mjrosato, gerald.schaefer, thierry.reding, vdumpa,
	jonathanh, cohuck, iommu, linux-kernel, linux-arm-kernel,
	linux-arm-msm, linux-samsung-soc, linux-mediatek, linux-rockchip,
	linux-s390, linux-sunxi, linux-tegra, virtualization, kvm

On 2022/6/6 14:19, Nicolin Chen wrote:
> +/**
> + * iommu_attach_group - Attach an IOMMU group to an IOMMU domain
> + * @domain: IOMMU domain to attach
> + * @dev: IOMMU group that will be attached

Nit: @group: ...

> + *
> + * Returns 0 on success and error code on failure
> + *
> + * Specifically, -EMEDIUMTYPE is returned if the domain and the group are
> + * incompatible in some way. This indicates that a caller should try another
> + * existing IOMMU domain or allocate a new one.
> + */
>   int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group)
>   {
>   	int ret;

Best regards,
baolu

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

* Re: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-07  3:23     ` Baolu Lu
  0 siblings, 0 replies; 138+ messages in thread
From: Baolu Lu @ 2022-06-07  3:23 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: baolu.lu, suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2,
	yong.wu, mjrosato, gerald.schaefer, thierry.reding, vdumpa,
	jonathanh, cohuck, iommu, linux-kernel, linux-arm-kernel,
	linux-arm-msm, linux-samsung-soc, linux-mediatek, linux-rockchip,
	linux-s390, linux-sunxi, linux-tegra, virtualization, kvm

On 2022/6/6 14:19, Nicolin Chen wrote:
> +/**
> + * iommu_attach_group - Attach an IOMMU group to an IOMMU domain
> + * @domain: IOMMU domain to attach
> + * @dev: IOMMU group that will be attached

Nit: @group: ...

> + *
> + * Returns 0 on success and error code on failure
> + *
> + * Specifically, -EMEDIUMTYPE is returned if the domain and the group are
> + * incompatible in some way. This indicates that a caller should try another
> + * existing IOMMU domain or allocate a new one.
> + */
>   int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group)
>   {
>   	int ret;

Best regards,
baolu

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

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

* Re: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-07  3:23     ` Baolu Lu
  0 siblings, 0 replies; 138+ messages in thread
From: Baolu Lu @ 2022-06-07  3:23 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: baolu.lu, suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2,
	yong.wu, mjrosato, gerald.schaefer, thierry.reding, vdumpa,
	jonathanh, cohuck, iommu, linux-kernel, linux-arm-kernel,
	linux-arm-msm, linux-samsung-soc, linux-mediatek, linux-rockchip,
	linux-s390, linux-sunxi, linux-tegra, virtualization, kvm

On 2022/6/6 14:19, Nicolin Chen wrote:
> +/**
> + * iommu_attach_group - Attach an IOMMU group to an IOMMU domain
> + * @domain: IOMMU domain to attach
> + * @dev: IOMMU group that will be attached

Nit: @group: ...

> + *
> + * Returns 0 on success and error code on failure
> + *
> + * Specifically, -EMEDIUMTYPE is returned if the domain and the group are
> + * incompatible in some way. This indicates that a caller should try another
> + * existing IOMMU domain or allocate a new one.
> + */
>   int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group)
>   {
>   	int ret;

Best regards,
baolu

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

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

* Re: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-07  3:23     ` Baolu Lu
  0 siblings, 0 replies; 138+ messages in thread
From: Baolu Lu @ 2022-06-07  3:23 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: mjrosato, virtualization, thierry.reding, alim.akhtar, alyssa,
	linux-s390, linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	yong.wu, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, suravee.suthikulpanit, dwmw2, baolu.lu

On 2022/6/6 14:19, Nicolin Chen wrote:
> +/**
> + * iommu_attach_group - Attach an IOMMU group to an IOMMU domain
> + * @domain: IOMMU domain to attach
> + * @dev: IOMMU group that will be attached

Nit: @group: ...

> + *
> + * Returns 0 on success and error code on failure
> + *
> + * Specifically, -EMEDIUMTYPE is returned if the domain and the group are
> + * incompatible in some way. This indicates that a caller should try another
> + * existing IOMMU domain or allocate a new one.
> + */
>   int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group)
>   {
>   	int ret;

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] 138+ messages in thread

* Re: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
  2022-06-07  3:23     ` Baolu Lu
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-07  4:03       ` Nicolin Chen
  -1 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-07  4:03 UTC (permalink / raw)
  To: Baolu Lu
  Cc: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On Tue, Jun 07, 2022 at 11:23:27AM +0800, Baolu Lu wrote:
> External email: Use caution opening links or attachments
> 
> 
> On 2022/6/6 14:19, Nicolin Chen wrote:
> > +/**
> > + * iommu_attach_group - Attach an IOMMU group to an IOMMU domain
> > + * @domain: IOMMU domain to attach
> > + * @dev: IOMMU group that will be attached
> 
> Nit: @group: ...

Oh...Thanks!

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

* Re: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-07  4:03       ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-07  4:03 UTC (permalink / raw)
  To: Baolu Lu
  Cc: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On Tue, Jun 07, 2022 at 11:23:27AM +0800, Baolu Lu wrote:
> External email: Use caution opening links or attachments
> 
> 
> On 2022/6/6 14:19, Nicolin Chen wrote:
> > +/**
> > + * iommu_attach_group - Attach an IOMMU group to an IOMMU domain
> > + * @domain: IOMMU domain to attach
> > + * @dev: IOMMU group that will be attached
> 
> Nit: @group: ...

Oh...Thanks!

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

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

* Re: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-07  4:03       ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen via iommu @ 2022-06-07  4:03 UTC (permalink / raw)
  To: Baolu Lu
  Cc: linux-s390, cohuck, heiko, linux-tegra, thierry.reding,
	alim.akhtar, will, alyssa, jean-philippe, linux-samsung-soc, kvm,
	samuel, zhang.lyra, jernej.skrabec, jonathanh, linux-rockchip,
	wens, agross, linux-arm-kernel, jgg, orsonzhai, gerald.schaefer,
	linux-sunxi, linux-arm-msm, alex.williamson, iommu,
	linux-mediatek, matthias.bgg, virtualization, dwmw2, marcan,
	linux-kernel, krzysztof.kozlowski, baolin.wang7, robin.murphy

On Tue, Jun 07, 2022 at 11:23:27AM +0800, Baolu Lu wrote:
> External email: Use caution opening links or attachments
> 
> 
> On 2022/6/6 14:19, Nicolin Chen wrote:
> > +/**
> > + * iommu_attach_group - Attach an IOMMU group to an IOMMU domain
> > + * @domain: IOMMU domain to attach
> > + * @dev: IOMMU group that will be attached
> 
> Nit: @group: ...

Oh...Thanks!
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-07  4:03       ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-07  4:03 UTC (permalink / raw)
  To: Baolu Lu
  Cc: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On Tue, Jun 07, 2022 at 11:23:27AM +0800, Baolu Lu wrote:
> External email: Use caution opening links or attachments
> 
> 
> On 2022/6/6 14:19, Nicolin Chen wrote:
> > +/**
> > + * iommu_attach_group - Attach an IOMMU group to an IOMMU domain
> > + * @domain: IOMMU domain to attach
> > + * @dev: IOMMU group that will be attached
> 
> Nit: @group: ...

Oh...Thanks!

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

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

* Re: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-07  4:03       ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-07  4:03 UTC (permalink / raw)
  To: Baolu Lu
  Cc: linux-s390, cohuck, heiko, mjrosato, bjorn.andersson,
	linux-tegra, thierry.reding, alim.akhtar, will, alyssa,
	m.szyprowski, jean-philippe, linux-samsung-soc, kvm, samuel,
	zhang.lyra, joro, robdclark, jernej.skrabec, jonathanh,
	linux-rockchip, wens, agross, linux-arm-kernel, jgg, orsonzhai,
	gerald.schaefer, linux-sunxi, sven, linux-arm-msm,
	alex.williamson, iommu, linux-mediatek, matthias.bgg,
	virtualization, yong.wu, dwmw2, marcan, linux-kernel,
	krzysztof.kozlowski, suravee.suthikulpanit, baolin.wang7,
	robin.murphy

On Tue, Jun 07, 2022 at 11:23:27AM +0800, Baolu Lu wrote:
> External email: Use caution opening links or attachments
> 
> 
> On 2022/6/6 14:19, Nicolin Chen wrote:
> > +/**
> > + * iommu_attach_group - Attach an IOMMU group to an IOMMU domain
> > + * @domain: IOMMU domain to attach
> > + * @dev: IOMMU group that will be attached
> 
> Nit: @group: ...

Oh...Thanks!

_______________________________________________
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] 138+ messages in thread

* Re: [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
  2022-06-06  6:19 ` Nicolin Chen
                     ` (2 preceding siblings ...)
  (?)
@ 2022-06-07  7:44   ` Baolu Lu
  -1 siblings, 0 replies; 138+ messages in thread
From: Baolu Lu @ 2022-06-07  7:44 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: baolu.lu, suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2,
	yong.wu, mjrosato, gerald.schaefer, thierry.reding, vdumpa,
	jonathanh, cohuck, iommu, linux-kernel, linux-arm-kernel,
	linux-arm-msm, linux-samsung-soc, linux-mediatek, linux-rockchip,
	linux-s390, linux-sunxi, linux-tegra, virtualization, kvm

On 2022/6/6 14:19, Nicolin Chen wrote:
> Worths mentioning the exact match for enforce_cache_coherency is removed
> with this series, since there's very less value in doing that since KVM
> won't be able to take advantage of it -- this just wastes domain memory.
> Instead, we rely on Intel IOMMU driver taking care of that internally.

After reading this series, I don't see that Intel IOMMU driver needs any
further change to support the new scheme. Did I miss anything?

Best regards,
baolu

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

* Re: [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-07  7:44   ` Baolu Lu
  0 siblings, 0 replies; 138+ messages in thread
From: Baolu Lu @ 2022-06-07  7:44 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: baolu.lu, suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2,
	yong.wu, mjrosato, gerald.schaefer, thierry.reding, vdumpa,
	jonathanh, cohuck, iommu, linux-kernel, linux-arm-kernel,
	linux-arm-msm, linux-samsung-soc, linux-mediatek, linux-rockchip,
	linux-s390, linux-sunxi, linux-tegra, virtualization, kvm

On 2022/6/6 14:19, Nicolin Chen wrote:
> Worths mentioning the exact match for enforce_cache_coherency is removed
> with this series, since there's very less value in doing that since KVM
> won't be able to take advantage of it -- this just wastes domain memory.
> Instead, we rely on Intel IOMMU driver taking care of that internally.

After reading this series, I don't see that Intel IOMMU driver needs any
further change to support the new scheme. Did I miss anything?

Best regards,
baolu

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

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

* Re: [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-07  7:44   ` Baolu Lu
  0 siblings, 0 replies; 138+ messages in thread
From: Baolu Lu @ 2022-06-07  7:44 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

On 2022/6/6 14:19, Nicolin Chen wrote:
> Worths mentioning the exact match for enforce_cache_coherency is removed
> with this series, since there's very less value in doing that since KVM
> won't be able to take advantage of it -- this just wastes domain memory.
> Instead, we rely on Intel IOMMU driver taking care of that internally.

After reading this series, I don't see that Intel IOMMU driver needs any
further change to support the new scheme. Did I miss anything?

Best regards,
baolu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-07  7:44   ` Baolu Lu
  0 siblings, 0 replies; 138+ messages in thread
From: Baolu Lu @ 2022-06-07  7:44 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: baolu.lu, suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2,
	yong.wu, mjrosato, gerald.schaefer, thierry.reding, vdumpa,
	jonathanh, cohuck, iommu, linux-kernel, linux-arm-kernel,
	linux-arm-msm, linux-samsung-soc, linux-mediatek, linux-rockchip,
	linux-s390, linux-sunxi, linux-tegra, virtualization, kvm

On 2022/6/6 14:19, Nicolin Chen wrote:
> Worths mentioning the exact match for enforce_cache_coherency is removed
> with this series, since there's very less value in doing that since KVM
> won't be able to take advantage of it -- this just wastes domain memory.
> Instead, we rely on Intel IOMMU driver taking care of that internally.

After reading this series, I don't see that Intel IOMMU driver needs any
further change to support the new scheme. Did I miss anything?

Best regards,
baolu

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

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

* Re: [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-07  7:44   ` Baolu Lu
  0 siblings, 0 replies; 138+ messages in thread
From: Baolu Lu @ 2022-06-07  7:44 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: mjrosato, virtualization, thierry.reding, alim.akhtar, alyssa,
	linux-s390, linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	yong.wu, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, suravee.suthikulpanit, dwmw2, baolu.lu

On 2022/6/6 14:19, Nicolin Chen wrote:
> Worths mentioning the exact match for enforce_cache_coherency is removed
> with this series, since there's very less value in doing that since KVM
> won't be able to take advantage of it -- this just wastes domain memory.
> Instead, we rely on Intel IOMMU driver taking care of that internally.

After reading this series, I don't see that Intel IOMMU driver needs any
further change to support the new scheme. Did I miss anything?

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] 138+ messages in thread

* Re: [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
  2022-06-07  7:44   ` Baolu Lu
                       ` (2 preceding siblings ...)
  (?)
@ 2022-06-07 11:58     ` Jason Gunthorpe via iommu
  -1 siblings, 0 replies; 138+ messages in thread
From: Jason Gunthorpe @ 2022-06-07 11:58 UTC (permalink / raw)
  To: Baolu Lu
  Cc: Nicolin Chen, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On Tue, Jun 07, 2022 at 03:44:43PM +0800, Baolu Lu wrote:
> On 2022/6/6 14:19, Nicolin Chen wrote:
> > Worths mentioning the exact match for enforce_cache_coherency is removed
> > with this series, since there's very less value in doing that since KVM
> > won't be able to take advantage of it -- this just wastes domain memory.
> > Instead, we rely on Intel IOMMU driver taking care of that internally.
> 
> After reading this series, I don't see that Intel IOMMU driver needs any
> further change to support the new scheme. Did I miss anything?

You already did it :)

Jason

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

* Re: [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-07 11:58     ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Jason Gunthorpe via iommu @ 2022-06-07 11:58 UTC (permalink / raw)
  To: Baolu Lu
  Cc: linux-s390, cohuck, heiko, linux-tegra, thierry.reding,
	alim.akhtar, will, alyssa, jean-philippe, linux-samsung-soc, kvm,
	samuel, zhang.lyra, jernej.skrabec, jonathanh, linux-rockchip,
	wens, agross, linux-arm-kernel, orsonzhai, gerald.schaefer,
	linux-sunxi, linux-arm-msm, alex.williamson, iommu,
	linux-mediatek, matthias.bgg, virtualization, dwmw2, marcan,
	linux-kernel, krzysztof.kozlowski, baolin.wang7, robin.murphy

On Tue, Jun 07, 2022 at 03:44:43PM +0800, Baolu Lu wrote:
> On 2022/6/6 14:19, Nicolin Chen wrote:
> > Worths mentioning the exact match for enforce_cache_coherency is removed
> > with this series, since there's very less value in doing that since KVM
> > won't be able to take advantage of it -- this just wastes domain memory.
> > Instead, we rely on Intel IOMMU driver taking care of that internally.
> 
> After reading this series, I don't see that Intel IOMMU driver needs any
> further change to support the new scheme. Did I miss anything?

You already did it :)

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

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

* Re: [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-07 11:58     ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Jason Gunthorpe @ 2022-06-07 11:58 UTC (permalink / raw)
  To: Baolu Lu
  Cc: Nicolin Chen, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On Tue, Jun 07, 2022 at 03:44:43PM +0800, Baolu Lu wrote:
> On 2022/6/6 14:19, Nicolin Chen wrote:
> > Worths mentioning the exact match for enforce_cache_coherency is removed
> > with this series, since there's very less value in doing that since KVM
> > won't be able to take advantage of it -- this just wastes domain memory.
> > Instead, we rely on Intel IOMMU driver taking care of that internally.
> 
> After reading this series, I don't see that Intel IOMMU driver needs any
> further change to support the new scheme. Did I miss anything?

You already did it :)

Jason

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

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

* Re: [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-07 11:58     ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Jason Gunthorpe @ 2022-06-07 11:58 UTC (permalink / raw)
  To: Baolu Lu
  Cc: Nicolin Chen, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, agross, bjorn.andersson,
	matthias.bgg, heiko, orsonzhai, baolin.wang7, zhang.lyra, wens,
	jernej.skrabec, samuel, jean-philippe, alex.williamson,
	suravee.suthikulpanit, alyssa, alim.akhtar, dwmw2, yong.wu,
	mjrosato, gerald.schaefer, thierry.reding, vdumpa, jonathanh,
	cohuck, iommu, linux-kernel, linux-arm-kernel, linux-arm-msm,
	linux-samsung-soc, linux-mediatek, linux-rockchip, linux-s390,
	linux-sunxi, linux-tegra, virtualization, kvm

On Tue, Jun 07, 2022 at 03:44:43PM +0800, Baolu Lu wrote:
> On 2022/6/6 14:19, Nicolin Chen wrote:
> > Worths mentioning the exact match for enforce_cache_coherency is removed
> > with this series, since there's very less value in doing that since KVM
> > won't be able to take advantage of it -- this just wastes domain memory.
> > Instead, we rely on Intel IOMMU driver taking care of that internally.
> 
> After reading this series, I don't see that Intel IOMMU driver needs any
> further change to support the new scheme. Did I miss anything?

You already did it :)

Jason

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

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

* Re: [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-07 11:58     ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Jason Gunthorpe @ 2022-06-07 11:58 UTC (permalink / raw)
  To: Baolu Lu
  Cc: linux-s390, cohuck, heiko, mjrosato, bjorn.andersson,
	linux-tegra, thierry.reding, alim.akhtar, will, alyssa,
	m.szyprowski, jean-philippe, linux-samsung-soc, kvm, samuel,
	zhang.lyra, joro, robdclark, jernej.skrabec, jonathanh,
	linux-rockchip, wens, agross, Nicolin Chen, linux-arm-kernel,
	orsonzhai, gerald.schaefer, linux-sunxi, sven, linux-arm-msm,
	alex.williamson, iommu, linux-mediatek, matthias.bgg,
	virtualization, yong.wu, dwmw2, marcan, linux-kernel,
	krzysztof.kozlowski, suravee.suthikulpanit, baolin.wang7,
	robin.murphy

On Tue, Jun 07, 2022 at 03:44:43PM +0800, Baolu Lu wrote:
> On 2022/6/6 14:19, Nicolin Chen wrote:
> > Worths mentioning the exact match for enforce_cache_coherency is removed
> > with this series, since there's very less value in doing that since KVM
> > won't be able to take advantage of it -- this just wastes domain memory.
> > Instead, we rely on Intel IOMMU driver taking care of that internally.
> 
> After reading this series, I don't see that Intel IOMMU driver needs any
> further change to support the new scheme. Did I miss anything?

You already did it :)

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] 138+ messages in thread

* Re: [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
  2022-06-07 11:58     ` Jason Gunthorpe via iommu
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-07 12:42       ` Baolu Lu
  -1 siblings, 0 replies; 138+ messages in thread
From: Baolu Lu @ 2022-06-07 12:42 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: baolu.lu, Nicolin Chen, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, suravee.suthikulpanit, alyssa, alim.akhtar,
	dwmw2, yong.wu, mjrosato, gerald.schaefer, thierry.reding,
	vdumpa, jonathanh, cohuck, iommu, linux-kernel, linux-arm-kernel,
	linux-arm-msm, linux-samsung-soc, linux-mediatek, linux-rockchip,
	linux-s390, linux-sunxi, linux-tegra, virtualization, kvm

On 2022/6/7 19:58, Jason Gunthorpe wrote:
> On Tue, Jun 07, 2022 at 03:44:43PM +0800, Baolu Lu wrote:
>> On 2022/6/6 14:19, Nicolin Chen wrote:
>>> Worths mentioning the exact match for enforce_cache_coherency is removed
>>> with this series, since there's very less value in doing that since KVM
>>> won't be able to take advantage of it -- this just wastes domain memory.
>>> Instead, we rely on Intel IOMMU driver taking care of that internally.
>>
>> After reading this series, I don't see that Intel IOMMU driver needs any
>> further change to support the new scheme. Did I miss anything?
> 
> You already did it :)

Just as I thought. Thank you!

Best regards,
baolu


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

* Re: [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-07 12:42       ` Baolu Lu
  0 siblings, 0 replies; 138+ messages in thread
From: Baolu Lu @ 2022-06-07 12:42 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: linux-s390, cohuck, heiko, linux-tegra, thierry.reding,
	alim.akhtar, will, alyssa, jean-philippe, linux-samsung-soc, kvm,
	samuel, zhang.lyra, jernej.skrabec, jonathanh, linux-rockchip,
	wens, agross, linux-arm-kernel, orsonzhai, gerald.schaefer,
	linux-sunxi, linux-arm-msm, alex.williamson, iommu,
	linux-mediatek, matthias.bgg, virtualization, dwmw2, marcan,
	linux-kernel, krzysztof.kozlowski, baolin.wang7, robin.murphy

On 2022/6/7 19:58, Jason Gunthorpe wrote:
> On Tue, Jun 07, 2022 at 03:44:43PM +0800, Baolu Lu wrote:
>> On 2022/6/6 14:19, Nicolin Chen wrote:
>>> Worths mentioning the exact match for enforce_cache_coherency is removed
>>> with this series, since there's very less value in doing that since KVM
>>> won't be able to take advantage of it -- this just wastes domain memory.
>>> Instead, we rely on Intel IOMMU driver taking care of that internally.
>>
>> After reading this series, I don't see that Intel IOMMU driver needs any
>> further change to support the new scheme. Did I miss anything?
> 
> You already did it :)

Just as I thought. Thank you!

Best regards,
baolu

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

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

* Re: [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-07 12:42       ` Baolu Lu
  0 siblings, 0 replies; 138+ messages in thread
From: Baolu Lu @ 2022-06-07 12:42 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: baolu.lu, Nicolin Chen, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, suravee.suthikulpanit, alyssa, alim.akhtar,
	dwmw2, yong.wu, mjrosato, gerald.schaefer, thierry.reding,
	vdumpa, jonathanh, cohuck, iommu, linux-kernel, linux-arm-kernel,
	linux-arm-msm, linux-samsung-soc, linux-mediatek, linux-rockchip,
	linux-s390, linux-sunxi, linux-tegra, virtualization, kvm

On 2022/6/7 19:58, Jason Gunthorpe wrote:
> On Tue, Jun 07, 2022 at 03:44:43PM +0800, Baolu Lu wrote:
>> On 2022/6/6 14:19, Nicolin Chen wrote:
>>> Worths mentioning the exact match for enforce_cache_coherency is removed
>>> with this series, since there's very less value in doing that since KVM
>>> won't be able to take advantage of it -- this just wastes domain memory.
>>> Instead, we rely on Intel IOMMU driver taking care of that internally.
>>
>> After reading this series, I don't see that Intel IOMMU driver needs any
>> further change to support the new scheme. Did I miss anything?
> 
> You already did it :)

Just as I thought. Thank you!

Best regards,
baolu


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

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

* Re: [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-07 12:42       ` Baolu Lu
  0 siblings, 0 replies; 138+ messages in thread
From: Baolu Lu @ 2022-06-07 12:42 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: baolu.lu, Nicolin Chen, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, suravee.suthikulpanit, alyssa, alim.akhtar,
	dwmw2, yong.wu, mjrosato, gerald.schaefer, thierry.reding,
	vdumpa, jonathanh, cohuck, iommu, linux-kernel, linux-arm-kernel,
	linux-arm-msm, linux-samsung-soc, linux-mediatek, linux-rockchip,
	linux-s390, linux-sunxi, linux-tegra, virtualization, kvm

On 2022/6/7 19:58, Jason Gunthorpe wrote:
> On Tue, Jun 07, 2022 at 03:44:43PM +0800, Baolu Lu wrote:
>> On 2022/6/6 14:19, Nicolin Chen wrote:
>>> Worths mentioning the exact match for enforce_cache_coherency is removed
>>> with this series, since there's very less value in doing that since KVM
>>> won't be able to take advantage of it -- this just wastes domain memory.
>>> Instead, we rely on Intel IOMMU driver taking care of that internally.
>>
>> After reading this series, I don't see that Intel IOMMU driver needs any
>> further change to support the new scheme. Did I miss anything?
> 
> You already did it :)

Just as I thought. Thank you!

Best regards,
baolu


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

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

* Re: [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine
@ 2022-06-07 12:42       ` Baolu Lu
  0 siblings, 0 replies; 138+ messages in thread
From: Baolu Lu @ 2022-06-07 12:42 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: linux-s390, cohuck, heiko, mjrosato, bjorn.andersson,
	linux-tegra, thierry.reding, alim.akhtar, will, alyssa,
	m.szyprowski, jean-philippe, linux-samsung-soc, kvm, samuel,
	zhang.lyra, joro, robdclark, jernej.skrabec, jonathanh,
	linux-rockchip, wens, agross, Nicolin Chen, linux-arm-kernel,
	orsonzhai, gerald.schaefer, linux-sunxi, sven, linux-arm-msm,
	alex.williamson, iommu, linux-mediatek, matthias.bgg,
	virtualization, yong.wu, dwmw2, marcan, linux-kernel,
	krzysztof.kozlowski, suravee.suthikulpanit, baolin.wang7,
	robin.murphy, baolu.lu

On 2022/6/7 19:58, Jason Gunthorpe wrote:
> On Tue, Jun 07, 2022 at 03:44:43PM +0800, Baolu Lu wrote:
>> On 2022/6/6 14:19, Nicolin Chen wrote:
>>> Worths mentioning the exact match for enforce_cache_coherency is removed
>>> with this series, since there's very less value in doing that since KVM
>>> won't be able to take advantage of it -- this just wastes domain memory.
>>> Instead, we rely on Intel IOMMU driver taking care of that internally.
>>
>> After reading this series, I don't see that Intel IOMMU driver needs any
>> further change to support the new scheme. Did I miss anything?
> 
> You already did it :)

Just as I thought. Thank you!

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] 138+ messages in thread

* RE: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
  2022-06-06  6:19   ` Nicolin Chen
                       ` (3 preceding siblings ...)
  (?)
@ 2022-06-08  7:49     ` Tian, Kevin
  -1 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  7:49 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> Cases like VFIO wish to attach a device to an existing domain that was
> not allocated specifically from the device. This raises a condition
> where the IOMMU driver can fail the domain attach because the domain and
> device are incompatible with each other.
> 
> This is a soft failure that can be resolved by using a different domain.
> 
> Provide a dedicated errno from the IOMMU driver during attach that the
> reason attached failed is because of domain incompatability. EMEDIUMTYPE
> is chosen because it is never used within the iommu subsystem today and
> evokes a sense that the 'medium' aka the domain is incompatible.
> 
> VFIO can use this to know attach is a soft failure and it should continue
> searching. Otherwise the attach will be a hard failure and VFIO will
> return the code to userspace.
> 
> Update all drivers to return EMEDIUMTYPE in their failure paths that are
> related to domain incompatability.

Seems not all drivers are converted, e.g.:

mtk_iommu_v1_attach_device():
	/* Only allow the domain created internally. */
	mtk_mapping = data->mapping;
	if (mtk_mapping->domain != domain)
		return 0;
** the current code sounds incorrect which should return an error


s390_iommu_attach_device():
	/* Allow only devices with identical DMA range limits */
	} else if (domain->geometry.aperture_start != zdev->start_dma ||
		domain->geometry.aperture_end != zdev->end_dma) {
		rc = -EINVAL;


sprd_iommu_attach_device():
	if (dom->sdev) {
		pr_err("There's already a device attached to this domain.\n");
		return -EINVAL;
	}


gart_iommu_attach_dev():
	if (gart->active_domain && gart->active_domain != domain) {
		ret = -EBUSY;


arm_smmu_attach_dev():
	if (!fwspec || fwspec->ops != &arm_smmu_ops) {
		dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
		return -ENXIO;
	}
**probably this check can be covered by next patch which moves bus ops
check into iommu core?

Thanks
Kevin

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

* RE: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-08  7:49     ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  7:49 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: linux-s390, linux-samsung-soc, kvm, linux-arm-msm, cohuck,
	linux-kernel, virtualization, linux-rockchip, iommu,
	thierry.reding, linux-mediatek, linux-arm-kernel, alim.akhtar,
	linux-tegra, gerald.schaefer, jonathanh, dwmw2, linux-sunxi,
	alyssa

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> Cases like VFIO wish to attach a device to an existing domain that was
> not allocated specifically from the device. This raises a condition
> where the IOMMU driver can fail the domain attach because the domain and
> device are incompatible with each other.
> 
> This is a soft failure that can be resolved by using a different domain.
> 
> Provide a dedicated errno from the IOMMU driver during attach that the
> reason attached failed is because of domain incompatability. EMEDIUMTYPE
> is chosen because it is never used within the iommu subsystem today and
> evokes a sense that the 'medium' aka the domain is incompatible.
> 
> VFIO can use this to know attach is a soft failure and it should continue
> searching. Otherwise the attach will be a hard failure and VFIO will
> return the code to userspace.
> 
> Update all drivers to return EMEDIUMTYPE in their failure paths that are
> related to domain incompatability.

Seems not all drivers are converted, e.g.:

mtk_iommu_v1_attach_device():
	/* Only allow the domain created internally. */
	mtk_mapping = data->mapping;
	if (mtk_mapping->domain != domain)
		return 0;
** the current code sounds incorrect which should return an error


s390_iommu_attach_device():
	/* Allow only devices with identical DMA range limits */
	} else if (domain->geometry.aperture_start != zdev->start_dma ||
		domain->geometry.aperture_end != zdev->end_dma) {
		rc = -EINVAL;


sprd_iommu_attach_device():
	if (dom->sdev) {
		pr_err("There's already a device attached to this domain.\n");
		return -EINVAL;
	}


gart_iommu_attach_dev():
	if (gart->active_domain && gart->active_domain != domain) {
		ret = -EBUSY;


arm_smmu_attach_dev():
	if (!fwspec || fwspec->ops != &arm_smmu_ops) {
		dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
		return -ENXIO;
	}
**probably this check can be covered by next patch which moves bus ops
check into iommu core?

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

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

* RE: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-08  7:49     ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  7:49 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: linux-s390, linux-samsung-soc, kvm, linux-arm-msm, cohuck,
	linux-kernel, virtualization, linux-rockchip, iommu,
	thierry.reding, linux-mediatek, linux-arm-kernel, alim.akhtar,
	linux-tegra, gerald.schaefer, jonathanh, dwmw2, linux-sunxi,
	alyssa

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> Cases like VFIO wish to attach a device to an existing domain that was
> not allocated specifically from the device. This raises a condition
> where the IOMMU driver can fail the domain attach because the domain and
> device are incompatible with each other.
> 
> This is a soft failure that can be resolved by using a different domain.
> 
> Provide a dedicated errno from the IOMMU driver during attach that the
> reason attached failed is because of domain incompatability. EMEDIUMTYPE
> is chosen because it is never used within the iommu subsystem today and
> evokes a sense that the 'medium' aka the domain is incompatible.
> 
> VFIO can use this to know attach is a soft failure and it should continue
> searching. Otherwise the attach will be a hard failure and VFIO will
> return the code to userspace.
> 
> Update all drivers to return EMEDIUMTYPE in their failure paths that are
> related to domain incompatability.

Seems not all drivers are converted, e.g.:

mtk_iommu_v1_attach_device():
	/* Only allow the domain created internally. */
	mtk_mapping = data->mapping;
	if (mtk_mapping->domain != domain)
		return 0;
** the current code sounds incorrect which should return an error


s390_iommu_attach_device():
	/* Allow only devices with identical DMA range limits */
	} else if (domain->geometry.aperture_start != zdev->start_dma ||
		domain->geometry.aperture_end != zdev->end_dma) {
		rc = -EINVAL;


sprd_iommu_attach_device():
	if (dom->sdev) {
		pr_err("There's already a device attached to this domain.\n");
		return -EINVAL;
	}


gart_iommu_attach_dev():
	if (gart->active_domain && gart->active_domain != domain) {
		ret = -EBUSY;


arm_smmu_attach_dev():
	if (!fwspec || fwspec->ops != &arm_smmu_ops) {
		dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
		return -ENXIO;
	}
**probably this check can be covered by next patch which moves bus ops
check into iommu core?

Thanks
Kevin
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

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

* RE: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-08  7:49     ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  7:49 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> Cases like VFIO wish to attach a device to an existing domain that was
> not allocated specifically from the device. This raises a condition
> where the IOMMU driver can fail the domain attach because the domain and
> device are incompatible with each other.
> 
> This is a soft failure that can be resolved by using a different domain.
> 
> Provide a dedicated errno from the IOMMU driver during attach that the
> reason attached failed is because of domain incompatability. EMEDIUMTYPE
> is chosen because it is never used within the iommu subsystem today and
> evokes a sense that the 'medium' aka the domain is incompatible.
> 
> VFIO can use this to know attach is a soft failure and it should continue
> searching. Otherwise the attach will be a hard failure and VFIO will
> return the code to userspace.
> 
> Update all drivers to return EMEDIUMTYPE in their failure paths that are
> related to domain incompatability.

Seems not all drivers are converted, e.g.:

mtk_iommu_v1_attach_device():
	/* Only allow the domain created internally. */
	mtk_mapping = data->mapping;
	if (mtk_mapping->domain != domain)
		return 0;
** the current code sounds incorrect which should return an error


s390_iommu_attach_device():
	/* Allow only devices with identical DMA range limits */
	} else if (domain->geometry.aperture_start != zdev->start_dma ||
		domain->geometry.aperture_end != zdev->end_dma) {
		rc = -EINVAL;


sprd_iommu_attach_device():
	if (dom->sdev) {
		pr_err("There's already a device attached to this domain.\n");
		return -EINVAL;
	}


gart_iommu_attach_dev():
	if (gart->active_domain && gart->active_domain != domain) {
		ret = -EBUSY;


arm_smmu_attach_dev():
	if (!fwspec || fwspec->ops != &arm_smmu_ops) {
		dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
		return -ENXIO;
	}
**probably this check can be covered by next patch which moves bus ops
check into iommu core?

Thanks
Kevin

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

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

* RE: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-08  7:49     ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  7:49 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> Cases like VFIO wish to attach a device to an existing domain that was
> not allocated specifically from the device. This raises a condition
> where the IOMMU driver can fail the domain attach because the domain and
> device are incompatible with each other.
> 
> This is a soft failure that can be resolved by using a different domain.
> 
> Provide a dedicated errno from the IOMMU driver during attach that the
> reason attached failed is because of domain incompatability. EMEDIUMTYPE
> is chosen because it is never used within the iommu subsystem today and
> evokes a sense that the 'medium' aka the domain is incompatible.
> 
> VFIO can use this to know attach is a soft failure and it should continue
> searching. Otherwise the attach will be a hard failure and VFIO will
> return the code to userspace.
> 
> Update all drivers to return EMEDIUMTYPE in their failure paths that are
> related to domain incompatability.

Seems not all drivers are converted, e.g.:

mtk_iommu_v1_attach_device():
	/* Only allow the domain created internally. */
	mtk_mapping = data->mapping;
	if (mtk_mapping->domain != domain)
		return 0;
** the current code sounds incorrect which should return an error


s390_iommu_attach_device():
	/* Allow only devices with identical DMA range limits */
	} else if (domain->geometry.aperture_start != zdev->start_dma ||
		domain->geometry.aperture_end != zdev->end_dma) {
		rc = -EINVAL;


sprd_iommu_attach_device():
	if (dom->sdev) {
		pr_err("There's already a device attached to this domain.\n");
		return -EINVAL;
	}


gart_iommu_attach_dev():
	if (gart->active_domain && gart->active_domain != domain) {
		ret = -EBUSY;


arm_smmu_attach_dev():
	if (!fwspec || fwspec->ops != &arm_smmu_ops) {
		dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
		return -ENXIO;
	}
**probably this check can be covered by next patch which moves bus ops
check into iommu core?

Thanks
Kevin

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

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

* RE: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-08  7:49     ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  7:49 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> Cases like VFIO wish to attach a device to an existing domain that was
> not allocated specifically from the device. This raises a condition
> where the IOMMU driver can fail the domain attach because the domain and
> device are incompatible with each other.
> 
> This is a soft failure that can be resolved by using a different domain.
> 
> Provide a dedicated errno from the IOMMU driver during attach that the
> reason attached failed is because of domain incompatability. EMEDIUMTYPE
> is chosen because it is never used within the iommu subsystem today and
> evokes a sense that the 'medium' aka the domain is incompatible.
> 
> VFIO can use this to know attach is a soft failure and it should continue
> searching. Otherwise the attach will be a hard failure and VFIO will
> return the code to userspace.
> 
> Update all drivers to return EMEDIUMTYPE in their failure paths that are
> related to domain incompatability.

Seems not all drivers are converted, e.g.:

mtk_iommu_v1_attach_device():
	/* Only allow the domain created internally. */
	mtk_mapping = data->mapping;
	if (mtk_mapping->domain != domain)
		return 0;
** the current code sounds incorrect which should return an error


s390_iommu_attach_device():
	/* Allow only devices with identical DMA range limits */
	} else if (domain->geometry.aperture_start != zdev->start_dma ||
		domain->geometry.aperture_end != zdev->end_dma) {
		rc = -EINVAL;


sprd_iommu_attach_device():
	if (dom->sdev) {
		pr_err("There's already a device attached to this domain.\n");
		return -EINVAL;
	}


gart_iommu_attach_dev():
	if (gart->active_domain && gart->active_domain != domain) {
		ret = -EBUSY;


arm_smmu_attach_dev():
	if (!fwspec || fwspec->ops != &arm_smmu_ops) {
		dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
		return -ENXIO;
	}
**probably this check can be covered by next patch which moves bus ops
check into iommu core?

Thanks
Kevin

_______________________________________________
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] 138+ messages in thread

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
  2022-06-06  6:19   ` Nicolin Chen via iommu
                       ` (3 preceding siblings ...)
  (?)
@ 2022-06-08  8:28     ` Tian, Kevin
  -1 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  8:28 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> The KVM mechanism for controlling wbinvd is only triggered during
> kvm_vfio_group_add(), meaning it is a one-shot test done once the devices
> are setup.

It's not one-shot. kvm_vfio_update_coherency() is called in both
group_add() and group_del(). Then the coherency property is
checked dynamically in wbinvd emulation:

kvm_emulate_wbinvd()
  kvm_emulate_wbinvd_noskip()
    need_emulate_wbinvd()
      kvm_arch_has_noncoherent_dma()

It's also checked when a vcpu is scheduled to a new cpu for
tracking dirty cpus which requires cache flush when emulating
wbinvd on that vcpu. See kvm_arch_vcpu_load().

	/* Address WBINVD may be executed by guest */
	if (need_emulate_wbinvd(vcpu)) {
		if (static_call(kvm_x86_has_wbinvd_exit)())
			cpumask_set_cpu(cpu, vcpu->arch.wbinvd_dirty_mask);

In addition, it's also checked when deciding the effective memory
type of EPT entry. See vmx_get_mt_mask().

	if (!kvm_arch_has_noncoherent_dma(vcpu->kvm))
		return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT) | VMX_EPT_IPAT_BIT;

But I doubt above can work reliably when the property is changed
in the fly given above paths are triggered at different points. The
guest may end up in a mixed state where inconsistent coherency 
is assumed in different emulation paths.

and In reality I don't think such niche scenario is even tested 
given the only device imposing such trick is integrated Intel GPU
which iiuc no one would try to hotplug/hot-remove it to/from
a guest.

given that I'm fine with the change in this patch. Even more probably
we really want an explicit one-shot model so KVM can lock down
the property once it starts to consume it then further adding a new
group which would change the coherency is explicitly rejected and
removing an existing group leaves it intact.

> 
> So, there is no value in trying to push a device that could do enforced
> cache coherency to a dedicated domain vs re-using an existing domain since

"an existing domain (even if it doesn't enforce coherency)", otherwise if
it's already compatible there is no question here.

> KVM won't be able to take advantage of it. This just wastes domain memory.
> 
> Simplify this code and eliminate the test. This removes the only logic
> that needed to have a dummy domain attached prior to searching for a
> matching domain and simplifies the next patches.
> 
> If someday we want to try and optimize this further the better approach is
> to update the Intel driver so that enforce_cache_coherency() can work on a
> domain that already has IOPTEs and then call the enforce_cache_coherency()
> after detaching a device from a domain to upgrade the whole domain to
> enforced cache coherency mode.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
>  drivers/vfio/vfio_iommu_type1.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c
> b/drivers/vfio/vfio_iommu_type1.c
> index c13b9290e357..f4e3b423a453 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -2285,9 +2285,7 @@ static int vfio_iommu_type1_attach_group(void
> *iommu_data,
>  	 * testing if they're on the same bus_type.
>  	 */
>  	list_for_each_entry(d, &iommu->domain_list, next) {
> -		if (d->domain->ops == domain->domain->ops &&
> -		    d->enforce_cache_coherency ==
> -			    domain->enforce_cache_coherency) {
> +		if (d->domain->ops == domain->domain->ops) {
>  			iommu_detach_group(domain->domain, group-
> >iommu_group);
>  			if (!iommu_attach_group(d->domain,
>  						group->iommu_group)) {
> --
> 2.17.1
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-08  8:28     ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  8:28 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> The KVM mechanism for controlling wbinvd is only triggered during
> kvm_vfio_group_add(), meaning it is a one-shot test done once the devices
> are setup.

It's not one-shot. kvm_vfio_update_coherency() is called in both
group_add() and group_del(). Then the coherency property is
checked dynamically in wbinvd emulation:

kvm_emulate_wbinvd()
  kvm_emulate_wbinvd_noskip()
    need_emulate_wbinvd()
      kvm_arch_has_noncoherent_dma()

It's also checked when a vcpu is scheduled to a new cpu for
tracking dirty cpus which requires cache flush when emulating
wbinvd on that vcpu. See kvm_arch_vcpu_load().

	/* Address WBINVD may be executed by guest */
	if (need_emulate_wbinvd(vcpu)) {
		if (static_call(kvm_x86_has_wbinvd_exit)())
			cpumask_set_cpu(cpu, vcpu->arch.wbinvd_dirty_mask);

In addition, it's also checked when deciding the effective memory
type of EPT entry. See vmx_get_mt_mask().

	if (!kvm_arch_has_noncoherent_dma(vcpu->kvm))
		return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT) | VMX_EPT_IPAT_BIT;

But I doubt above can work reliably when the property is changed
in the fly given above paths are triggered at different points. The
guest may end up in a mixed state where inconsistent coherency 
is assumed in different emulation paths.

and In reality I don't think such niche scenario is even tested 
given the only device imposing such trick is integrated Intel GPU
which iiuc no one would try to hotplug/hot-remove it to/from
a guest.

given that I'm fine with the change in this patch. Even more probably
we really want an explicit one-shot model so KVM can lock down
the property once it starts to consume it then further adding a new
group which would change the coherency is explicitly rejected and
removing an existing group leaves it intact.

> 
> So, there is no value in trying to push a device that could do enforced
> cache coherency to a dedicated domain vs re-using an existing domain since

"an existing domain (even if it doesn't enforce coherency)", otherwise if
it's already compatible there is no question here.

> KVM won't be able to take advantage of it. This just wastes domain memory.
> 
> Simplify this code and eliminate the test. This removes the only logic
> that needed to have a dummy domain attached prior to searching for a
> matching domain and simplifies the next patches.
> 
> If someday we want to try and optimize this further the better approach is
> to update the Intel driver so that enforce_cache_coherency() can work on a
> domain that already has IOPTEs and then call the enforce_cache_coherency()
> after detaching a device from a domain to upgrade the whole domain to
> enforced cache coherency mode.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
>  drivers/vfio/vfio_iommu_type1.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c
> b/drivers/vfio/vfio_iommu_type1.c
> index c13b9290e357..f4e3b423a453 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -2285,9 +2285,7 @@ static int vfio_iommu_type1_attach_group(void
> *iommu_data,
>  	 * testing if they're on the same bus_type.
>  	 */
>  	list_for_each_entry(d, &iommu->domain_list, next) {
> -		if (d->domain->ops == domain->domain->ops &&
> -		    d->enforce_cache_coherency ==
> -			    domain->enforce_cache_coherency) {
> +		if (d->domain->ops == domain->domain->ops) {
>  			iommu_detach_group(domain->domain, group-
> >iommu_group);
>  			if (!iommu_attach_group(d->domain,
>  						group->iommu_group)) {
> --
> 2.17.1
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

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

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-08  8:28     ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  8:28 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: linux-s390, linux-samsung-soc, kvm, linux-arm-msm, cohuck,
	linux-kernel, virtualization, linux-rockchip, iommu,
	thierry.reding, linux-mediatek, linux-arm-kernel, alim.akhtar,
	linux-tegra, gerald.schaefer, jonathanh, dwmw2, linux-sunxi,
	alyssa

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> The KVM mechanism for controlling wbinvd is only triggered during
> kvm_vfio_group_add(), meaning it is a one-shot test done once the devices
> are setup.

It's not one-shot. kvm_vfio_update_coherency() is called in both
group_add() and group_del(). Then the coherency property is
checked dynamically in wbinvd emulation:

kvm_emulate_wbinvd()
  kvm_emulate_wbinvd_noskip()
    need_emulate_wbinvd()
      kvm_arch_has_noncoherent_dma()

It's also checked when a vcpu is scheduled to a new cpu for
tracking dirty cpus which requires cache flush when emulating
wbinvd on that vcpu. See kvm_arch_vcpu_load().

	/* Address WBINVD may be executed by guest */
	if (need_emulate_wbinvd(vcpu)) {
		if (static_call(kvm_x86_has_wbinvd_exit)())
			cpumask_set_cpu(cpu, vcpu->arch.wbinvd_dirty_mask);

In addition, it's also checked when deciding the effective memory
type of EPT entry. See vmx_get_mt_mask().

	if (!kvm_arch_has_noncoherent_dma(vcpu->kvm))
		return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT) | VMX_EPT_IPAT_BIT;

But I doubt above can work reliably when the property is changed
in the fly given above paths are triggered at different points. The
guest may end up in a mixed state where inconsistent coherency 
is assumed in different emulation paths.

and In reality I don't think such niche scenario is even tested 
given the only device imposing such trick is integrated Intel GPU
which iiuc no one would try to hotplug/hot-remove it to/from
a guest.

given that I'm fine with the change in this patch. Even more probably
we really want an explicit one-shot model so KVM can lock down
the property once it starts to consume it then further adding a new
group which would change the coherency is explicitly rejected and
removing an existing group leaves it intact.

> 
> So, there is no value in trying to push a device that could do enforced
> cache coherency to a dedicated domain vs re-using an existing domain since

"an existing domain (even if it doesn't enforce coherency)", otherwise if
it's already compatible there is no question here.

> KVM won't be able to take advantage of it. This just wastes domain memory.
> 
> Simplify this code and eliminate the test. This removes the only logic
> that needed to have a dummy domain attached prior to searching for a
> matching domain and simplifies the next patches.
> 
> If someday we want to try and optimize this further the better approach is
> to update the Intel driver so that enforce_cache_coherency() can work on a
> domain that already has IOPTEs and then call the enforce_cache_coherency()
> after detaching a device from a domain to upgrade the whole domain to
> enforced cache coherency mode.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
>  drivers/vfio/vfio_iommu_type1.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c
> b/drivers/vfio/vfio_iommu_type1.c
> index c13b9290e357..f4e3b423a453 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -2285,9 +2285,7 @@ static int vfio_iommu_type1_attach_group(void
> *iommu_data,
>  	 * testing if they're on the same bus_type.
>  	 */
>  	list_for_each_entry(d, &iommu->domain_list, next) {
> -		if (d->domain->ops == domain->domain->ops &&
> -		    d->enforce_cache_coherency ==
> -			    domain->enforce_cache_coherency) {
> +		if (d->domain->ops == domain->domain->ops) {
>  			iommu_detach_group(domain->domain, group-
> >iommu_group);
>  			if (!iommu_attach_group(d->domain,
>  						group->iommu_group)) {
> --
> 2.17.1
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-08  8:28     ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  8:28 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> The KVM mechanism for controlling wbinvd is only triggered during
> kvm_vfio_group_add(), meaning it is a one-shot test done once the devices
> are setup.

It's not one-shot. kvm_vfio_update_coherency() is called in both
group_add() and group_del(). Then the coherency property is
checked dynamically in wbinvd emulation:

kvm_emulate_wbinvd()
  kvm_emulate_wbinvd_noskip()
    need_emulate_wbinvd()
      kvm_arch_has_noncoherent_dma()

It's also checked when a vcpu is scheduled to a new cpu for
tracking dirty cpus which requires cache flush when emulating
wbinvd on that vcpu. See kvm_arch_vcpu_load().

	/* Address WBINVD may be executed by guest */
	if (need_emulate_wbinvd(vcpu)) {
		if (static_call(kvm_x86_has_wbinvd_exit)())
			cpumask_set_cpu(cpu, vcpu->arch.wbinvd_dirty_mask);

In addition, it's also checked when deciding the effective memory
type of EPT entry. See vmx_get_mt_mask().

	if (!kvm_arch_has_noncoherent_dma(vcpu->kvm))
		return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT) | VMX_EPT_IPAT_BIT;

But I doubt above can work reliably when the property is changed
in the fly given above paths are triggered at different points. The
guest may end up in a mixed state where inconsistent coherency 
is assumed in different emulation paths.

and In reality I don't think such niche scenario is even tested 
given the only device imposing such trick is integrated Intel GPU
which iiuc no one would try to hotplug/hot-remove it to/from
a guest.

given that I'm fine with the change in this patch. Even more probably
we really want an explicit one-shot model so KVM can lock down
the property once it starts to consume it then further adding a new
group which would change the coherency is explicitly rejected and
removing an existing group leaves it intact.

> 
> So, there is no value in trying to push a device that could do enforced
> cache coherency to a dedicated domain vs re-using an existing domain since

"an existing domain (even if it doesn't enforce coherency)", otherwise if
it's already compatible there is no question here.

> KVM won't be able to take advantage of it. This just wastes domain memory.
> 
> Simplify this code and eliminate the test. This removes the only logic
> that needed to have a dummy domain attached prior to searching for a
> matching domain and simplifies the next patches.
> 
> If someday we want to try and optimize this further the better approach is
> to update the Intel driver so that enforce_cache_coherency() can work on a
> domain that already has IOPTEs and then call the enforce_cache_coherency()
> after detaching a device from a domain to upgrade the whole domain to
> enforced cache coherency mode.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
>  drivers/vfio/vfio_iommu_type1.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c
> b/drivers/vfio/vfio_iommu_type1.c
> index c13b9290e357..f4e3b423a453 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -2285,9 +2285,7 @@ static int vfio_iommu_type1_attach_group(void
> *iommu_data,
>  	 * testing if they're on the same bus_type.
>  	 */
>  	list_for_each_entry(d, &iommu->domain_list, next) {
> -		if (d->domain->ops == domain->domain->ops &&
> -		    d->enforce_cache_coherency ==
> -			    domain->enforce_cache_coherency) {
> +		if (d->domain->ops == domain->domain->ops) {
>  			iommu_detach_group(domain->domain, group-
> >iommu_group);
>  			if (!iommu_attach_group(d->domain,
>  						group->iommu_group)) {
> --
> 2.17.1
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

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

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-08  8:28     ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  8:28 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: linux-s390, linux-samsung-soc, kvm, linux-arm-msm, cohuck,
	linux-kernel, virtualization, linux-rockchip, iommu,
	thierry.reding, linux-mediatek, linux-arm-kernel, alim.akhtar,
	linux-tegra, gerald.schaefer, jonathanh, dwmw2, linux-sunxi,
	alyssa

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> The KVM mechanism for controlling wbinvd is only triggered during
> kvm_vfio_group_add(), meaning it is a one-shot test done once the devices
> are setup.

It's not one-shot. kvm_vfio_update_coherency() is called in both
group_add() and group_del(). Then the coherency property is
checked dynamically in wbinvd emulation:

kvm_emulate_wbinvd()
  kvm_emulate_wbinvd_noskip()
    need_emulate_wbinvd()
      kvm_arch_has_noncoherent_dma()

It's also checked when a vcpu is scheduled to a new cpu for
tracking dirty cpus which requires cache flush when emulating
wbinvd on that vcpu. See kvm_arch_vcpu_load().

	/* Address WBINVD may be executed by guest */
	if (need_emulate_wbinvd(vcpu)) {
		if (static_call(kvm_x86_has_wbinvd_exit)())
			cpumask_set_cpu(cpu, vcpu->arch.wbinvd_dirty_mask);

In addition, it's also checked when deciding the effective memory
type of EPT entry. See vmx_get_mt_mask().

	if (!kvm_arch_has_noncoherent_dma(vcpu->kvm))
		return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT) | VMX_EPT_IPAT_BIT;

But I doubt above can work reliably when the property is changed
in the fly given above paths are triggered at different points. The
guest may end up in a mixed state where inconsistent coherency 
is assumed in different emulation paths.

and In reality I don't think such niche scenario is even tested 
given the only device imposing such trick is integrated Intel GPU
which iiuc no one would try to hotplug/hot-remove it to/from
a guest.

given that I'm fine with the change in this patch. Even more probably
we really want an explicit one-shot model so KVM can lock down
the property once it starts to consume it then further adding a new
group which would change the coherency is explicitly rejected and
removing an existing group leaves it intact.

> 
> So, there is no value in trying to push a device that could do enforced
> cache coherency to a dedicated domain vs re-using an existing domain since

"an existing domain (even if it doesn't enforce coherency)", otherwise if
it's already compatible there is no question here.

> KVM won't be able to take advantage of it. This just wastes domain memory.
> 
> Simplify this code and eliminate the test. This removes the only logic
> that needed to have a dummy domain attached prior to searching for a
> matching domain and simplifies the next patches.
> 
> If someday we want to try and optimize this further the better approach is
> to update the Intel driver so that enforce_cache_coherency() can work on a
> domain that already has IOPTEs and then call the enforce_cache_coherency()
> after detaching a device from a domain to upgrade the whole domain to
> enforced cache coherency mode.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
>  drivers/vfio/vfio_iommu_type1.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c
> b/drivers/vfio/vfio_iommu_type1.c
> index c13b9290e357..f4e3b423a453 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -2285,9 +2285,7 @@ static int vfio_iommu_type1_attach_group(void
> *iommu_data,
>  	 * testing if they're on the same bus_type.
>  	 */
>  	list_for_each_entry(d, &iommu->domain_list, next) {
> -		if (d->domain->ops == domain->domain->ops &&
> -		    d->enforce_cache_coherency ==
> -			    domain->enforce_cache_coherency) {
> +		if (d->domain->ops == domain->domain->ops) {
>  			iommu_detach_group(domain->domain, group-
> >iommu_group);
>  			if (!iommu_attach_group(d->domain,
>  						group->iommu_group)) {
> --
> 2.17.1
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

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

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-08  8:28     ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  8:28 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> The KVM mechanism for controlling wbinvd is only triggered during
> kvm_vfio_group_add(), meaning it is a one-shot test done once the devices
> are setup.

It's not one-shot. kvm_vfio_update_coherency() is called in both
group_add() and group_del(). Then the coherency property is
checked dynamically in wbinvd emulation:

kvm_emulate_wbinvd()
  kvm_emulate_wbinvd_noskip()
    need_emulate_wbinvd()
      kvm_arch_has_noncoherent_dma()

It's also checked when a vcpu is scheduled to a new cpu for
tracking dirty cpus which requires cache flush when emulating
wbinvd on that vcpu. See kvm_arch_vcpu_load().

	/* Address WBINVD may be executed by guest */
	if (need_emulate_wbinvd(vcpu)) {
		if (static_call(kvm_x86_has_wbinvd_exit)())
			cpumask_set_cpu(cpu, vcpu->arch.wbinvd_dirty_mask);

In addition, it's also checked when deciding the effective memory
type of EPT entry. See vmx_get_mt_mask().

	if (!kvm_arch_has_noncoherent_dma(vcpu->kvm))
		return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT) | VMX_EPT_IPAT_BIT;

But I doubt above can work reliably when the property is changed
in the fly given above paths are triggered at different points. The
guest may end up in a mixed state where inconsistent coherency 
is assumed in different emulation paths.

and In reality I don't think such niche scenario is even tested 
given the only device imposing such trick is integrated Intel GPU
which iiuc no one would try to hotplug/hot-remove it to/from
a guest.

given that I'm fine with the change in this patch. Even more probably
we really want an explicit one-shot model so KVM can lock down
the property once it starts to consume it then further adding a new
group which would change the coherency is explicitly rejected and
removing an existing group leaves it intact.

> 
> So, there is no value in trying to push a device that could do enforced
> cache coherency to a dedicated domain vs re-using an existing domain since

"an existing domain (even if it doesn't enforce coherency)", otherwise if
it's already compatible there is no question here.

> KVM won't be able to take advantage of it. This just wastes domain memory.
> 
> Simplify this code and eliminate the test. This removes the only logic
> that needed to have a dummy domain attached prior to searching for a
> matching domain and simplifies the next patches.
> 
> If someday we want to try and optimize this further the better approach is
> to update the Intel driver so that enforce_cache_coherency() can work on a
> domain that already has IOPTEs and then call the enforce_cache_coherency()
> after detaching a device from a domain to upgrade the whole domain to
> enforced cache coherency mode.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
>  drivers/vfio/vfio_iommu_type1.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c
> b/drivers/vfio/vfio_iommu_type1.c
> index c13b9290e357..f4e3b423a453 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -2285,9 +2285,7 @@ static int vfio_iommu_type1_attach_group(void
> *iommu_data,
>  	 * testing if they're on the same bus_type.
>  	 */
>  	list_for_each_entry(d, &iommu->domain_list, next) {
> -		if (d->domain->ops == domain->domain->ops &&
> -		    d->enforce_cache_coherency ==
> -			    domain->enforce_cache_coherency) {
> +		if (d->domain->ops == domain->domain->ops) {
>  			iommu_detach_group(domain->domain, group-
> >iommu_group);
>  			if (!iommu_attach_group(d->domain,
>  						group->iommu_group)) {
> --
> 2.17.1
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu

_______________________________________________
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] 138+ messages in thread

* RE: [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
  2022-06-06  6:19   ` Nicolin Chen via iommu
                       ` (3 preceding siblings ...)
  (?)
@ 2022-06-08  8:35     ` Tian, Kevin
  -1 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  8:35 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> All devices in emulated_iommu_groups have pinned_page_dirty_scope
> set, so the update_dirty_scope in the first list_for_each_entry
> is always false. Clean it up, and move the "if update_dirty_scope"
> part from the detach_group_done routine to the domain_list part.
> 
> Rename the "detach_group_done" goto label accordingly.
> 
> Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
>  drivers/vfio/vfio_iommu_type1.c | 27 ++++++++++++---------------
>  1 file changed, 12 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c
> b/drivers/vfio/vfio_iommu_type1.c
> index f4e3b423a453..b45b1cc118ef 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -2463,14 +2463,12 @@ static void
> vfio_iommu_type1_detach_group(void *iommu_data,
>  	struct vfio_iommu *iommu = iommu_data;
>  	struct vfio_domain *domain;
>  	struct vfio_iommu_group *group;
> -	bool update_dirty_scope = false;
>  	LIST_HEAD(iova_copy);
> 
>  	mutex_lock(&iommu->lock);
>  	list_for_each_entry(group, &iommu->emulated_iommu_groups,
> next) {
>  		if (group->iommu_group != iommu_group)
>  			continue;
> -		update_dirty_scope = !group->pinned_page_dirty_scope;
>  		list_del(&group->next);
>  		kfree(group);
> 
> @@ -2479,7 +2477,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			WARN_ON(iommu->notifier.head);
>  			vfio_iommu_unmap_unpin_all(iommu);
>  		}
> -		goto detach_group_done;
> +		goto out_unlock;
>  	}
> 
>  	/*
> @@ -2495,9 +2493,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			continue;
> 
>  		iommu_detach_group(domain->domain, group-
> >iommu_group);
> -		update_dirty_scope = !group->pinned_page_dirty_scope;
>  		list_del(&group->next);
> -		kfree(group);
>  		/*
>  		 * Group ownership provides privilege, if the group list is
>  		 * empty, the domain goes away. If it's the last domain with
> @@ -2519,7 +2515,17 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			kfree(domain);
>  			vfio_iommu_aper_expand(iommu, &iova_copy);
>  			vfio_update_pgsize_bitmap(iommu);
> +			/*
> +			 * Removal of a group without dirty tracking may
> allow
> +			 * the iommu scope to be promoted.
> +			 */
> +			if (!group->pinned_page_dirty_scope) {
> +				iommu->num_non_pinned_groups--;
> +				if (iommu->dirty_page_tracking)
> +
> 	vfio_iommu_populate_bitmap_full(iommu);

This doesn't look correct. The old code decrements
num_non_pinned_groups for every detach group without dirty
tracking. But now it's only done when the domain is about to
be released...

> +			}
>  		}
> +		kfree(group);
>  		break;
>  	}
> 
> @@ -2528,16 +2534,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  	else
>  		vfio_iommu_iova_free(&iova_copy);
> 
> -detach_group_done:
> -	/*
> -	 * Removal of a group without dirty tracking may allow the iommu
> scope
> -	 * to be promoted.
> -	 */
> -	if (update_dirty_scope) {
> -		iommu->num_non_pinned_groups--;
> -		if (iommu->dirty_page_tracking)
> -			vfio_iommu_populate_bitmap_full(iommu);
> -	}
> +out_unlock:
>  	mutex_unlock(&iommu->lock);
>  }
> 
> --
> 2.17.1
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* RE: [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
@ 2022-06-08  8:35     ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  8:35 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> All devices in emulated_iommu_groups have pinned_page_dirty_scope
> set, so the update_dirty_scope in the first list_for_each_entry
> is always false. Clean it up, and move the "if update_dirty_scope"
> part from the detach_group_done routine to the domain_list part.
> 
> Rename the "detach_group_done" goto label accordingly.
> 
> Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
>  drivers/vfio/vfio_iommu_type1.c | 27 ++++++++++++---------------
>  1 file changed, 12 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c
> b/drivers/vfio/vfio_iommu_type1.c
> index f4e3b423a453..b45b1cc118ef 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -2463,14 +2463,12 @@ static void
> vfio_iommu_type1_detach_group(void *iommu_data,
>  	struct vfio_iommu *iommu = iommu_data;
>  	struct vfio_domain *domain;
>  	struct vfio_iommu_group *group;
> -	bool update_dirty_scope = false;
>  	LIST_HEAD(iova_copy);
> 
>  	mutex_lock(&iommu->lock);
>  	list_for_each_entry(group, &iommu->emulated_iommu_groups,
> next) {
>  		if (group->iommu_group != iommu_group)
>  			continue;
> -		update_dirty_scope = !group->pinned_page_dirty_scope;
>  		list_del(&group->next);
>  		kfree(group);
> 
> @@ -2479,7 +2477,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			WARN_ON(iommu->notifier.head);
>  			vfio_iommu_unmap_unpin_all(iommu);
>  		}
> -		goto detach_group_done;
> +		goto out_unlock;
>  	}
> 
>  	/*
> @@ -2495,9 +2493,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			continue;
> 
>  		iommu_detach_group(domain->domain, group-
> >iommu_group);
> -		update_dirty_scope = !group->pinned_page_dirty_scope;
>  		list_del(&group->next);
> -		kfree(group);
>  		/*
>  		 * Group ownership provides privilege, if the group list is
>  		 * empty, the domain goes away. If it's the last domain with
> @@ -2519,7 +2515,17 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			kfree(domain);
>  			vfio_iommu_aper_expand(iommu, &iova_copy);
>  			vfio_update_pgsize_bitmap(iommu);
> +			/*
> +			 * Removal of a group without dirty tracking may
> allow
> +			 * the iommu scope to be promoted.
> +			 */
> +			if (!group->pinned_page_dirty_scope) {
> +				iommu->num_non_pinned_groups--;
> +				if (iommu->dirty_page_tracking)
> +
> 	vfio_iommu_populate_bitmap_full(iommu);

This doesn't look correct. The old code decrements
num_non_pinned_groups for every detach group without dirty
tracking. But now it's only done when the domain is about to
be released...

> +			}
>  		}
> +		kfree(group);
>  		break;
>  	}
> 
> @@ -2528,16 +2534,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  	else
>  		vfio_iommu_iova_free(&iova_copy);
> 
> -detach_group_done:
> -	/*
> -	 * Removal of a group without dirty tracking may allow the iommu
> scope
> -	 * to be promoted.
> -	 */
> -	if (update_dirty_scope) {
> -		iommu->num_non_pinned_groups--;
> -		if (iommu->dirty_page_tracking)
> -			vfio_iommu_populate_bitmap_full(iommu);
> -	}
> +out_unlock:
>  	mutex_unlock(&iommu->lock);
>  }
> 
> --
> 2.17.1
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

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

* RE: [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
@ 2022-06-08  8:35     ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  8:35 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: linux-s390, linux-samsung-soc, kvm, linux-arm-msm, cohuck,
	linux-kernel, virtualization, linux-rockchip, iommu,
	thierry.reding, linux-mediatek, linux-arm-kernel, alim.akhtar,
	linux-tegra, gerald.schaefer, jonathanh, dwmw2, linux-sunxi,
	alyssa

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> All devices in emulated_iommu_groups have pinned_page_dirty_scope
> set, so the update_dirty_scope in the first list_for_each_entry
> is always false. Clean it up, and move the "if update_dirty_scope"
> part from the detach_group_done routine to the domain_list part.
> 
> Rename the "detach_group_done" goto label accordingly.
> 
> Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
>  drivers/vfio/vfio_iommu_type1.c | 27 ++++++++++++---------------
>  1 file changed, 12 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c
> b/drivers/vfio/vfio_iommu_type1.c
> index f4e3b423a453..b45b1cc118ef 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -2463,14 +2463,12 @@ static void
> vfio_iommu_type1_detach_group(void *iommu_data,
>  	struct vfio_iommu *iommu = iommu_data;
>  	struct vfio_domain *domain;
>  	struct vfio_iommu_group *group;
> -	bool update_dirty_scope = false;
>  	LIST_HEAD(iova_copy);
> 
>  	mutex_lock(&iommu->lock);
>  	list_for_each_entry(group, &iommu->emulated_iommu_groups,
> next) {
>  		if (group->iommu_group != iommu_group)
>  			continue;
> -		update_dirty_scope = !group->pinned_page_dirty_scope;
>  		list_del(&group->next);
>  		kfree(group);
> 
> @@ -2479,7 +2477,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			WARN_ON(iommu->notifier.head);
>  			vfio_iommu_unmap_unpin_all(iommu);
>  		}
> -		goto detach_group_done;
> +		goto out_unlock;
>  	}
> 
>  	/*
> @@ -2495,9 +2493,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			continue;
> 
>  		iommu_detach_group(domain->domain, group-
> >iommu_group);
> -		update_dirty_scope = !group->pinned_page_dirty_scope;
>  		list_del(&group->next);
> -		kfree(group);
>  		/*
>  		 * Group ownership provides privilege, if the group list is
>  		 * empty, the domain goes away. If it's the last domain with
> @@ -2519,7 +2515,17 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			kfree(domain);
>  			vfio_iommu_aper_expand(iommu, &iova_copy);
>  			vfio_update_pgsize_bitmap(iommu);
> +			/*
> +			 * Removal of a group without dirty tracking may
> allow
> +			 * the iommu scope to be promoted.
> +			 */
> +			if (!group->pinned_page_dirty_scope) {
> +				iommu->num_non_pinned_groups--;
> +				if (iommu->dirty_page_tracking)
> +
> 	vfio_iommu_populate_bitmap_full(iommu);

This doesn't look correct. The old code decrements
num_non_pinned_groups for every detach group without dirty
tracking. But now it's only done when the domain is about to
be released...

> +			}
>  		}
> +		kfree(group);
>  		break;
>  	}
> 
> @@ -2528,16 +2534,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  	else
>  		vfio_iommu_iova_free(&iova_copy);
> 
> -detach_group_done:
> -	/*
> -	 * Removal of a group without dirty tracking may allow the iommu
> scope
> -	 * to be promoted.
> -	 */
> -	if (update_dirty_scope) {
> -		iommu->num_non_pinned_groups--;
> -		if (iommu->dirty_page_tracking)
> -			vfio_iommu_populate_bitmap_full(iommu);
> -	}
> +out_unlock:
>  	mutex_unlock(&iommu->lock);
>  }
> 
> --
> 2.17.1
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* RE: [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
@ 2022-06-08  8:35     ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  8:35 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> All devices in emulated_iommu_groups have pinned_page_dirty_scope
> set, so the update_dirty_scope in the first list_for_each_entry
> is always false. Clean it up, and move the "if update_dirty_scope"
> part from the detach_group_done routine to the domain_list part.
> 
> Rename the "detach_group_done" goto label accordingly.
> 
> Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
>  drivers/vfio/vfio_iommu_type1.c | 27 ++++++++++++---------------
>  1 file changed, 12 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c
> b/drivers/vfio/vfio_iommu_type1.c
> index f4e3b423a453..b45b1cc118ef 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -2463,14 +2463,12 @@ static void
> vfio_iommu_type1_detach_group(void *iommu_data,
>  	struct vfio_iommu *iommu = iommu_data;
>  	struct vfio_domain *domain;
>  	struct vfio_iommu_group *group;
> -	bool update_dirty_scope = false;
>  	LIST_HEAD(iova_copy);
> 
>  	mutex_lock(&iommu->lock);
>  	list_for_each_entry(group, &iommu->emulated_iommu_groups,
> next) {
>  		if (group->iommu_group != iommu_group)
>  			continue;
> -		update_dirty_scope = !group->pinned_page_dirty_scope;
>  		list_del(&group->next);
>  		kfree(group);
> 
> @@ -2479,7 +2477,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			WARN_ON(iommu->notifier.head);
>  			vfio_iommu_unmap_unpin_all(iommu);
>  		}
> -		goto detach_group_done;
> +		goto out_unlock;
>  	}
> 
>  	/*
> @@ -2495,9 +2493,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			continue;
> 
>  		iommu_detach_group(domain->domain, group-
> >iommu_group);
> -		update_dirty_scope = !group->pinned_page_dirty_scope;
>  		list_del(&group->next);
> -		kfree(group);
>  		/*
>  		 * Group ownership provides privilege, if the group list is
>  		 * empty, the domain goes away. If it's the last domain with
> @@ -2519,7 +2515,17 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			kfree(domain);
>  			vfio_iommu_aper_expand(iommu, &iova_copy);
>  			vfio_update_pgsize_bitmap(iommu);
> +			/*
> +			 * Removal of a group without dirty tracking may
> allow
> +			 * the iommu scope to be promoted.
> +			 */
> +			if (!group->pinned_page_dirty_scope) {
> +				iommu->num_non_pinned_groups--;
> +				if (iommu->dirty_page_tracking)
> +
> 	vfio_iommu_populate_bitmap_full(iommu);

This doesn't look correct. The old code decrements
num_non_pinned_groups for every detach group without dirty
tracking. But now it's only done when the domain is about to
be released...

> +			}
>  		}
> +		kfree(group);
>  		break;
>  	}
> 
> @@ -2528,16 +2534,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  	else
>  		vfio_iommu_iova_free(&iova_copy);
> 
> -detach_group_done:
> -	/*
> -	 * Removal of a group without dirty tracking may allow the iommu
> scope
> -	 * to be promoted.
> -	 */
> -	if (update_dirty_scope) {
> -		iommu->num_non_pinned_groups--;
> -		if (iommu->dirty_page_tracking)
> -			vfio_iommu_populate_bitmap_full(iommu);
> -	}
> +out_unlock:
>  	mutex_unlock(&iommu->lock);
>  }
> 
> --
> 2.17.1
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

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

* RE: [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
@ 2022-06-08  8:35     ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  8:35 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: linux-s390, linux-samsung-soc, kvm, linux-arm-msm, cohuck,
	linux-kernel, virtualization, linux-rockchip, iommu,
	thierry.reding, linux-mediatek, linux-arm-kernel, alim.akhtar,
	linux-tegra, gerald.schaefer, jonathanh, dwmw2, linux-sunxi,
	alyssa

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> All devices in emulated_iommu_groups have pinned_page_dirty_scope
> set, so the update_dirty_scope in the first list_for_each_entry
> is always false. Clean it up, and move the "if update_dirty_scope"
> part from the detach_group_done routine to the domain_list part.
> 
> Rename the "detach_group_done" goto label accordingly.
> 
> Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
>  drivers/vfio/vfio_iommu_type1.c | 27 ++++++++++++---------------
>  1 file changed, 12 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c
> b/drivers/vfio/vfio_iommu_type1.c
> index f4e3b423a453..b45b1cc118ef 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -2463,14 +2463,12 @@ static void
> vfio_iommu_type1_detach_group(void *iommu_data,
>  	struct vfio_iommu *iommu = iommu_data;
>  	struct vfio_domain *domain;
>  	struct vfio_iommu_group *group;
> -	bool update_dirty_scope = false;
>  	LIST_HEAD(iova_copy);
> 
>  	mutex_lock(&iommu->lock);
>  	list_for_each_entry(group, &iommu->emulated_iommu_groups,
> next) {
>  		if (group->iommu_group != iommu_group)
>  			continue;
> -		update_dirty_scope = !group->pinned_page_dirty_scope;
>  		list_del(&group->next);
>  		kfree(group);
> 
> @@ -2479,7 +2477,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			WARN_ON(iommu->notifier.head);
>  			vfio_iommu_unmap_unpin_all(iommu);
>  		}
> -		goto detach_group_done;
> +		goto out_unlock;
>  	}
> 
>  	/*
> @@ -2495,9 +2493,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			continue;
> 
>  		iommu_detach_group(domain->domain, group-
> >iommu_group);
> -		update_dirty_scope = !group->pinned_page_dirty_scope;
>  		list_del(&group->next);
> -		kfree(group);
>  		/*
>  		 * Group ownership provides privilege, if the group list is
>  		 * empty, the domain goes away. If it's the last domain with
> @@ -2519,7 +2515,17 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			kfree(domain);
>  			vfio_iommu_aper_expand(iommu, &iova_copy);
>  			vfio_update_pgsize_bitmap(iommu);
> +			/*
> +			 * Removal of a group without dirty tracking may
> allow
> +			 * the iommu scope to be promoted.
> +			 */
> +			if (!group->pinned_page_dirty_scope) {
> +				iommu->num_non_pinned_groups--;
> +				if (iommu->dirty_page_tracking)
> +
> 	vfio_iommu_populate_bitmap_full(iommu);

This doesn't look correct. The old code decrements
num_non_pinned_groups for every detach group without dirty
tracking. But now it's only done when the domain is about to
be released...

> +			}
>  		}
> +		kfree(group);
>  		break;
>  	}
> 
> @@ -2528,16 +2534,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  	else
>  		vfio_iommu_iova_free(&iova_copy);
> 
> -detach_group_done:
> -	/*
> -	 * Removal of a group without dirty tracking may allow the iommu
> scope
> -	 * to be promoted.
> -	 */
> -	if (update_dirty_scope) {
> -		iommu->num_non_pinned_groups--;
> -		if (iommu->dirty_page_tracking)
> -			vfio_iommu_populate_bitmap_full(iommu);
> -	}
> +out_unlock:
>  	mutex_unlock(&iommu->lock);
>  }
> 
> --
> 2.17.1
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

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

* RE: [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
@ 2022-06-08  8:35     ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08  8:35 UTC (permalink / raw)
  To: Nicolin Chen, jgg, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson
  Cc: virtualization, thierry.reding, alim.akhtar, alyssa, linux-s390,
	linux-samsung-soc, kvm, jonathanh, linux-rockchip,
	gerald.schaefer, linux-sunxi, linux-arm-msm, linux-mediatek,
	linux-tegra, linux-arm-kernel, cohuck, linux-kernel, iommu,
	dwmw2

> From: Nicolin Chen
> Sent: Monday, June 6, 2022 2:19 PM
> 
> All devices in emulated_iommu_groups have pinned_page_dirty_scope
> set, so the update_dirty_scope in the first list_for_each_entry
> is always false. Clean it up, and move the "if update_dirty_scope"
> part from the detach_group_done routine to the domain_list part.
> 
> Rename the "detach_group_done" goto label accordingly.
> 
> Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
>  drivers/vfio/vfio_iommu_type1.c | 27 ++++++++++++---------------
>  1 file changed, 12 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c
> b/drivers/vfio/vfio_iommu_type1.c
> index f4e3b423a453..b45b1cc118ef 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -2463,14 +2463,12 @@ static void
> vfio_iommu_type1_detach_group(void *iommu_data,
>  	struct vfio_iommu *iommu = iommu_data;
>  	struct vfio_domain *domain;
>  	struct vfio_iommu_group *group;
> -	bool update_dirty_scope = false;
>  	LIST_HEAD(iova_copy);
> 
>  	mutex_lock(&iommu->lock);
>  	list_for_each_entry(group, &iommu->emulated_iommu_groups,
> next) {
>  		if (group->iommu_group != iommu_group)
>  			continue;
> -		update_dirty_scope = !group->pinned_page_dirty_scope;
>  		list_del(&group->next);
>  		kfree(group);
> 
> @@ -2479,7 +2477,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			WARN_ON(iommu->notifier.head);
>  			vfio_iommu_unmap_unpin_all(iommu);
>  		}
> -		goto detach_group_done;
> +		goto out_unlock;
>  	}
> 
>  	/*
> @@ -2495,9 +2493,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			continue;
> 
>  		iommu_detach_group(domain->domain, group-
> >iommu_group);
> -		update_dirty_scope = !group->pinned_page_dirty_scope;
>  		list_del(&group->next);
> -		kfree(group);
>  		/*
>  		 * Group ownership provides privilege, if the group list is
>  		 * empty, the domain goes away. If it's the last domain with
> @@ -2519,7 +2515,17 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  			kfree(domain);
>  			vfio_iommu_aper_expand(iommu, &iova_copy);
>  			vfio_update_pgsize_bitmap(iommu);
> +			/*
> +			 * Removal of a group without dirty tracking may
> allow
> +			 * the iommu scope to be promoted.
> +			 */
> +			if (!group->pinned_page_dirty_scope) {
> +				iommu->num_non_pinned_groups--;
> +				if (iommu->dirty_page_tracking)
> +
> 	vfio_iommu_populate_bitmap_full(iommu);

This doesn't look correct. The old code decrements
num_non_pinned_groups for every detach group without dirty
tracking. But now it's only done when the domain is about to
be released...

> +			}
>  		}
> +		kfree(group);
>  		break;
>  	}
> 
> @@ -2528,16 +2534,7 @@ static void vfio_iommu_type1_detach_group(void
> *iommu_data,
>  	else
>  		vfio_iommu_iova_free(&iova_copy);
> 
> -detach_group_done:
> -	/*
> -	 * Removal of a group without dirty tracking may allow the iommu
> scope
> -	 * to be promoted.
> -	 */
> -	if (update_dirty_scope) {
> -		iommu->num_non_pinned_groups--;
> -		if (iommu->dirty_page_tracking)
> -			vfio_iommu_populate_bitmap_full(iommu);
> -	}
> +out_unlock:
>  	mutex_unlock(&iommu->lock);
>  }
> 
> --
> 2.17.1
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu

_______________________________________________
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] 138+ messages in thread

* Re: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
  2022-06-08  8:28     ` Tian, Kevin
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-08 11:17       ` Jason Gunthorpe
  -1 siblings, 0 replies; 138+ messages in thread
From: Jason Gunthorpe @ 2022-06-08 11:17 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: Nicolin Chen, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

On Wed, Jun 08, 2022 at 08:28:03AM +0000, Tian, Kevin wrote:
> > From: Nicolin Chen
> > Sent: Monday, June 6, 2022 2:19 PM
> > 
> > From: Jason Gunthorpe <jgg@nvidia.com>
> > 
> > The KVM mechanism for controlling wbinvd is only triggered during
> > kvm_vfio_group_add(), meaning it is a one-shot test done once the devices
> > are setup.
> 
> It's not one-shot. kvm_vfio_update_coherency() is called in both
> group_add() and group_del(). Then the coherency property is
> checked dynamically in wbinvd emulation:

From the perspective of managing the domains that is still
one-shot. It doesn't get updated when individual devices are
added/removed to domains.

> given that I'm fine with the change in this patch. Even more probably
> we really want an explicit one-shot model so KVM can lock down
> the property once it starts to consume it then further adding a new
> group which would change the coherency is explicitly rejected and
> removing an existing group leaves it intact.

Why? Once wbinvd is enabled it is compatible with all domain
configurations, so just leave it on and ignore everything at that
point.

Jason

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

* Re: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-08 11:17       ` Jason Gunthorpe
  0 siblings, 0 replies; 138+ messages in thread
From: Jason Gunthorpe @ 2022-06-08 11:17 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: Nicolin Chen, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

On Wed, Jun 08, 2022 at 08:28:03AM +0000, Tian, Kevin wrote:
> > From: Nicolin Chen
> > Sent: Monday, June 6, 2022 2:19 PM
> > 
> > From: Jason Gunthorpe <jgg@nvidia.com>
> > 
> > The KVM mechanism for controlling wbinvd is only triggered during
> > kvm_vfio_group_add(), meaning it is a one-shot test done once the devices
> > are setup.
> 
> It's not one-shot. kvm_vfio_update_coherency() is called in both
> group_add() and group_del(). Then the coherency property is
> checked dynamically in wbinvd emulation:

From the perspective of managing the domains that is still
one-shot. It doesn't get updated when individual devices are
added/removed to domains.

> given that I'm fine with the change in this patch. Even more probably
> we really want an explicit one-shot model so KVM can lock down
> the property once it starts to consume it then further adding a new
> group which would change the coherency is explicitly rejected and
> removing an existing group leaves it intact.

Why? Once wbinvd is enabled it is compatible with all domain
configurations, so just leave it on and ignore everything at that
point.

Jason

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

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

* Re: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-08 11:17       ` Jason Gunthorpe
  0 siblings, 0 replies; 138+ messages in thread
From: Jason Gunthorpe via iommu @ 2022-06-08 11:17 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: cohuck, heiko, kvm, linux-tegra, thierry.reding, alim.akhtar,
	will, alyssa, jean-philippe, linux-samsung-soc, samuel,
	zhang.lyra, jernej.skrabec, jonathanh, linux-rockchip, wens,
	agross, orsonzhai, gerald.schaefer, linux-sunxi, linux-arm-msm,
	alex.williamson, iommu, linux-mediatek, matthias.bgg,
	virtualization, linux-arm-kernel, linux-s390, marcan,
	linux-kernel, krzysztof.kozlowski, baolin.wang7, dwmw2,
	robin.murphy

On Wed, Jun 08, 2022 at 08:28:03AM +0000, Tian, Kevin wrote:
> > From: Nicolin Chen
> > Sent: Monday, June 6, 2022 2:19 PM
> > 
> > From: Jason Gunthorpe <jgg@nvidia.com>
> > 
> > The KVM mechanism for controlling wbinvd is only triggered during
> > kvm_vfio_group_add(), meaning it is a one-shot test done once the devices
> > are setup.
> 
> It's not one-shot. kvm_vfio_update_coherency() is called in both
> group_add() and group_del(). Then the coherency property is
> checked dynamically in wbinvd emulation:

From the perspective of managing the domains that is still
one-shot. It doesn't get updated when individual devices are
added/removed to domains.

> given that I'm fine with the change in this patch. Even more probably
> we really want an explicit one-shot model so KVM can lock down
> the property once it starts to consume it then further adding a new
> group which would change the coherency is explicitly rejected and
> removing an existing group leaves it intact.

Why? Once wbinvd is enabled it is compatible with all domain
configurations, so just leave it on and ignore everything at that
point.

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

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

* Re: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-08 11:17       ` Jason Gunthorpe
  0 siblings, 0 replies; 138+ messages in thread
From: Jason Gunthorpe @ 2022-06-08 11:17 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: Nicolin Chen, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

On Wed, Jun 08, 2022 at 08:28:03AM +0000, Tian, Kevin wrote:
> > From: Nicolin Chen
> > Sent: Monday, June 6, 2022 2:19 PM
> > 
> > From: Jason Gunthorpe <jgg@nvidia.com>
> > 
> > The KVM mechanism for controlling wbinvd is only triggered during
> > kvm_vfio_group_add(), meaning it is a one-shot test done once the devices
> > are setup.
> 
> It's not one-shot. kvm_vfio_update_coherency() is called in both
> group_add() and group_del(). Then the coherency property is
> checked dynamically in wbinvd emulation:

From the perspective of managing the domains that is still
one-shot. It doesn't get updated when individual devices are
added/removed to domains.

> given that I'm fine with the change in this patch. Even more probably
> we really want an explicit one-shot model so KVM can lock down
> the property once it starts to consume it then further adding a new
> group which would change the coherency is explicitly rejected and
> removing an existing group leaves it intact.

Why? Once wbinvd is enabled it is compatible with all domain
configurations, so just leave it on and ignore everything at that
point.

Jason

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

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

* Re: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-08 11:17       ` Jason Gunthorpe
  0 siblings, 0 replies; 138+ messages in thread
From: Jason Gunthorpe @ 2022-06-08 11:17 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: Nicolin Chen, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

On Wed, Jun 08, 2022 at 08:28:03AM +0000, Tian, Kevin wrote:
> > From: Nicolin Chen
> > Sent: Monday, June 6, 2022 2:19 PM
> > 
> > From: Jason Gunthorpe <jgg@nvidia.com>
> > 
> > The KVM mechanism for controlling wbinvd is only triggered during
> > kvm_vfio_group_add(), meaning it is a one-shot test done once the devices
> > are setup.
> 
> It's not one-shot. kvm_vfio_update_coherency() is called in both
> group_add() and group_del(). Then the coherency property is
> checked dynamically in wbinvd emulation:

From the perspective of managing the domains that is still
one-shot. It doesn't get updated when individual devices are
added/removed to domains.

> given that I'm fine with the change in this patch. Even more probably
> we really want an explicit one-shot model so KVM can lock down
> the property once it starts to consume it then further adding a new
> group which would change the coherency is explicitly rejected and
> removing an existing group leaves it intact.

Why? Once wbinvd is enabled it is compatible with all domain
configurations, so just leave it on and ignore everything at that
point.

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] 138+ messages in thread

* Re: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
  2022-06-08  7:49     ` Tian, Kevin
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-08 17:38       ` Nicolin Chen via iommu
  -1 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-08 17:38 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

Hi Kevin,

On Wed, Jun 08, 2022 at 07:49:10AM +0000, Tian, Kevin wrote:
> External email: Use caution opening links or attachments
> 
> 
> > From: Nicolin Chen
> > Sent: Monday, June 6, 2022 2:19 PM
> >
> > Cases like VFIO wish to attach a device to an existing domain that was
> > not allocated specifically from the device. This raises a condition
> > where the IOMMU driver can fail the domain attach because the domain and
> > device are incompatible with each other.
> >
> > This is a soft failure that can be resolved by using a different domain.
> >
> > Provide a dedicated errno from the IOMMU driver during attach that the
> > reason attached failed is because of domain incompatability. EMEDIUMTYPE
> > is chosen because it is never used within the iommu subsystem today and
> > evokes a sense that the 'medium' aka the domain is incompatible.
> >
> > VFIO can use this to know attach is a soft failure and it should continue
> > searching. Otherwise the attach will be a hard failure and VFIO will
> > return the code to userspace.
> >
> > Update all drivers to return EMEDIUMTYPE in their failure paths that are
> > related to domain incompatability.
> 
> Seems not all drivers are converted, e.g.:

Thank you for going through all of them!

> mtk_iommu_v1_attach_device():
>         /* Only allow the domain created internally. */
>         mtk_mapping = data->mapping;
>         if (mtk_mapping->domain != domain)
>                 return 0;
> ** the current code sounds incorrect which should return an error

I agree.
 
> s390_iommu_attach_device():
>         /* Allow only devices with identical DMA range limits */
>         } else if (domain->geometry.aperture_start != zdev->start_dma ||
>                 domain->geometry.aperture_end != zdev->end_dma) {
>                 rc = -EINVAL;
>
> sprd_iommu_attach_device():
>         if (dom->sdev) {
>                 pr_err("There's already a device attached to this domain.\n");
>                 return -EINVAL;
>         }
> 
> 
> gart_iommu_attach_dev():
>         if (gart->active_domain && gart->active_domain != domain) {
>                 ret = -EBUSY;

Will add these.

> arm_smmu_attach_dev():
>         if (!fwspec || fwspec->ops != &arm_smmu_ops) {
>                 dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
>                 return -ENXIO;
>         }
> **probably this check can be covered by next patch which moves bus ops
> check into iommu core?

I was thinking that it could be covered. Yet, we are about to drop
that ops check, as Robin pointed out that we don't need that ops
sanity for we don't have mixed-driver systems yet. So perhaps this
would be a different ops check and should return -EMEDIUMTYPE too,
I think.

Thanks
Nic

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

* Re: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-08 17:38       ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen via iommu @ 2022-06-08 17:38 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: cohuck, heiko, kvm, linux-tegra, thierry.reding, alim.akhtar,
	will, alyssa, jean-philippe, linux-samsung-soc, samuel,
	zhang.lyra, jernej.skrabec, jonathanh, linux-rockchip, wens,
	agross, jgg, orsonzhai, gerald.schaefer, linux-sunxi,
	linux-arm-msm, alex.williamson, iommu, linux-mediatek,
	matthias.bgg, virtualization, linux-arm-kernel, linux-s390,
	marcan, linux-kernel, krzysztof.kozlowski, baolin.wang7, dwmw2,
	robin.murphy

Hi Kevin,

On Wed, Jun 08, 2022 at 07:49:10AM +0000, Tian, Kevin wrote:
> External email: Use caution opening links or attachments
> 
> 
> > From: Nicolin Chen
> > Sent: Monday, June 6, 2022 2:19 PM
> >
> > Cases like VFIO wish to attach a device to an existing domain that was
> > not allocated specifically from the device. This raises a condition
> > where the IOMMU driver can fail the domain attach because the domain and
> > device are incompatible with each other.
> >
> > This is a soft failure that can be resolved by using a different domain.
> >
> > Provide a dedicated errno from the IOMMU driver during attach that the
> > reason attached failed is because of domain incompatability. EMEDIUMTYPE
> > is chosen because it is never used within the iommu subsystem today and
> > evokes a sense that the 'medium' aka the domain is incompatible.
> >
> > VFIO can use this to know attach is a soft failure and it should continue
> > searching. Otherwise the attach will be a hard failure and VFIO will
> > return the code to userspace.
> >
> > Update all drivers to return EMEDIUMTYPE in their failure paths that are
> > related to domain incompatability.
> 
> Seems not all drivers are converted, e.g.:

Thank you for going through all of them!

> mtk_iommu_v1_attach_device():
>         /* Only allow the domain created internally. */
>         mtk_mapping = data->mapping;
>         if (mtk_mapping->domain != domain)
>                 return 0;
> ** the current code sounds incorrect which should return an error

I agree.
 
> s390_iommu_attach_device():
>         /* Allow only devices with identical DMA range limits */
>         } else if (domain->geometry.aperture_start != zdev->start_dma ||
>                 domain->geometry.aperture_end != zdev->end_dma) {
>                 rc = -EINVAL;
>
> sprd_iommu_attach_device():
>         if (dom->sdev) {
>                 pr_err("There's already a device attached to this domain.\n");
>                 return -EINVAL;
>         }
> 
> 
> gart_iommu_attach_dev():
>         if (gart->active_domain && gart->active_domain != domain) {
>                 ret = -EBUSY;

Will add these.

> arm_smmu_attach_dev():
>         if (!fwspec || fwspec->ops != &arm_smmu_ops) {
>                 dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
>                 return -ENXIO;
>         }
> **probably this check can be covered by next patch which moves bus ops
> check into iommu core?

I was thinking that it could be covered. Yet, we are about to drop
that ops check, as Robin pointed out that we don't need that ops
sanity for we don't have mixed-driver systems yet. So perhaps this
would be a different ops check and should return -EMEDIUMTYPE too,
I think.

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

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

* Re: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-08 17:38       ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-08 17:38 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

Hi Kevin,

On Wed, Jun 08, 2022 at 07:49:10AM +0000, Tian, Kevin wrote:
> External email: Use caution opening links or attachments
> 
> 
> > From: Nicolin Chen
> > Sent: Monday, June 6, 2022 2:19 PM
> >
> > Cases like VFIO wish to attach a device to an existing domain that was
> > not allocated specifically from the device. This raises a condition
> > where the IOMMU driver can fail the domain attach because the domain and
> > device are incompatible with each other.
> >
> > This is a soft failure that can be resolved by using a different domain.
> >
> > Provide a dedicated errno from the IOMMU driver during attach that the
> > reason attached failed is because of domain incompatability. EMEDIUMTYPE
> > is chosen because it is never used within the iommu subsystem today and
> > evokes a sense that the 'medium' aka the domain is incompatible.
> >
> > VFIO can use this to know attach is a soft failure and it should continue
> > searching. Otherwise the attach will be a hard failure and VFIO will
> > return the code to userspace.
> >
> > Update all drivers to return EMEDIUMTYPE in their failure paths that are
> > related to domain incompatability.
> 
> Seems not all drivers are converted, e.g.:

Thank you for going through all of them!

> mtk_iommu_v1_attach_device():
>         /* Only allow the domain created internally. */
>         mtk_mapping = data->mapping;
>         if (mtk_mapping->domain != domain)
>                 return 0;
> ** the current code sounds incorrect which should return an error

I agree.
 
> s390_iommu_attach_device():
>         /* Allow only devices with identical DMA range limits */
>         } else if (domain->geometry.aperture_start != zdev->start_dma ||
>                 domain->geometry.aperture_end != zdev->end_dma) {
>                 rc = -EINVAL;
>
> sprd_iommu_attach_device():
>         if (dom->sdev) {
>                 pr_err("There's already a device attached to this domain.\n");
>                 return -EINVAL;
>         }
> 
> 
> gart_iommu_attach_dev():
>         if (gart->active_domain && gart->active_domain != domain) {
>                 ret = -EBUSY;

Will add these.

> arm_smmu_attach_dev():
>         if (!fwspec || fwspec->ops != &arm_smmu_ops) {
>                 dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
>                 return -ENXIO;
>         }
> **probably this check can be covered by next patch which moves bus ops
> check into iommu core?

I was thinking that it could be covered. Yet, we are about to drop
that ops check, as Robin pointed out that we don't need that ops
sanity for we don't have mixed-driver systems yet. So perhaps this
would be a different ops check and should return -EMEDIUMTYPE too,
I think.

Thanks
Nic

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

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

* Re: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-08 17:38       ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-08 17:38 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

Hi Kevin,

On Wed, Jun 08, 2022 at 07:49:10AM +0000, Tian, Kevin wrote:
> External email: Use caution opening links or attachments
> 
> 
> > From: Nicolin Chen
> > Sent: Monday, June 6, 2022 2:19 PM
> >
> > Cases like VFIO wish to attach a device to an existing domain that was
> > not allocated specifically from the device. This raises a condition
> > where the IOMMU driver can fail the domain attach because the domain and
> > device are incompatible with each other.
> >
> > This is a soft failure that can be resolved by using a different domain.
> >
> > Provide a dedicated errno from the IOMMU driver during attach that the
> > reason attached failed is because of domain incompatability. EMEDIUMTYPE
> > is chosen because it is never used within the iommu subsystem today and
> > evokes a sense that the 'medium' aka the domain is incompatible.
> >
> > VFIO can use this to know attach is a soft failure and it should continue
> > searching. Otherwise the attach will be a hard failure and VFIO will
> > return the code to userspace.
> >
> > Update all drivers to return EMEDIUMTYPE in their failure paths that are
> > related to domain incompatability.
> 
> Seems not all drivers are converted, e.g.:

Thank you for going through all of them!

> mtk_iommu_v1_attach_device():
>         /* Only allow the domain created internally. */
>         mtk_mapping = data->mapping;
>         if (mtk_mapping->domain != domain)
>                 return 0;
> ** the current code sounds incorrect which should return an error

I agree.
 
> s390_iommu_attach_device():
>         /* Allow only devices with identical DMA range limits */
>         } else if (domain->geometry.aperture_start != zdev->start_dma ||
>                 domain->geometry.aperture_end != zdev->end_dma) {
>                 rc = -EINVAL;
>
> sprd_iommu_attach_device():
>         if (dom->sdev) {
>                 pr_err("There's already a device attached to this domain.\n");
>                 return -EINVAL;
>         }
> 
> 
> gart_iommu_attach_dev():
>         if (gart->active_domain && gart->active_domain != domain) {
>                 ret = -EBUSY;

Will add these.

> arm_smmu_attach_dev():
>         if (!fwspec || fwspec->ops != &arm_smmu_ops) {
>                 dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
>                 return -ENXIO;
>         }
> **probably this check can be covered by next patch which moves bus ops
> check into iommu core?

I was thinking that it could be covered. Yet, we are about to drop
that ops check, as Robin pointed out that we don't need that ops
sanity for we don't have mixed-driver systems yet. So perhaps this
would be a different ops check and should return -EMEDIUMTYPE too,
I think.

Thanks
Nic

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

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

* Re: [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group
@ 2022-06-08 17:38       ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-08 17:38 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

Hi Kevin,

On Wed, Jun 08, 2022 at 07:49:10AM +0000, Tian, Kevin wrote:
> External email: Use caution opening links or attachments
> 
> 
> > From: Nicolin Chen
> > Sent: Monday, June 6, 2022 2:19 PM
> >
> > Cases like VFIO wish to attach a device to an existing domain that was
> > not allocated specifically from the device. This raises a condition
> > where the IOMMU driver can fail the domain attach because the domain and
> > device are incompatible with each other.
> >
> > This is a soft failure that can be resolved by using a different domain.
> >
> > Provide a dedicated errno from the IOMMU driver during attach that the
> > reason attached failed is because of domain incompatability. EMEDIUMTYPE
> > is chosen because it is never used within the iommu subsystem today and
> > evokes a sense that the 'medium' aka the domain is incompatible.
> >
> > VFIO can use this to know attach is a soft failure and it should continue
> > searching. Otherwise the attach will be a hard failure and VFIO will
> > return the code to userspace.
> >
> > Update all drivers to return EMEDIUMTYPE in their failure paths that are
> > related to domain incompatability.
> 
> Seems not all drivers are converted, e.g.:

Thank you for going through all of them!

> mtk_iommu_v1_attach_device():
>         /* Only allow the domain created internally. */
>         mtk_mapping = data->mapping;
>         if (mtk_mapping->domain != domain)
>                 return 0;
> ** the current code sounds incorrect which should return an error

I agree.
 
> s390_iommu_attach_device():
>         /* Allow only devices with identical DMA range limits */
>         } else if (domain->geometry.aperture_start != zdev->start_dma ||
>                 domain->geometry.aperture_end != zdev->end_dma) {
>                 rc = -EINVAL;
>
> sprd_iommu_attach_device():
>         if (dom->sdev) {
>                 pr_err("There's already a device attached to this domain.\n");
>                 return -EINVAL;
>         }
> 
> 
> gart_iommu_attach_dev():
>         if (gart->active_domain && gart->active_domain != domain) {
>                 ret = -EBUSY;

Will add these.

> arm_smmu_attach_dev():
>         if (!fwspec || fwspec->ops != &arm_smmu_ops) {
>                 dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
>                 return -ENXIO;
>         }
> **probably this check can be covered by next patch which moves bus ops
> check into iommu core?

I was thinking that it could be covered. Yet, we are about to drop
that ops check, as Robin pointed out that we don't need that ops
sanity for we don't have mixed-driver systems yet. So perhaps this
would be a different ops check and should return -EMEDIUMTYPE too,
I think.

Thanks
Nic

_______________________________________________
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] 138+ messages in thread

* Re: [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
  2022-06-08  8:35     ` Tian, Kevin
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-08 17:46       ` Nicolin Chen via iommu
  -1 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-08 17:46 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

On Wed, Jun 08, 2022 at 08:35:47AM +0000, Tian, Kevin wrote:

> > @@ -2519,7 +2515,17 @@ static void vfio_iommu_type1_detach_group(void
> > *iommu_data,
> >                       kfree(domain);
> >                       vfio_iommu_aper_expand(iommu, &iova_copy);
> >                       vfio_update_pgsize_bitmap(iommu);
> > +                     /*
> > +                      * Removal of a group without dirty tracking may
> > allow
> > +                      * the iommu scope to be promoted.
> > +                      */
> > +                     if (!group->pinned_page_dirty_scope) {
> > +                             iommu->num_non_pinned_groups--;
> > +                             if (iommu->dirty_page_tracking)
> > +
> >       vfio_iommu_populate_bitmap_full(iommu);
> 
> This doesn't look correct. The old code decrements
> num_non_pinned_groups for every detach group without dirty
> tracking. But now it's only done when the domain is about to
> be released...

Hmm..you are right. It should be placed outside:
		if (list_empty(&domain->group_list)) {
			...
		}
+		if (!group->pinned_page_dirty_scope) {
+			...
+		}

Will fix this and the same problem in PATCH-5 too.

Thanks!

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

* Re: [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
@ 2022-06-08 17:46       ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen via iommu @ 2022-06-08 17:46 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: cohuck, heiko, kvm, linux-tegra, thierry.reding, alim.akhtar,
	will, alyssa, jean-philippe, linux-samsung-soc, samuel,
	zhang.lyra, jernej.skrabec, jonathanh, linux-rockchip, wens,
	agross, jgg, orsonzhai, gerald.schaefer, linux-sunxi,
	linux-arm-msm, alex.williamson, iommu, linux-mediatek,
	matthias.bgg, virtualization, linux-arm-kernel, linux-s390,
	marcan, linux-kernel, krzysztof.kozlowski, baolin.wang7, dwmw2,
	robin.murphy

On Wed, Jun 08, 2022 at 08:35:47AM +0000, Tian, Kevin wrote:

> > @@ -2519,7 +2515,17 @@ static void vfio_iommu_type1_detach_group(void
> > *iommu_data,
> >                       kfree(domain);
> >                       vfio_iommu_aper_expand(iommu, &iova_copy);
> >                       vfio_update_pgsize_bitmap(iommu);
> > +                     /*
> > +                      * Removal of a group without dirty tracking may
> > allow
> > +                      * the iommu scope to be promoted.
> > +                      */
> > +                     if (!group->pinned_page_dirty_scope) {
> > +                             iommu->num_non_pinned_groups--;
> > +                             if (iommu->dirty_page_tracking)
> > +
> >       vfio_iommu_populate_bitmap_full(iommu);
> 
> This doesn't look correct. The old code decrements
> num_non_pinned_groups for every detach group without dirty
> tracking. But now it's only done when the domain is about to
> be released...

Hmm..you are right. It should be placed outside:
		if (list_empty(&domain->group_list)) {
			...
		}
+		if (!group->pinned_page_dirty_scope) {
+			...
+		}

Will fix this and the same problem in PATCH-5 too.

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

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

* Re: [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
@ 2022-06-08 17:46       ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-08 17:46 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

On Wed, Jun 08, 2022 at 08:35:47AM +0000, Tian, Kevin wrote:

> > @@ -2519,7 +2515,17 @@ static void vfio_iommu_type1_detach_group(void
> > *iommu_data,
> >                       kfree(domain);
> >                       vfio_iommu_aper_expand(iommu, &iova_copy);
> >                       vfio_update_pgsize_bitmap(iommu);
> > +                     /*
> > +                      * Removal of a group without dirty tracking may
> > allow
> > +                      * the iommu scope to be promoted.
> > +                      */
> > +                     if (!group->pinned_page_dirty_scope) {
> > +                             iommu->num_non_pinned_groups--;
> > +                             if (iommu->dirty_page_tracking)
> > +
> >       vfio_iommu_populate_bitmap_full(iommu);
> 
> This doesn't look correct. The old code decrements
> num_non_pinned_groups for every detach group without dirty
> tracking. But now it's only done when the domain is about to
> be released...

Hmm..you are right. It should be placed outside:
		if (list_empty(&domain->group_list)) {
			...
		}
+		if (!group->pinned_page_dirty_scope) {
+			...
+		}

Will fix this and the same problem in PATCH-5 too.

Thanks!

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

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

* Re: [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
@ 2022-06-08 17:46       ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-08 17:46 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

On Wed, Jun 08, 2022 at 08:35:47AM +0000, Tian, Kevin wrote:

> > @@ -2519,7 +2515,17 @@ static void vfio_iommu_type1_detach_group(void
> > *iommu_data,
> >                       kfree(domain);
> >                       vfio_iommu_aper_expand(iommu, &iova_copy);
> >                       vfio_update_pgsize_bitmap(iommu);
> > +                     /*
> > +                      * Removal of a group without dirty tracking may
> > allow
> > +                      * the iommu scope to be promoted.
> > +                      */
> > +                     if (!group->pinned_page_dirty_scope) {
> > +                             iommu->num_non_pinned_groups--;
> > +                             if (iommu->dirty_page_tracking)
> > +
> >       vfio_iommu_populate_bitmap_full(iommu);
> 
> This doesn't look correct. The old code decrements
> num_non_pinned_groups for every detach group without dirty
> tracking. But now it's only done when the domain is about to
> be released...

Hmm..you are right. It should be placed outside:
		if (list_empty(&domain->group_list)) {
			...
		}
+		if (!group->pinned_page_dirty_scope) {
+			...
+		}

Will fix this and the same problem in PATCH-5 too.

Thanks!

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

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

* Re: [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group()
@ 2022-06-08 17:46       ` Nicolin Chen via iommu
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-08 17:46 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: jgg, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

On Wed, Jun 08, 2022 at 08:35:47AM +0000, Tian, Kevin wrote:

> > @@ -2519,7 +2515,17 @@ static void vfio_iommu_type1_detach_group(void
> > *iommu_data,
> >                       kfree(domain);
> >                       vfio_iommu_aper_expand(iommu, &iova_copy);
> >                       vfio_update_pgsize_bitmap(iommu);
> > +                     /*
> > +                      * Removal of a group without dirty tracking may
> > allow
> > +                      * the iommu scope to be promoted.
> > +                      */
> > +                     if (!group->pinned_page_dirty_scope) {
> > +                             iommu->num_non_pinned_groups--;
> > +                             if (iommu->dirty_page_tracking)
> > +
> >       vfio_iommu_populate_bitmap_full(iommu);
> 
> This doesn't look correct. The old code decrements
> num_non_pinned_groups for every detach group without dirty
> tracking. But now it's only done when the domain is about to
> be released...

Hmm..you are right. It should be placed outside:
		if (list_empty(&domain->group_list)) {
			...
		}
+		if (!group->pinned_page_dirty_scope) {
+			...
+		}

Will fix this and the same problem in PATCH-5 too.

Thanks!

_______________________________________________
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] 138+ messages in thread

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
  2022-06-08 11:17       ` Jason Gunthorpe
                           ` (3 preceding siblings ...)
  (?)
@ 2022-06-08 23:48         ` Tian, Kevin
  -1 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08 23:48 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Nicolin Chen, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

> From: Jason Gunthorpe <jgg@nvidia.com>
> Sent: Wednesday, June 8, 2022 7:17 PM
> 
> On Wed, Jun 08, 2022 at 08:28:03AM +0000, Tian, Kevin wrote:
> > > From: Nicolin Chen
> > > Sent: Monday, June 6, 2022 2:19 PM
> > >
> > > From: Jason Gunthorpe <jgg@nvidia.com>
> > >
> > > The KVM mechanism for controlling wbinvd is only triggered during
> > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> devices
> > > are setup.
> >
> > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > group_add() and group_del(). Then the coherency property is
> > checked dynamically in wbinvd emulation:
> 
> From the perspective of managing the domains that is still
> one-shot. It doesn't get updated when individual devices are
> added/removed to domains.

It's unchanged per-domain but dynamic per-vm when multiple
domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
It's the latter being checked in the kvm.

> 
> > given that I'm fine with the change in this patch. Even more probably
> > we really want an explicit one-shot model so KVM can lock down
> > the property once it starts to consume it then further adding a new
> > group which would change the coherency is explicitly rejected and
> > removing an existing group leaves it intact.
> 
> Why? Once wbinvd is enabled it is compatible with all domain
> configurations, so just leave it on and ignore everything at that
> point.
> 

More than that. My point was to make it a static policy so even if
wbinvd is disabled in the start we want to leave it off and not affected
by adding a device which doesn't have coherency. 'wbinvd off' is not
a compatible configuration hence imo need a way to reject adding
incompatible device.

Thanks
Kevin

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

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-08 23:48         ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08 23:48 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Nicolin Chen, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

> From: Jason Gunthorpe <jgg@nvidia.com>
> Sent: Wednesday, June 8, 2022 7:17 PM
> 
> On Wed, Jun 08, 2022 at 08:28:03AM +0000, Tian, Kevin wrote:
> > > From: Nicolin Chen
> > > Sent: Monday, June 6, 2022 2:19 PM
> > >
> > > From: Jason Gunthorpe <jgg@nvidia.com>
> > >
> > > The KVM mechanism for controlling wbinvd is only triggered during
> > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> devices
> > > are setup.
> >
> > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > group_add() and group_del(). Then the coherency property is
> > checked dynamically in wbinvd emulation:
> 
> From the perspective of managing the domains that is still
> one-shot. It doesn't get updated when individual devices are
> added/removed to domains.

It's unchanged per-domain but dynamic per-vm when multiple
domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
It's the latter being checked in the kvm.

> 
> > given that I'm fine with the change in this patch. Even more probably
> > we really want an explicit one-shot model so KVM can lock down
> > the property once it starts to consume it then further adding a new
> > group which would change the coherency is explicitly rejected and
> > removing an existing group leaves it intact.
> 
> Why? Once wbinvd is enabled it is compatible with all domain
> configurations, so just leave it on and ignore everything at that
> point.
> 

More than that. My point was to make it a static policy so even if
wbinvd is disabled in the start we want to leave it off and not affected
by adding a device which doesn't have coherency. 'wbinvd off' is not
a compatible configuration hence imo need a way to reject adding
incompatible device.

Thanks
Kevin

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

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

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-08 23:48         ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08 23:48 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Nicolin Chen, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

> From: Jason Gunthorpe <jgg@nvidia.com>
> Sent: Wednesday, June 8, 2022 7:17 PM
> 
> On Wed, Jun 08, 2022 at 08:28:03AM +0000, Tian, Kevin wrote:
> > > From: Nicolin Chen
> > > Sent: Monday, June 6, 2022 2:19 PM
> > >
> > > From: Jason Gunthorpe <jgg@nvidia.com>
> > >
> > > The KVM mechanism for controlling wbinvd is only triggered during
> > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> devices
> > > are setup.
> >
> > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > group_add() and group_del(). Then the coherency property is
> > checked dynamically in wbinvd emulation:
> 
> From the perspective of managing the domains that is still
> one-shot. It doesn't get updated when individual devices are
> added/removed to domains.

It's unchanged per-domain but dynamic per-vm when multiple
domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
It's the latter being checked in the kvm.

> 
> > given that I'm fine with the change in this patch. Even more probably
> > we really want an explicit one-shot model so KVM can lock down
> > the property once it starts to consume it then further adding a new
> > group which would change the coherency is explicitly rejected and
> > removing an existing group leaves it intact.
> 
> Why? Once wbinvd is enabled it is compatible with all domain
> configurations, so just leave it on and ignore everything at that
> point.
> 

More than that. My point was to make it a static policy so even if
wbinvd is disabled in the start we want to leave it off and not affected
by adding a device which doesn't have coherency. 'wbinvd off' is not
a compatible configuration hence imo need a way to reject adding
incompatible device.

Thanks
Kevin

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

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

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-08 23:48         ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08 23:48 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: cohuck, heiko, kvm, linux-tegra, thierry.reding, alim.akhtar,
	will, alyssa, jean-philippe, linux-samsung-soc, samuel,
	zhang.lyra, jernej.skrabec, jonathanh, linux-rockchip, wens,
	agross, orsonzhai, gerald.schaefer, linux-sunxi, linux-arm-msm,
	alex.williamson, iommu, linux-mediatek, matthias.bgg,
	virtualization, linux-arm-kernel, linux-s390, marcan,
	linux-kernel, krzysztof.kozlowski, baolin.wang7, dwmw2,
	robin.murphy

> From: Jason Gunthorpe <jgg@nvidia.com>
> Sent: Wednesday, June 8, 2022 7:17 PM
> 
> On Wed, Jun 08, 2022 at 08:28:03AM +0000, Tian, Kevin wrote:
> > > From: Nicolin Chen
> > > Sent: Monday, June 6, 2022 2:19 PM
> > >
> > > From: Jason Gunthorpe <jgg@nvidia.com>
> > >
> > > The KVM mechanism for controlling wbinvd is only triggered during
> > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> devices
> > > are setup.
> >
> > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > group_add() and group_del(). Then the coherency property is
> > checked dynamically in wbinvd emulation:
> 
> From the perspective of managing the domains that is still
> one-shot. It doesn't get updated when individual devices are
> added/removed to domains.

It's unchanged per-domain but dynamic per-vm when multiple
domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
It's the latter being checked in the kvm.

> 
> > given that I'm fine with the change in this patch. Even more probably
> > we really want an explicit one-shot model so KVM can lock down
> > the property once it starts to consume it then further adding a new
> > group which would change the coherency is explicitly rejected and
> > removing an existing group leaves it intact.
> 
> Why? Once wbinvd is enabled it is compatible with all domain
> configurations, so just leave it on and ignore everything at that
> point.
> 

More than that. My point was to make it a static policy so even if
wbinvd is disabled in the start we want to leave it off and not affected
by adding a device which doesn't have coherency. 'wbinvd off' is not
a compatible configuration hence imo need a way to reject adding
incompatible device.

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

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

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-08 23:48         ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08 23:48 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: cohuck, heiko, kvm, bjorn.andersson, linux-tegra, thierry.reding,
	alim.akhtar, will, alyssa, m.szyprowski, jean-philippe,
	linux-samsung-soc, samuel, zhang.lyra, joro, robdclark,
	jernej.skrabec, jonathanh, linux-rockchip, wens, agross,
	Nicolin Chen, orsonzhai, gerald.schaefer, linux-sunxi, sven,
	linux-arm-msm, iommu, linux-mediatek, matthias.bgg,
	virtualization, linux-arm-kernel, linux-s390, marcan,
	linux-kernel, krzysztof.kozlowski, baolin.wang7, dwmw2,
	robin.murphy, baolu.lu

> From: Jason Gunthorpe <jgg@nvidia.com>
> Sent: Wednesday, June 8, 2022 7:17 PM
> 
> On Wed, Jun 08, 2022 at 08:28:03AM +0000, Tian, Kevin wrote:
> > > From: Nicolin Chen
> > > Sent: Monday, June 6, 2022 2:19 PM
> > >
> > > From: Jason Gunthorpe <jgg@nvidia.com>
> > >
> > > The KVM mechanism for controlling wbinvd is only triggered during
> > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> devices
> > > are setup.
> >
> > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > group_add() and group_del(). Then the coherency property is
> > checked dynamically in wbinvd emulation:
> 
> From the perspective of managing the domains that is still
> one-shot. It doesn't get updated when individual devices are
> added/removed to domains.

It's unchanged per-domain but dynamic per-vm when multiple
domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
It's the latter being checked in the kvm.

> 
> > given that I'm fine with the change in this patch. Even more probably
> > we really want an explicit one-shot model so KVM can lock down
> > the property once it starts to consume it then further adding a new
> > group which would change the coherency is explicitly rejected and
> > removing an existing group leaves it intact.
> 
> Why? Once wbinvd is enabled it is compatible with all domain
> configurations, so just leave it on and ignore everything at that
> point.
> 

More than that. My point was to make it a static policy so even if
wbinvd is disabled in the start we want to leave it off and not affected
by adding a device which doesn't have coherency. 'wbinvd off' is not
a compatible configuration hence imo need a way to reject adding
incompatible device.

Thanks
Kevin
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

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

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-08 23:48         ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-08 23:48 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Nicolin Chen, joro, will, marcan, sven, robin.murphy, robdclark,
	m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

> From: Jason Gunthorpe <jgg@nvidia.com>
> Sent: Wednesday, June 8, 2022 7:17 PM
> 
> On Wed, Jun 08, 2022 at 08:28:03AM +0000, Tian, Kevin wrote:
> > > From: Nicolin Chen
> > > Sent: Monday, June 6, 2022 2:19 PM
> > >
> > > From: Jason Gunthorpe <jgg@nvidia.com>
> > >
> > > The KVM mechanism for controlling wbinvd is only triggered during
> > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> devices
> > > are setup.
> >
> > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > group_add() and group_del(). Then the coherency property is
> > checked dynamically in wbinvd emulation:
> 
> From the perspective of managing the domains that is still
> one-shot. It doesn't get updated when individual devices are
> added/removed to domains.

It's unchanged per-domain but dynamic per-vm when multiple
domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
It's the latter being checked in the kvm.

> 
> > given that I'm fine with the change in this patch. Even more probably
> > we really want an explicit one-shot model so KVM can lock down
> > the property once it starts to consume it then further adding a new
> > group which would change the coherency is explicitly rejected and
> > removing an existing group leaves it intact.
> 
> Why? Once wbinvd is enabled it is compatible with all domain
> configurations, so just leave it on and ignore everything at that
> point.
> 

More than that. My point was to make it a static policy so even if
wbinvd is disabled in the start we want to leave it off and not affected
by adding a device which doesn't have coherency. 'wbinvd off' is not
a compatible configuration hence imo need a way to reject adding
incompatible device.

Thanks
Kevin

_______________________________________________
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] 138+ messages in thread

* Re: [PATCH 5/5] vfio/iommu_type1: Simplify group attachment
  2022-06-06  6:19   ` Nicolin Chen via iommu
@ 2022-06-13 13:42 ` Dan Carpenter
  -1 siblings, 0 replies; 138+ messages in thread
From: kernel test robot @ 2022-06-10 16:39 UTC (permalink / raw)
  To: kbuild

[-- Attachment #1: Type: text/plain, Size: 8261 bytes --]

CC: kbuild-all(a)lists.01.org
BCC: lkp(a)intel.com
In-Reply-To: <20220606061927.26049-6-nicolinc@nvidia.com>
References: <20220606061927.26049-6-nicolinc@nvidia.com>
TO: Nicolin Chen <nicolinc@nvidia.com>
TO: jgg(a)nvidia.com
TO: joro(a)8bytes.org
TO: will(a)kernel.org
TO: marcan(a)marcan.st
TO: sven(a)svenpeter.dev
TO: robin.murphy(a)arm.com
TO: robdclark(a)gmail.com
TO: m.szyprowski(a)samsung.com
TO: krzysztof.kozlowski(a)linaro.org
TO: baolu.lu(a)linux.intel.com
TO: agross(a)kernel.org
TO: bjorn.andersson(a)linaro.org
TO: matthias.bgg(a)gmail.com
TO: heiko(a)sntech.de
TO: orsonzhai(a)gmail.com
TO: baolin.wang7(a)gmail.com
TO: zhang.lyra(a)gmail.com
TO: wens(a)csie.org
TO: jernej.skrabec(a)gmail.com
TO: samuel(a)sholland.org
TO: jean-philippe(a)linaro.org
TO: alex.williamson(a)redhat.com
CC: suravee.suthikulpanit(a)amd.com
CC: alyssa(a)rosenzweig.io
CC: alim.akhtar(a)samsung.com
CC: dwmw2(a)infradead.org
CC: yong.wu(a)mediatek.com
CC: mjrosato(a)linux.ibm.com
CC: gerald.schaefer(a)linux.ibm.com
CC: thierry.reding(a)gmail.com

Hi Nicolin,

I love your patch! Perhaps something to improve:

[auto build test WARNING on joro-iommu/next]
[also build test WARNING on tegra/for-next v5.19-rc1 next-20220610]
[cannot apply to awilliam-vfio/next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Nicolin-Chen/Simplify-vfio_iommu_type1-attach-detach-routine/20220606-143004
base:   https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next
:::::: branch date: 4 days ago
:::::: commit date: 4 days ago
config: i386-randconfig-m021 (https://download.01.org/0day-ci/archive/20220611/202206110041.8CaoeVuj-lkp(a)intel.com/config)
compiler: gcc-11 (Debian 11.3.0-3) 11.3.0

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

smatch warnings:
drivers/vfio/vfio_iommu_type1.c:2229 vfio_iommu_alloc_attach_domain() error: we previously assumed 'domain' could be null (see line 2191)
drivers/vfio/vfio_iommu_type1.c:2229 vfio_iommu_alloc_attach_domain() error: dereferencing freed memory 'domain'

vim +/domain +2229 drivers/vfio/vfio_iommu_type1.c

572f64c71e0fe3 Zenghui Yu   2020-10-22  2156  
c1a4076891cf18 Nicolin Chen 2022-06-05  2157  static struct vfio_domain *
c1a4076891cf18 Nicolin Chen 2022-06-05  2158  vfio_iommu_alloc_attach_domain(struct bus_type *bus, struct vfio_iommu *iommu,
c1a4076891cf18 Nicolin Chen 2022-06-05  2159  			       struct vfio_iommu_group *group)
c1a4076891cf18 Nicolin Chen 2022-06-05  2160  {
c1a4076891cf18 Nicolin Chen 2022-06-05  2161  	struct iommu_domain *new_domain;
c1a4076891cf18 Nicolin Chen 2022-06-05  2162  	struct vfio_domain *domain;
c1a4076891cf18 Nicolin Chen 2022-06-05  2163  	int ret = 0;
c1a4076891cf18 Nicolin Chen 2022-06-05  2164  
c1a4076891cf18 Nicolin Chen 2022-06-05  2165  	/* Try to match an existing compatible domain */
c1a4076891cf18 Nicolin Chen 2022-06-05  2166  	list_for_each_entry (domain, &iommu->domain_list, next) {
c1a4076891cf18 Nicolin Chen 2022-06-05  2167  		ret = iommu_attach_group(domain->domain, group->iommu_group);
c1a4076891cf18 Nicolin Chen 2022-06-05  2168  		if (ret == -EMEDIUMTYPE)
c1a4076891cf18 Nicolin Chen 2022-06-05  2169  			continue;
c1a4076891cf18 Nicolin Chen 2022-06-05  2170  		if (ret)
c1a4076891cf18 Nicolin Chen 2022-06-05  2171  			return ERR_PTR(ret);
c1a4076891cf18 Nicolin Chen 2022-06-05  2172  		list_add(&group->next, &domain->group_list);
c1a4076891cf18 Nicolin Chen 2022-06-05  2173  		return domain;
c1a4076891cf18 Nicolin Chen 2022-06-05  2174  	}
c1a4076891cf18 Nicolin Chen 2022-06-05  2175  
c1a4076891cf18 Nicolin Chen 2022-06-05  2176  	new_domain = iommu_domain_alloc(bus);
c1a4076891cf18 Nicolin Chen 2022-06-05  2177  	if (!new_domain)
c1a4076891cf18 Nicolin Chen 2022-06-05  2178  		return ERR_PTR(-EIO);
c1a4076891cf18 Nicolin Chen 2022-06-05  2179  
c1a4076891cf18 Nicolin Chen 2022-06-05  2180  	if (iommu->nesting) {
c1a4076891cf18 Nicolin Chen 2022-06-05  2181  		ret = iommu_enable_nesting(new_domain);
c1a4076891cf18 Nicolin Chen 2022-06-05  2182  		if (ret)
c1a4076891cf18 Nicolin Chen 2022-06-05  2183  			goto out_free_iommu_domain;
c1a4076891cf18 Nicolin Chen 2022-06-05  2184  	}
c1a4076891cf18 Nicolin Chen 2022-06-05  2185  
c1a4076891cf18 Nicolin Chen 2022-06-05  2186  	ret = iommu_attach_group(new_domain, group->iommu_group);
c1a4076891cf18 Nicolin Chen 2022-06-05  2187  	if (ret)
c1a4076891cf18 Nicolin Chen 2022-06-05  2188  		goto out_free_iommu_domain;
c1a4076891cf18 Nicolin Chen 2022-06-05  2189  
c1a4076891cf18 Nicolin Chen 2022-06-05  2190  	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
c1a4076891cf18 Nicolin Chen 2022-06-05 @2191  	if (!domain) {
c1a4076891cf18 Nicolin Chen 2022-06-05  2192  		ret = -ENOMEM;
c1a4076891cf18 Nicolin Chen 2022-06-05  2193  		goto out_detach;
c1a4076891cf18 Nicolin Chen 2022-06-05  2194  	}
c1a4076891cf18 Nicolin Chen 2022-06-05  2195  
c1a4076891cf18 Nicolin Chen 2022-06-05  2196  	domain->domain = new_domain;
c1a4076891cf18 Nicolin Chen 2022-06-05  2197  	vfio_test_domain_fgsp(domain);
c1a4076891cf18 Nicolin Chen 2022-06-05  2198  
c1a4076891cf18 Nicolin Chen 2022-06-05  2199  	/*
c1a4076891cf18 Nicolin Chen 2022-06-05  2200  	 * If the IOMMU can block non-coherent operations (ie PCIe TLPs with
c1a4076891cf18 Nicolin Chen 2022-06-05  2201  	 * no-snoop set) then VFIO always turns this feature on because on Intel
c1a4076891cf18 Nicolin Chen 2022-06-05  2202  	 * platforms it optimizes KVM to disable wbinvd emulation.
c1a4076891cf18 Nicolin Chen 2022-06-05  2203  	 */
c1a4076891cf18 Nicolin Chen 2022-06-05  2204  	if (new_domain->ops->enforce_cache_coherency)
c1a4076891cf18 Nicolin Chen 2022-06-05  2205  		domain->enforce_cache_coherency =
c1a4076891cf18 Nicolin Chen 2022-06-05  2206  			new_domain->ops->enforce_cache_coherency(new_domain);
c1a4076891cf18 Nicolin Chen 2022-06-05  2207  
c1a4076891cf18 Nicolin Chen 2022-06-05  2208  	/* replay mappings on new domains */
c1a4076891cf18 Nicolin Chen 2022-06-05  2209  	ret = vfio_iommu_replay(iommu, domain);
c1a4076891cf18 Nicolin Chen 2022-06-05  2210  	if (ret)
c1a4076891cf18 Nicolin Chen 2022-06-05  2211  		goto out_free_domain;
c1a4076891cf18 Nicolin Chen 2022-06-05  2212  
c1a4076891cf18 Nicolin Chen 2022-06-05  2213  	/*
c1a4076891cf18 Nicolin Chen 2022-06-05  2214  	 * An iommu backed group can dirty memory directly and therefore
c1a4076891cf18 Nicolin Chen 2022-06-05  2215  	 * demotes the iommu scope until it declares itself dirty tracking
c1a4076891cf18 Nicolin Chen 2022-06-05  2216  	 * capable via the page pinning interface.
c1a4076891cf18 Nicolin Chen 2022-06-05  2217  	 */
c1a4076891cf18 Nicolin Chen 2022-06-05  2218  	iommu->num_non_pinned_groups++;
c1a4076891cf18 Nicolin Chen 2022-06-05  2219  
c1a4076891cf18 Nicolin Chen 2022-06-05  2220  	INIT_LIST_HEAD(&domain->group_list);
c1a4076891cf18 Nicolin Chen 2022-06-05  2221  	list_add(&group->next, &domain->group_list);
c1a4076891cf18 Nicolin Chen 2022-06-05  2222  	list_add(&domain->next, &iommu->domain_list);
c1a4076891cf18 Nicolin Chen 2022-06-05  2223  	vfio_update_pgsize_bitmap(iommu);
c1a4076891cf18 Nicolin Chen 2022-06-05  2224  	return domain;
c1a4076891cf18 Nicolin Chen 2022-06-05  2225  
c1a4076891cf18 Nicolin Chen 2022-06-05  2226  out_free_domain:
c1a4076891cf18 Nicolin Chen 2022-06-05  2227  	kfree(domain);
c1a4076891cf18 Nicolin Chen 2022-06-05  2228  out_detach:
c1a4076891cf18 Nicolin Chen 2022-06-05 @2229  	iommu_detach_group(domain->domain, group->iommu_group);
c1a4076891cf18 Nicolin Chen 2022-06-05  2230  out_free_iommu_domain:
c1a4076891cf18 Nicolin Chen 2022-06-05  2231  	iommu_domain_free(new_domain);
c1a4076891cf18 Nicolin Chen 2022-06-05  2232  	return ERR_PTR(ret);
c1a4076891cf18 Nicolin Chen 2022-06-05  2233  }
c1a4076891cf18 Nicolin Chen 2022-06-05  2234  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

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

* Re: [PATCH 5/5] vfio/iommu_type1: Simplify group attachment
@ 2022-06-13 13:42 ` Dan Carpenter
  0 siblings, 0 replies; 138+ messages in thread
From: Dan Carpenter @ 2022-06-13 13:42 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 6859 bytes --]

Hi Nicolin,

url:    https://github.com/intel-lab-lkp/linux/commits/Nicolin-Chen/Simplify-vfio_iommu_type1-attach-detach-routine/20220606-143004
base:   https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next
config: i386-randconfig-m021 (https://download.01.org/0day-ci/archive/20220611/202206110041.8CaoeVuj-lkp(a)intel.com/config)
compiler: gcc-11 (Debian 11.3.0-3) 11.3.0

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

smatch warnings:
drivers/vfio/vfio_iommu_type1.c:2229 vfio_iommu_alloc_attach_domain() error: we previously assumed 'domain' could be null (see line 2191)
drivers/vfio/vfio_iommu_type1.c:2229 vfio_iommu_alloc_attach_domain() error: dereferencing freed memory 'domain'

vim +/domain +2229 drivers/vfio/vfio_iommu_type1.c

c1a4076891cf18 Nicolin Chen 2022-06-05  2157  static struct vfio_domain *
c1a4076891cf18 Nicolin Chen 2022-06-05  2158  vfio_iommu_alloc_attach_domain(struct bus_type *bus, struct vfio_iommu *iommu,
c1a4076891cf18 Nicolin Chen 2022-06-05  2159  			       struct vfio_iommu_group *group)
c1a4076891cf18 Nicolin Chen 2022-06-05  2160  {
c1a4076891cf18 Nicolin Chen 2022-06-05  2161  	struct iommu_domain *new_domain;
c1a4076891cf18 Nicolin Chen 2022-06-05  2162  	struct vfio_domain *domain;
c1a4076891cf18 Nicolin Chen 2022-06-05  2163  	int ret = 0;
c1a4076891cf18 Nicolin Chen 2022-06-05  2164  
c1a4076891cf18 Nicolin Chen 2022-06-05  2165  	/* Try to match an existing compatible domain */
c1a4076891cf18 Nicolin Chen 2022-06-05  2166  	list_for_each_entry (domain, &iommu->domain_list, next) {
c1a4076891cf18 Nicolin Chen 2022-06-05  2167  		ret = iommu_attach_group(domain->domain, group->iommu_group);
c1a4076891cf18 Nicolin Chen 2022-06-05  2168  		if (ret == -EMEDIUMTYPE)
c1a4076891cf18 Nicolin Chen 2022-06-05  2169  			continue;
c1a4076891cf18 Nicolin Chen 2022-06-05  2170  		if (ret)
c1a4076891cf18 Nicolin Chen 2022-06-05  2171  			return ERR_PTR(ret);
c1a4076891cf18 Nicolin Chen 2022-06-05  2172  		list_add(&group->next, &domain->group_list);
c1a4076891cf18 Nicolin Chen 2022-06-05  2173  		return domain;
c1a4076891cf18 Nicolin Chen 2022-06-05  2174  	}
c1a4076891cf18 Nicolin Chen 2022-06-05  2175  
c1a4076891cf18 Nicolin Chen 2022-06-05  2176  	new_domain = iommu_domain_alloc(bus);
c1a4076891cf18 Nicolin Chen 2022-06-05  2177  	if (!new_domain)
c1a4076891cf18 Nicolin Chen 2022-06-05  2178  		return ERR_PTR(-EIO);
c1a4076891cf18 Nicolin Chen 2022-06-05  2179  
c1a4076891cf18 Nicolin Chen 2022-06-05  2180  	if (iommu->nesting) {
c1a4076891cf18 Nicolin Chen 2022-06-05  2181  		ret = iommu_enable_nesting(new_domain);
c1a4076891cf18 Nicolin Chen 2022-06-05  2182  		if (ret)
c1a4076891cf18 Nicolin Chen 2022-06-05  2183  			goto out_free_iommu_domain;
c1a4076891cf18 Nicolin Chen 2022-06-05  2184  	}
c1a4076891cf18 Nicolin Chen 2022-06-05  2185  
c1a4076891cf18 Nicolin Chen 2022-06-05  2186  	ret = iommu_attach_group(new_domain, group->iommu_group);
c1a4076891cf18 Nicolin Chen 2022-06-05  2187  	if (ret)
c1a4076891cf18 Nicolin Chen 2022-06-05  2188  		goto out_free_iommu_domain;
c1a4076891cf18 Nicolin Chen 2022-06-05  2189  
c1a4076891cf18 Nicolin Chen 2022-06-05  2190  	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
c1a4076891cf18 Nicolin Chen 2022-06-05 @2191  	if (!domain) {
                                                     ^^^^^^
NULL

c1a4076891cf18 Nicolin Chen 2022-06-05  2192  		ret = -ENOMEM;
c1a4076891cf18 Nicolin Chen 2022-06-05  2193  		goto out_detach;
c1a4076891cf18 Nicolin Chen 2022-06-05  2194  	}
c1a4076891cf18 Nicolin Chen 2022-06-05  2195  
c1a4076891cf18 Nicolin Chen 2022-06-05  2196  	domain->domain = new_domain;
c1a4076891cf18 Nicolin Chen 2022-06-05  2197  	vfio_test_domain_fgsp(domain);
c1a4076891cf18 Nicolin Chen 2022-06-05  2198  
c1a4076891cf18 Nicolin Chen 2022-06-05  2199  	/*
c1a4076891cf18 Nicolin Chen 2022-06-05  2200  	 * If the IOMMU can block non-coherent operations (ie PCIe TLPs with
c1a4076891cf18 Nicolin Chen 2022-06-05  2201  	 * no-snoop set) then VFIO always turns this feature on because on Intel
c1a4076891cf18 Nicolin Chen 2022-06-05  2202  	 * platforms it optimizes KVM to disable wbinvd emulation.
c1a4076891cf18 Nicolin Chen 2022-06-05  2203  	 */
c1a4076891cf18 Nicolin Chen 2022-06-05  2204  	if (new_domain->ops->enforce_cache_coherency)
c1a4076891cf18 Nicolin Chen 2022-06-05  2205  		domain->enforce_cache_coherency =
c1a4076891cf18 Nicolin Chen 2022-06-05  2206  			new_domain->ops->enforce_cache_coherency(new_domain);
c1a4076891cf18 Nicolin Chen 2022-06-05  2207  
c1a4076891cf18 Nicolin Chen 2022-06-05  2208  	/* replay mappings on new domains */
c1a4076891cf18 Nicolin Chen 2022-06-05  2209  	ret = vfio_iommu_replay(iommu, domain);
c1a4076891cf18 Nicolin Chen 2022-06-05  2210  	if (ret)
c1a4076891cf18 Nicolin Chen 2022-06-05  2211  		goto out_free_domain;
c1a4076891cf18 Nicolin Chen 2022-06-05  2212  
c1a4076891cf18 Nicolin Chen 2022-06-05  2213  	/*
c1a4076891cf18 Nicolin Chen 2022-06-05  2214  	 * An iommu backed group can dirty memory directly and therefore
c1a4076891cf18 Nicolin Chen 2022-06-05  2215  	 * demotes the iommu scope until it declares itself dirty tracking
c1a4076891cf18 Nicolin Chen 2022-06-05  2216  	 * capable via the page pinning interface.
c1a4076891cf18 Nicolin Chen 2022-06-05  2217  	 */
c1a4076891cf18 Nicolin Chen 2022-06-05  2218  	iommu->num_non_pinned_groups++;
c1a4076891cf18 Nicolin Chen 2022-06-05  2219  
c1a4076891cf18 Nicolin Chen 2022-06-05  2220  	INIT_LIST_HEAD(&domain->group_list);
c1a4076891cf18 Nicolin Chen 2022-06-05  2221  	list_add(&group->next, &domain->group_list);
c1a4076891cf18 Nicolin Chen 2022-06-05  2222  	list_add(&domain->next, &iommu->domain_list);
c1a4076891cf18 Nicolin Chen 2022-06-05  2223  	vfio_update_pgsize_bitmap(iommu);
c1a4076891cf18 Nicolin Chen 2022-06-05  2224  	return domain;
c1a4076891cf18 Nicolin Chen 2022-06-05  2225  
c1a4076891cf18 Nicolin Chen 2022-06-05  2226  out_free_domain:
c1a4076891cf18 Nicolin Chen 2022-06-05  2227  	kfree(domain);
                                                      ^^^^^^
Freed

c1a4076891cf18 Nicolin Chen 2022-06-05  2228  out_detach:
c1a4076891cf18 Nicolin Chen 2022-06-05 @2229  	iommu_detach_group(domain->domain, group->iommu_group);
                                                                   ^^^^^^^^^^^^^^
Boom!

c1a4076891cf18 Nicolin Chen 2022-06-05  2230  out_free_iommu_domain:
c1a4076891cf18 Nicolin Chen 2022-06-05  2231  	iommu_domain_free(new_domain);
c1a4076891cf18 Nicolin Chen 2022-06-05  2232  	return ERR_PTR(ret);
c1a4076891cf18 Nicolin Chen 2022-06-05  2233  }

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

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

* Re: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
  2022-06-08 23:48         ` Tian, Kevin
                             ` (2 preceding siblings ...)
  (?)
@ 2022-06-14 20:45           ` Nicolin Chen
  -1 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-14 20:45 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: Jason Gunthorpe, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

Hi Kevin,

On Wed, Jun 08, 2022 at 11:48:27PM +0000, Tian, Kevin wrote:
> > > > The KVM mechanism for controlling wbinvd is only triggered during
> > > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> > devices
> > > > are setup.
> > >
> > > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > > group_add() and group_del(). Then the coherency property is
> > > checked dynamically in wbinvd emulation:
> >
> > From the perspective of managing the domains that is still
> > one-shot. It doesn't get updated when individual devices are
> > added/removed to domains.
> 
> It's unchanged per-domain but dynamic per-vm when multiple
> domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
> It's the latter being checked in the kvm.

I am going to send a v2, yet not quite getting the point here.
Meanwhile, Jason is on leave.

What, in your opinion, would be an accurate description here?

Thanks
Nic

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

* Re: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-14 20:45           ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-14 20:45 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: Jason Gunthorpe, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

Hi Kevin,

On Wed, Jun 08, 2022 at 11:48:27PM +0000, Tian, Kevin wrote:
> > > > The KVM mechanism for controlling wbinvd is only triggered during
> > > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> > devices
> > > > are setup.
> > >
> > > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > > group_add() and group_del(). Then the coherency property is
> > > checked dynamically in wbinvd emulation:
> >
> > From the perspective of managing the domains that is still
> > one-shot. It doesn't get updated when individual devices are
> > added/removed to domains.
> 
> It's unchanged per-domain but dynamic per-vm when multiple
> domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
> It's the latter being checked in the kvm.

I am going to send a v2, yet not quite getting the point here.
Meanwhile, Jason is on leave.

What, in your opinion, would be an accurate description here?

Thanks
Nic

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

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

* Re: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-14 20:45           ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen via iommu @ 2022-06-14 20:45 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: cohuck, heiko, kvm, linux-tegra, thierry.reding, alim.akhtar,
	will, alyssa, jean-philippe, linux-samsung-soc, samuel,
	zhang.lyra, jernej.skrabec, jonathanh, linux-rockchip, wens,
	agross, Jason Gunthorpe, orsonzhai, gerald.schaefer, linux-sunxi,
	linux-arm-msm, alex.williamson, iommu, linux-mediatek,
	matthias.bgg, virtualization, linux-arm-kernel, linux-s390,
	marcan, linux-kernel, krzysztof.kozlowski, baolin.wang7, dwmw2,
	robin.murphy

Hi Kevin,

On Wed, Jun 08, 2022 at 11:48:27PM +0000, Tian, Kevin wrote:
> > > > The KVM mechanism for controlling wbinvd is only triggered during
> > > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> > devices
> > > > are setup.
> > >
> > > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > > group_add() and group_del(). Then the coherency property is
> > > checked dynamically in wbinvd emulation:
> >
> > From the perspective of managing the domains that is still
> > one-shot. It doesn't get updated when individual devices are
> > added/removed to domains.
> 
> It's unchanged per-domain but dynamic per-vm when multiple
> domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
> It's the latter being checked in the kvm.

I am going to send a v2, yet not quite getting the point here.
Meanwhile, Jason is on leave.

What, in your opinion, would be an accurate description here?

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

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

* Re: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-14 20:45           ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-14 20:45 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: Jason Gunthorpe, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

Hi Kevin,

On Wed, Jun 08, 2022 at 11:48:27PM +0000, Tian, Kevin wrote:
> > > > The KVM mechanism for controlling wbinvd is only triggered during
> > > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> > devices
> > > > are setup.
> > >
> > > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > > group_add() and group_del(). Then the coherency property is
> > > checked dynamically in wbinvd emulation:
> >
> > From the perspective of managing the domains that is still
> > one-shot. It doesn't get updated when individual devices are
> > added/removed to domains.
> 
> It's unchanged per-domain but dynamic per-vm when multiple
> domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
> It's the latter being checked in the kvm.

I am going to send a v2, yet not quite getting the point here.
Meanwhile, Jason is on leave.

What, in your opinion, would be an accurate description here?

Thanks
Nic

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

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

* Re: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-14 20:45           ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-14 20:45 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: Jason Gunthorpe, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

Hi Kevin,

On Wed, Jun 08, 2022 at 11:48:27PM +0000, Tian, Kevin wrote:
> > > > The KVM mechanism for controlling wbinvd is only triggered during
> > > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> > devices
> > > > are setup.
> > >
> > > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > > group_add() and group_del(). Then the coherency property is
> > > checked dynamically in wbinvd emulation:
> >
> > From the perspective of managing the domains that is still
> > one-shot. It doesn't get updated when individual devices are
> > added/removed to domains.
> 
> It's unchanged per-domain but dynamic per-vm when multiple
> domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
> It's the latter being checked in the kvm.

I am going to send a v2, yet not quite getting the point here.
Meanwhile, Jason is on leave.

What, in your opinion, would be an accurate description here?

Thanks
Nic

_______________________________________________
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] 138+ messages in thread

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
  2022-06-14 20:45           ` Nicolin Chen
                               ` (3 preceding siblings ...)
  (?)
@ 2022-06-15  7:35             ` Tian, Kevin
  -1 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-15  7:35 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: Jason Gunthorpe, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

> From: Nicolin Chen <nicolinc@nvidia.com>
> Sent: Wednesday, June 15, 2022 4:45 AM
> 
> Hi Kevin,
> 
> On Wed, Jun 08, 2022 at 11:48:27PM +0000, Tian, Kevin wrote:
> > > > > The KVM mechanism for controlling wbinvd is only triggered during
> > > > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> > > devices
> > > > > are setup.
> > > >
> > > > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > > > group_add() and group_del(). Then the coherency property is
> > > > checked dynamically in wbinvd emulation:
> > >
> > > From the perspective of managing the domains that is still
> > > one-shot. It doesn't get updated when individual devices are
> > > added/removed to domains.
> >
> > It's unchanged per-domain but dynamic per-vm when multiple
> > domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
> > It's the latter being checked in the kvm.
> 
> I am going to send a v2, yet not quite getting the point here.
> Meanwhile, Jason is on leave.
> 
> What, in your opinion, would be an accurate description here?
> 

Something like below:
--
The KVM mechanism for controlling wbinvd is based on OR of
the coherency property of all devices attached to a guest, no matter
those devices  are attached to a single domain or multiple domains.

So, there is no value in trying to push a device that could do enforced
cache coherency to a dedicated domain vs re-using an existing domain
which is non-coherent since KVM won't be able to take advantage of it. 
This just wastes domain memory.

Simplify this code and eliminate the test. This removes the only logic
that needed to have a dummy domain attached prior to searching for a
matching domain and simplifies the next patches.

It's unclear whether we want to further optimize the Intel driver to
update the domain coherency after a device is detached from it, at
least not before KVM can be verified to handle such dynamics in related
emulation paths (wbinvd, vcpu load, write_cr0, ept, etc.). In reality
we don't see an usage requiring such optimization as the only device
which imposes such non-coherency is Intel GPU which even doesn't
support hotplug/hot remove.
--

Thanks
Kevin

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

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-15  7:35             ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-15  7:35 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: Jason Gunthorpe, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

> From: Nicolin Chen <nicolinc@nvidia.com>
> Sent: Wednesday, June 15, 2022 4:45 AM
> 
> Hi Kevin,
> 
> On Wed, Jun 08, 2022 at 11:48:27PM +0000, Tian, Kevin wrote:
> > > > > The KVM mechanism for controlling wbinvd is only triggered during
> > > > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> > > devices
> > > > > are setup.
> > > >
> > > > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > > > group_add() and group_del(). Then the coherency property is
> > > > checked dynamically in wbinvd emulation:
> > >
> > > From the perspective of managing the domains that is still
> > > one-shot. It doesn't get updated when individual devices are
> > > added/removed to domains.
> >
> > It's unchanged per-domain but dynamic per-vm when multiple
> > domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
> > It's the latter being checked in the kvm.
> 
> I am going to send a v2, yet not quite getting the point here.
> Meanwhile, Jason is on leave.
> 
> What, in your opinion, would be an accurate description here?
> 

Something like below:
--
The KVM mechanism for controlling wbinvd is based on OR of
the coherency property of all devices attached to a guest, no matter
those devices  are attached to a single domain or multiple domains.

So, there is no value in trying to push a device that could do enforced
cache coherency to a dedicated domain vs re-using an existing domain
which is non-coherent since KVM won't be able to take advantage of it. 
This just wastes domain memory.

Simplify this code and eliminate the test. This removes the only logic
that needed to have a dummy domain attached prior to searching for a
matching domain and simplifies the next patches.

It's unclear whether we want to further optimize the Intel driver to
update the domain coherency after a device is detached from it, at
least not before KVM can be verified to handle such dynamics in related
emulation paths (wbinvd, vcpu load, write_cr0, ept, etc.). In reality
we don't see an usage requiring such optimization as the only device
which imposes such non-coherency is Intel GPU which even doesn't
support hotplug/hot remove.
--

Thanks
Kevin

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

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

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-15  7:35             ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-15  7:35 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: cohuck, heiko, kvm, linux-tegra, thierry.reding, alim.akhtar,
	will, alyssa, jean-philippe, linux-samsung-soc, samuel,
	zhang.lyra, jernej.skrabec, jonathanh, linux-rockchip, wens,
	agross, Jason Gunthorpe, orsonzhai, gerald.schaefer, linux-sunxi,
	linux-arm-msm, alex.williamson, iommu, linux-mediatek,
	matthias.bgg, virtualization, linux-arm-kernel, linux-s390,
	marcan, linux-kernel, krzysztof.kozlowski, baolin.wang7, dwmw2,
	robin.murphy

> From: Nicolin Chen <nicolinc@nvidia.com>
> Sent: Wednesday, June 15, 2022 4:45 AM
> 
> Hi Kevin,
> 
> On Wed, Jun 08, 2022 at 11:48:27PM +0000, Tian, Kevin wrote:
> > > > > The KVM mechanism for controlling wbinvd is only triggered during
> > > > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> > > devices
> > > > > are setup.
> > > >
> > > > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > > > group_add() and group_del(). Then the coherency property is
> > > > checked dynamically in wbinvd emulation:
> > >
> > > From the perspective of managing the domains that is still
> > > one-shot. It doesn't get updated when individual devices are
> > > added/removed to domains.
> >
> > It's unchanged per-domain but dynamic per-vm when multiple
> > domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
> > It's the latter being checked in the kvm.
> 
> I am going to send a v2, yet not quite getting the point here.
> Meanwhile, Jason is on leave.
> 
> What, in your opinion, would be an accurate description here?
> 

Something like below:
--
The KVM mechanism for controlling wbinvd is based on OR of
the coherency property of all devices attached to a guest, no matter
those devices  are attached to a single domain or multiple domains.

So, there is no value in trying to push a device that could do enforced
cache coherency to a dedicated domain vs re-using an existing domain
which is non-coherent since KVM won't be able to take advantage of it. 
This just wastes domain memory.

Simplify this code and eliminate the test. This removes the only logic
that needed to have a dummy domain attached prior to searching for a
matching domain and simplifies the next patches.

It's unclear whether we want to further optimize the Intel driver to
update the domain coherency after a device is detached from it, at
least not before KVM can be verified to handle such dynamics in related
emulation paths (wbinvd, vcpu load, write_cr0, ept, etc.). In reality
we don't see an usage requiring such optimization as the only device
which imposes such non-coherency is Intel GPU which even doesn't
support hotplug/hot remove.
--

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

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

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-15  7:35             ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-15  7:35 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: Jason Gunthorpe, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

> From: Nicolin Chen <nicolinc@nvidia.com>
> Sent: Wednesday, June 15, 2022 4:45 AM
> 
> Hi Kevin,
> 
> On Wed, Jun 08, 2022 at 11:48:27PM +0000, Tian, Kevin wrote:
> > > > > The KVM mechanism for controlling wbinvd is only triggered during
> > > > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> > > devices
> > > > > are setup.
> > > >
> > > > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > > > group_add() and group_del(). Then the coherency property is
> > > > checked dynamically in wbinvd emulation:
> > >
> > > From the perspective of managing the domains that is still
> > > one-shot. It doesn't get updated when individual devices are
> > > added/removed to domains.
> >
> > It's unchanged per-domain but dynamic per-vm when multiple
> > domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
> > It's the latter being checked in the kvm.
> 
> I am going to send a v2, yet not quite getting the point here.
> Meanwhile, Jason is on leave.
> 
> What, in your opinion, would be an accurate description here?
> 

Something like below:
--
The KVM mechanism for controlling wbinvd is based on OR of
the coherency property of all devices attached to a guest, no matter
those devices  are attached to a single domain or multiple domains.

So, there is no value in trying to push a device that could do enforced
cache coherency to a dedicated domain vs re-using an existing domain
which is non-coherent since KVM won't be able to take advantage of it. 
This just wastes domain memory.

Simplify this code and eliminate the test. This removes the only logic
that needed to have a dummy domain attached prior to searching for a
matching domain and simplifies the next patches.

It's unclear whether we want to further optimize the Intel driver to
update the domain coherency after a device is detached from it, at
least not before KVM can be verified to handle such dynamics in related
emulation paths (wbinvd, vcpu load, write_cr0, ept, etc.). In reality
we don't see an usage requiring such optimization as the only device
which imposes such non-coherency is Intel GPU which even doesn't
support hotplug/hot remove.
--

Thanks
Kevin

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

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

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-15  7:35             ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-15  7:35 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: cohuck, heiko, kvm, bjorn.andersson, linux-tegra, thierry.reding,
	alim.akhtar, will, alyssa, m.szyprowski, jean-philippe,
	linux-samsung-soc, samuel, zhang.lyra, joro, robdclark,
	jernej.skrabec, jonathanh, linux-rockchip, wens, agross,
	Jason Gunthorpe, orsonzhai, gerald.schaefer, linux-sunxi, sven,
	linux-arm-msm, iommu, linux-mediatek, matthias.bgg,
	virtualization, linux-arm-kernel, linux-s390, marcan,
	linux-kernel, krzysztof.kozlowski, baolin.wang7, dwmw2,
	robin.murphy, baolu.lu

> From: Nicolin Chen <nicolinc@nvidia.com>
> Sent: Wednesday, June 15, 2022 4:45 AM
> 
> Hi Kevin,
> 
> On Wed, Jun 08, 2022 at 11:48:27PM +0000, Tian, Kevin wrote:
> > > > > The KVM mechanism for controlling wbinvd is only triggered during
> > > > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> > > devices
> > > > > are setup.
> > > >
> > > > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > > > group_add() and group_del(). Then the coherency property is
> > > > checked dynamically in wbinvd emulation:
> > >
> > > From the perspective of managing the domains that is still
> > > one-shot. It doesn't get updated when individual devices are
> > > added/removed to domains.
> >
> > It's unchanged per-domain but dynamic per-vm when multiple
> > domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
> > It's the latter being checked in the kvm.
> 
> I am going to send a v2, yet not quite getting the point here.
> Meanwhile, Jason is on leave.
> 
> What, in your opinion, would be an accurate description here?
> 

Something like below:
--
The KVM mechanism for controlling wbinvd is based on OR of
the coherency property of all devices attached to a guest, no matter
those devices  are attached to a single domain or multiple domains.

So, there is no value in trying to push a device that could do enforced
cache coherency to a dedicated domain vs re-using an existing domain
which is non-coherent since KVM won't be able to take advantage of it. 
This just wastes domain memory.

Simplify this code and eliminate the test. This removes the only logic
that needed to have a dummy domain attached prior to searching for a
matching domain and simplifies the next patches.

It's unclear whether we want to further optimize the Intel driver to
update the domain coherency after a device is detached from it, at
least not before KVM can be verified to handle such dynamics in related
emulation paths (wbinvd, vcpu load, write_cr0, ept, etc.). In reality
we don't see an usage requiring such optimization as the only device
which imposes such non-coherency is Intel GPU which even doesn't
support hotplug/hot remove.
--

Thanks
Kevin
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

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

* RE: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-15  7:35             ` Tian, Kevin
  0 siblings, 0 replies; 138+ messages in thread
From: Tian, Kevin @ 2022-06-15  7:35 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: Jason Gunthorpe, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

> From: Nicolin Chen <nicolinc@nvidia.com>
> Sent: Wednesday, June 15, 2022 4:45 AM
> 
> Hi Kevin,
> 
> On Wed, Jun 08, 2022 at 11:48:27PM +0000, Tian, Kevin wrote:
> > > > > The KVM mechanism for controlling wbinvd is only triggered during
> > > > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> > > devices
> > > > > are setup.
> > > >
> > > > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > > > group_add() and group_del(). Then the coherency property is
> > > > checked dynamically in wbinvd emulation:
> > >
> > > From the perspective of managing the domains that is still
> > > one-shot. It doesn't get updated when individual devices are
> > > added/removed to domains.
> >
> > It's unchanged per-domain but dynamic per-vm when multiple
> > domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
> > It's the latter being checked in the kvm.
> 
> I am going to send a v2, yet not quite getting the point here.
> Meanwhile, Jason is on leave.
> 
> What, in your opinion, would be an accurate description here?
> 

Something like below:
--
The KVM mechanism for controlling wbinvd is based on OR of
the coherency property of all devices attached to a guest, no matter
those devices  are attached to a single domain or multiple domains.

So, there is no value in trying to push a device that could do enforced
cache coherency to a dedicated domain vs re-using an existing domain
which is non-coherent since KVM won't be able to take advantage of it. 
This just wastes domain memory.

Simplify this code and eliminate the test. This removes the only logic
that needed to have a dummy domain attached prior to searching for a
matching domain and simplifies the next patches.

It's unclear whether we want to further optimize the Intel driver to
update the domain coherency after a device is detached from it, at
least not before KVM can be verified to handle such dynamics in related
emulation paths (wbinvd, vcpu load, write_cr0, ept, etc.). In reality
we don't see an usage requiring such optimization as the only device
which imposes such non-coherency is Intel GPU which even doesn't
support hotplug/hot remove.
--

Thanks
Kevin

_______________________________________________
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] 138+ messages in thread

* Re: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
  2022-06-15  7:35             ` Tian, Kevin
  (?)
  (?)
@ 2022-06-15 23:12               ` Nicolin Chen
  -1 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-15 23:12 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: Jason Gunthorpe, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

On Wed, Jun 15, 2022 at 07:35:00AM +0000, Tian, Kevin wrote:
> External email: Use caution opening links or attachments
> 
> 
> > From: Nicolin Chen <nicolinc@nvidia.com>
> > Sent: Wednesday, June 15, 2022 4:45 AM
> >
> > Hi Kevin,
> >
> > On Wed, Jun 08, 2022 at 11:48:27PM +0000, Tian, Kevin wrote:
> > > > > > The KVM mechanism for controlling wbinvd is only triggered during
> > > > > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> > > > devices
> > > > > > are setup.
> > > > >
> > > > > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > > > > group_add() and group_del(). Then the coherency property is
> > > > > checked dynamically in wbinvd emulation:
> > > >
> > > > From the perspective of managing the domains that is still
> > > > one-shot. It doesn't get updated when individual devices are
> > > > added/removed to domains.
> > >
> > > It's unchanged per-domain but dynamic per-vm when multiple
> > > domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
> > > It's the latter being checked in the kvm.
> >
> > I am going to send a v2, yet not quite getting the point here.
> > Meanwhile, Jason is on leave.
> >
> > What, in your opinion, would be an accurate description here?
> >
> 
> Something like below:
> --
> The KVM mechanism for controlling wbinvd is based on OR of
> the coherency property of all devices attached to a guest, no matter
> those devices  are attached to a single domain or multiple domains.
> 
> So, there is no value in trying to push a device that could do enforced
> cache coherency to a dedicated domain vs re-using an existing domain
> which is non-coherent since KVM won't be able to take advantage of it.
> This just wastes domain memory.
> 
> Simplify this code and eliminate the test. This removes the only logic
> that needed to have a dummy domain attached prior to searching for a
> matching domain and simplifies the next patches.
> 
> It's unclear whether we want to further optimize the Intel driver to
> update the domain coherency after a device is detached from it, at
> least not before KVM can be verified to handle such dynamics in related
> emulation paths (wbinvd, vcpu load, write_cr0, ept, etc.). In reality
> we don't see an usage requiring such optimization as the only device
> which imposes such non-coherency is Intel GPU which even doesn't
> support hotplug/hot remove.

Thanks! I just updated that and will send v2.

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

* Re: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-15 23:12               ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-15 23:12 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: Jason Gunthorpe, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

On Wed, Jun 15, 2022 at 07:35:00AM +0000, Tian, Kevin wrote:
> External email: Use caution opening links or attachments
> 
> 
> > From: Nicolin Chen <nicolinc@nvidia.com>
> > Sent: Wednesday, June 15, 2022 4:45 AM
> >
> > Hi Kevin,
> >
> > On Wed, Jun 08, 2022 at 11:48:27PM +0000, Tian, Kevin wrote:
> > > > > > The KVM mechanism for controlling wbinvd is only triggered during
> > > > > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> > > > devices
> > > > > > are setup.
> > > > >
> > > > > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > > > > group_add() and group_del(). Then the coherency property is
> > > > > checked dynamically in wbinvd emulation:
> > > >
> > > > From the perspective of managing the domains that is still
> > > > one-shot. It doesn't get updated when individual devices are
> > > > added/removed to domains.
> > >
> > > It's unchanged per-domain but dynamic per-vm when multiple
> > > domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
> > > It's the latter being checked in the kvm.
> >
> > I am going to send a v2, yet not quite getting the point here.
> > Meanwhile, Jason is on leave.
> >
> > What, in your opinion, would be an accurate description here?
> >
> 
> Something like below:
> --
> The KVM mechanism for controlling wbinvd is based on OR of
> the coherency property of all devices attached to a guest, no matter
> those devices  are attached to a single domain or multiple domains.
> 
> So, there is no value in trying to push a device that could do enforced
> cache coherency to a dedicated domain vs re-using an existing domain
> which is non-coherent since KVM won't be able to take advantage of it.
> This just wastes domain memory.
> 
> Simplify this code and eliminate the test. This removes the only logic
> that needed to have a dummy domain attached prior to searching for a
> matching domain and simplifies the next patches.
> 
> It's unclear whether we want to further optimize the Intel driver to
> update the domain coherency after a device is detached from it, at
> least not before KVM can be verified to handle such dynamics in related
> emulation paths (wbinvd, vcpu load, write_cr0, ept, etc.). In reality
> we don't see an usage requiring such optimization as the only device
> which imposes such non-coherency is Intel GPU which even doesn't
> support hotplug/hot remove.

Thanks! I just updated that and will send v2.

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

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

* Re: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-15 23:12               ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen via iommu @ 2022-06-15 23:12 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: cohuck, heiko, kvm, linux-tegra, thierry.reding, alim.akhtar,
	will, alyssa, jean-philippe, linux-samsung-soc, samuel,
	zhang.lyra, jernej.skrabec, jonathanh, linux-rockchip, wens,
	agross, Jason Gunthorpe, orsonzhai, gerald.schaefer, linux-sunxi,
	linux-arm-msm, alex.williamson, iommu, linux-mediatek,
	matthias.bgg, virtualization, linux-arm-kernel, linux-s390,
	marcan, linux-kernel, krzysztof.kozlowski, baolin.wang7, dwmw2,
	robin.murphy

On Wed, Jun 15, 2022 at 07:35:00AM +0000, Tian, Kevin wrote:
> External email: Use caution opening links or attachments
> 
> 
> > From: Nicolin Chen <nicolinc@nvidia.com>
> > Sent: Wednesday, June 15, 2022 4:45 AM
> >
> > Hi Kevin,
> >
> > On Wed, Jun 08, 2022 at 11:48:27PM +0000, Tian, Kevin wrote:
> > > > > > The KVM mechanism for controlling wbinvd is only triggered during
> > > > > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> > > > devices
> > > > > > are setup.
> > > > >
> > > > > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > > > > group_add() and group_del(). Then the coherency property is
> > > > > checked dynamically in wbinvd emulation:
> > > >
> > > > From the perspective of managing the domains that is still
> > > > one-shot. It doesn't get updated when individual devices are
> > > > added/removed to domains.
> > >
> > > It's unchanged per-domain but dynamic per-vm when multiple
> > > domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
> > > It's the latter being checked in the kvm.
> >
> > I am going to send a v2, yet not quite getting the point here.
> > Meanwhile, Jason is on leave.
> >
> > What, in your opinion, would be an accurate description here?
> >
> 
> Something like below:
> --
> The KVM mechanism for controlling wbinvd is based on OR of
> the coherency property of all devices attached to a guest, no matter
> those devices  are attached to a single domain or multiple domains.
> 
> So, there is no value in trying to push a device that could do enforced
> cache coherency to a dedicated domain vs re-using an existing domain
> which is non-coherent since KVM won't be able to take advantage of it.
> This just wastes domain memory.
> 
> Simplify this code and eliminate the test. This removes the only logic
> that needed to have a dummy domain attached prior to searching for a
> matching domain and simplifies the next patches.
> 
> It's unclear whether we want to further optimize the Intel driver to
> update the domain coherency after a device is detached from it, at
> least not before KVM can be verified to handle such dynamics in related
> emulation paths (wbinvd, vcpu load, write_cr0, ept, etc.). In reality
> we don't see an usage requiring such optimization as the only device
> which imposes such non-coherency is Intel GPU which even doesn't
> support hotplug/hot remove.

Thanks! I just updated that and will send v2.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency
@ 2022-06-15 23:12               ` Nicolin Chen
  0 siblings, 0 replies; 138+ messages in thread
From: Nicolin Chen @ 2022-06-15 23:12 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: Jason Gunthorpe, joro, will, marcan, sven, robin.murphy,
	robdclark, m.szyprowski, krzysztof.kozlowski, baolu.lu, agross,
	bjorn.andersson, matthias.bgg, heiko, orsonzhai, baolin.wang7,
	zhang.lyra, wens, jernej.skrabec, samuel, jean-philippe,
	alex.williamson, virtualization, thierry.reding, alim.akhtar,
	alyssa, linux-s390, linux-samsung-soc, kvm, jonathanh,
	linux-rockchip, gerald.schaefer, linux-sunxi, linux-arm-msm,
	linux-mediatek, linux-tegra, linux-arm-kernel, cohuck,
	linux-kernel, iommu, dwmw2

On Wed, Jun 15, 2022 at 07:35:00AM +0000, Tian, Kevin wrote:
> External email: Use caution opening links or attachments
> 
> 
> > From: Nicolin Chen <nicolinc@nvidia.com>
> > Sent: Wednesday, June 15, 2022 4:45 AM
> >
> > Hi Kevin,
> >
> > On Wed, Jun 08, 2022 at 11:48:27PM +0000, Tian, Kevin wrote:
> > > > > > The KVM mechanism for controlling wbinvd is only triggered during
> > > > > > kvm_vfio_group_add(), meaning it is a one-shot test done once the
> > > > devices
> > > > > > are setup.
> > > > >
> > > > > It's not one-shot. kvm_vfio_update_coherency() is called in both
> > > > > group_add() and group_del(). Then the coherency property is
> > > > > checked dynamically in wbinvd emulation:
> > > >
> > > > From the perspective of managing the domains that is still
> > > > one-shot. It doesn't get updated when individual devices are
> > > > added/removed to domains.
> > >
> > > It's unchanged per-domain but dynamic per-vm when multiple
> > > domains are added/removed (i.e. kvm->arch.noncoherent_dma_count).
> > > It's the latter being checked in the kvm.
> >
> > I am going to send a v2, yet not quite getting the point here.
> > Meanwhile, Jason is on leave.
> >
> > What, in your opinion, would be an accurate description here?
> >
> 
> Something like below:
> --
> The KVM mechanism for controlling wbinvd is based on OR of
> the coherency property of all devices attached to a guest, no matter
> those devices  are attached to a single domain or multiple domains.
> 
> So, there is no value in trying to push a device that could do enforced
> cache coherency to a dedicated domain vs re-using an existing domain
> which is non-coherent since KVM won't be able to take advantage of it.
> This just wastes domain memory.
> 
> Simplify this code and eliminate the test. This removes the only logic
> that needed to have a dummy domain attached prior to searching for a
> matching domain and simplifies the next patches.
> 
> It's unclear whether we want to further optimize the Intel driver to
> update the domain coherency after a device is detached from it, at
> least not before KVM can be verified to handle such dynamics in related
> emulation paths (wbinvd, vcpu load, write_cr0, ept, etc.). In reality
> we don't see an usage requiring such optimization as the only device
> which imposes such non-coherency is Intel GPU which even doesn't
> support hotplug/hot remove.

Thanks! I just updated that and will send v2.

_______________________________________________
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] 138+ messages in thread

end of thread, other threads:[~2022-06-15 23:13 UTC | newest]

Thread overview: 138+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-06  6:19 [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine Nicolin Chen
2022-06-06  6:19 ` Nicolin Chen
2022-06-06  6:19 ` Nicolin Chen
2022-06-06  6:19 ` Nicolin Chen via iommu
2022-06-06  6:19 ` Nicolin Chen
2022-06-06  6:19 ` [PATCH 1/5] iommu: Return -EMEDIUMTYPE for incompatible domain and device/group Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen via iommu
2022-06-06  6:19   ` Nicolin Chen
2022-06-07  3:23   ` Baolu Lu
2022-06-07  3:23     ` Baolu Lu
2022-06-07  3:23     ` Baolu Lu
2022-06-07  3:23     ` Baolu Lu
2022-06-07  3:23     ` Baolu Lu
2022-06-07  4:03     ` Nicolin Chen
2022-06-07  4:03       ` Nicolin Chen
2022-06-07  4:03       ` Nicolin Chen
2022-06-07  4:03       ` Nicolin Chen via iommu
2022-06-07  4:03       ` Nicolin Chen
2022-06-08  7:49   ` Tian, Kevin
2022-06-08  7:49     ` Tian, Kevin
2022-06-08  7:49     ` Tian, Kevin
2022-06-08  7:49     ` Tian, Kevin
2022-06-08  7:49     ` Tian, Kevin
2022-06-08  7:49     ` Tian, Kevin
2022-06-08 17:38     ` Nicolin Chen
2022-06-08 17:38       ` Nicolin Chen
2022-06-08 17:38       ` Nicolin Chen
2022-06-08 17:38       ` Nicolin Chen
2022-06-08 17:38       ` Nicolin Chen via iommu
2022-06-06  6:19 ` [PATCH 2/5] iommu: Ensure device has the same iommu_ops as the domain Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen via iommu
2022-06-06 14:33   ` Robin Murphy
2022-06-06 14:33     ` Robin Murphy
2022-06-06 14:33     ` Robin Murphy
2022-06-06 14:33     ` Robin Murphy
2022-06-06 14:33     ` Robin Murphy
2022-06-06 14:33     ` Robin Murphy
2022-06-06 16:51     ` Nicolin Chen
2022-06-06 16:51       ` Nicolin Chen
2022-06-06 16:51       ` Nicolin Chen
2022-06-06 16:51       ` Nicolin Chen
2022-06-06 16:51       ` Nicolin Chen via iommu
2022-06-06 17:50       ` Robin Murphy
2022-06-06 17:50         ` Robin Murphy
2022-06-06 17:50         ` Robin Murphy
2022-06-06 17:50         ` Robin Murphy
2022-06-06 17:50         ` Robin Murphy
2022-06-06 17:50         ` Robin Murphy
2022-06-06 18:28         ` Nicolin Chen
2022-06-06 18:28           ` Nicolin Chen
2022-06-06 18:28           ` Nicolin Chen
2022-06-06 18:28           ` Nicolin Chen via iommu
2022-06-06 18:28           ` Nicolin Chen
2022-06-06 18:52           ` Jason Gunthorpe
2022-06-06 18:52             ` Jason Gunthorpe
2022-06-06 18:52             ` Jason Gunthorpe
2022-06-06 18:52             ` Jason Gunthorpe
2022-06-06 18:52             ` Jason Gunthorpe via iommu
2022-06-06  6:19 ` [PATCH 3/5] vfio/iommu_type1: Prefer to reuse domains vs match enforced cache coherency Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen via iommu
2022-06-08  8:28   ` Tian, Kevin
2022-06-08  8:28     ` Tian, Kevin
2022-06-08  8:28     ` Tian, Kevin
2022-06-08  8:28     ` Tian, Kevin
2022-06-08  8:28     ` Tian, Kevin
2022-06-08  8:28     ` Tian, Kevin
2022-06-08 11:17     ` Jason Gunthorpe
2022-06-08 11:17       ` Jason Gunthorpe
2022-06-08 11:17       ` Jason Gunthorpe
2022-06-08 11:17       ` Jason Gunthorpe via iommu
2022-06-08 11:17       ` Jason Gunthorpe
2022-06-08 23:48       ` Tian, Kevin
2022-06-08 23:48         ` Tian, Kevin
2022-06-08 23:48         ` Tian, Kevin
2022-06-08 23:48         ` Tian, Kevin
2022-06-08 23:48         ` Tian, Kevin
2022-06-08 23:48         ` Tian, Kevin
2022-06-14 20:45         ` Nicolin Chen
2022-06-14 20:45           ` Nicolin Chen
2022-06-14 20:45           ` Nicolin Chen
2022-06-14 20:45           ` Nicolin Chen via iommu
2022-06-14 20:45           ` Nicolin Chen
2022-06-15  7:35           ` Tian, Kevin
2022-06-15  7:35             ` Tian, Kevin
2022-06-15  7:35             ` Tian, Kevin
2022-06-15  7:35             ` Tian, Kevin
2022-06-15  7:35             ` Tian, Kevin
2022-06-15  7:35             ` Tian, Kevin
2022-06-15 23:12             ` Nicolin Chen
2022-06-15 23:12               ` Nicolin Chen
2022-06-15 23:12               ` Nicolin Chen via iommu
2022-06-15 23:12               ` Nicolin Chen
2022-06-06  6:19 ` [PATCH 4/5] vfio/iommu_type1: Clean up update_dirty_scope in detach_group() Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen via iommu
2022-06-08  8:35   ` Tian, Kevin
2022-06-08  8:35     ` Tian, Kevin
2022-06-08  8:35     ` Tian, Kevin
2022-06-08  8:35     ` Tian, Kevin
2022-06-08  8:35     ` Tian, Kevin
2022-06-08  8:35     ` Tian, Kevin
2022-06-08 17:46     ` Nicolin Chen
2022-06-08 17:46       ` Nicolin Chen
2022-06-08 17:46       ` Nicolin Chen
2022-06-08 17:46       ` Nicolin Chen
2022-06-08 17:46       ` Nicolin Chen via iommu
2022-06-06  6:19 ` [PATCH 5/5] vfio/iommu_type1: Simplify group attachment Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen
2022-06-06  6:19   ` Nicolin Chen via iommu
2022-06-07  7:44 ` [PATCH 0/5] Simplify vfio_iommu_type1 attach/detach routine Baolu Lu
2022-06-07  7:44   ` Baolu Lu
2022-06-07  7:44   ` Baolu Lu
2022-06-07  7:44   ` Baolu Lu
2022-06-07  7:44   ` Baolu Lu
2022-06-07 11:58   ` Jason Gunthorpe
2022-06-07 11:58     ` Jason Gunthorpe
2022-06-07 11:58     ` Jason Gunthorpe
2022-06-07 11:58     ` Jason Gunthorpe
2022-06-07 11:58     ` Jason Gunthorpe via iommu
2022-06-07 12:42     ` Baolu Lu
2022-06-07 12:42       ` Baolu Lu
2022-06-07 12:42       ` Baolu Lu
2022-06-07 12:42       ` Baolu Lu
2022-06-07 12:42       ` Baolu Lu
2022-06-10 16:39 [PATCH 5/5] vfio/iommu_type1: Simplify group attachment kernel test robot
2022-06-13 13:42 ` Dan Carpenter

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.