Re: [PATCH 2/5] iommu: Add blocking_domain_ops field in iommu_ops

2022-05-20 Thread Baolu Lu

On 2022/5/20 16:45, Joerg Roedel wrote:

On Mon, May 16, 2022 at 09:57:56AM +0800, Lu Baolu wrote:

const struct iommu_domain_ops *default_domain_ops;
+   const struct iommu_domain_ops *blocking_domain_ops;


I don't understand why extra domain-ops are needed for this. I think it
would be more straight-forward to implement allocation of
IOMMU_DOMAIN_BLOCKED domains in each driver and let the details be
handled in the set_dev() call-back. The IOMMU driver can make sure DMA
is blocked for a device when it encounters a IOMMU_DOMAIN_BLOCKED
domain.

For IOMMUs that have no explicit way to block DMA could just use an
unmanaged domain with an empty page-table.


Yes, this is what will go.

Best regards,
baolu

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


Re: [PATCH 2/5] iommu: Add blocking_domain_ops field in iommu_ops

2022-05-20 Thread Joerg Roedel
On Mon, May 16, 2022 at 09:57:56AM +0800, Lu Baolu wrote:
>   const struct iommu_domain_ops *default_domain_ops;
> + const struct iommu_domain_ops *blocking_domain_ops;

I don't understand why extra domain-ops are needed for this. I think it
would be more straight-forward to implement allocation of
IOMMU_DOMAIN_BLOCKED domains in each driver and let the details be
handled in the set_dev() call-back. The IOMMU driver can make sure DMA
is blocked for a device when it encounters a IOMMU_DOMAIN_BLOCKED
domain.

For IOMMUs that have no explicit way to block DMA could just use an
unmanaged domain with an empty page-table.

Regards,

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


Re: [PATCH 2/5] iommu: Add blocking_domain_ops field in iommu_ops

2022-05-18 Thread Baolu Lu

On 2022/5/17 21:13, Jason Gunthorpe wrote:

On Tue, May 17, 2022 at 01:43:03PM +0100, Robin Murphy wrote:


FWIW from my point of view I'm happy with having a .detach_dev_pasid op
meaning implicitly-blocked access for now.


If this is the path then lets not call it attach/detach
please. 'set_dev_pasid' and 'set_dev_blocking_pasid' are clearer
names.


Sure. And with the blocking domain implemented, the
set_dev_blocking_pasid could be deprecated.




On SMMUv3, PASIDs don't mix with our current notion of
IOMMU_DOMAIN_IDENTITY (nor the potential one for
IOMMU_DOMAIN_BLOCKED), so giving PASIDs functional symmetry with
devices would need significantly more work anyway.


There is no extra work in the driver, beyond SMMU having to implement
a blocking domain. The blocking domain's set_dev_pasid op simply is
whatever set_dev_blocking_pasid would have done on the unmanaged
domain.

identity doesn't come into this, identity domains should have a NULL
set_dev_pasid op if the driver can't support using it on a PASID.

IMHO blocking_domain->ops->set_dev_pasid() is just a more logical name
than domain->ops->set_dev_blocking_pasid() - especially since VFIO
would like drivers to implement blocking domain anyhow.


Perhaps implementing blocking domains for intel and smmuv3 iommu drivers
seem to be a more practical start.

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


Re: [PATCH 2/5] iommu: Add blocking_domain_ops field in iommu_ops

2022-05-17 Thread Jason Gunthorpe via iommu
On Tue, May 17, 2022 at 01:43:03PM +0100, Robin Murphy wrote:

> FWIW from my point of view I'm happy with having a .detach_dev_pasid op
> meaning implicitly-blocked access for now. 

If this is the path then lets not call it attach/detach
please. 'set_dev_pasid' and 'set_dev_blocking_pasid' are clearer
names.

> On SMMUv3, PASIDs don't mix with our current notion of
> IOMMU_DOMAIN_IDENTITY (nor the potential one for
> IOMMU_DOMAIN_BLOCKED), so giving PASIDs functional symmetry with
> devices would need significantly more work anyway.

There is no extra work in the driver, beyond SMMU having to implement
a blocking domain. The blocking domain's set_dev_pasid op simply is
whatever set_dev_blocking_pasid would have done on the unmanaged
domain.

identity doesn't come into this, identity domains should have a NULL
set_dev_pasid op if the driver can't support using it on a PASID.

IMHO blocking_domain->ops->set_dev_pasid() is just a more logical name
than domain->ops->set_dev_blocking_pasid() - especially since VFIO
would like drivers to implement blocking domain anyhow.

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


Re: [PATCH 2/5] iommu: Add blocking_domain_ops field in iommu_ops

2022-05-17 Thread Jason Gunthorpe via iommu
On Tue, May 17, 2022 at 10:37:55AM +0800, Baolu Lu wrote:
> Hi Jason,
> 
> On 2022/5/16 21:57, Jason Gunthorpe wrote:
> > On Mon, May 16, 2022 at 12:22:08PM +0100, Robin Murphy wrote:
> > > On 2022-05-16 02:57, Lu Baolu wrote:
> > > > Each IOMMU driver must provide a blocking domain ops. If the hardware
> > > > supports detaching domain from device, setting blocking domain equals
> > > > detaching the existing domain from the deivce. Otherwise, an UNMANAGED
> > > > domain without any mapping will be used instead.
> > > Unfortunately that's backwards - most of the implementations of 
> > > .detach_dev
> > > are disabling translation entirely, meaning the device ends up effectively
> > > in passthrough rather than blocked.
> > Ideally we'd convert the detach_dev of every driver into either
> > a blocking or identity domain. The trick is knowing which is which..
> 
> I am still a bit puzzled about how the blocking_domain should be used when
> it is extended to support ->set_dev_pasid.
> 
> If it's a blocking domain, the IOMMU driver knows that setting the
> blocking domain to device pasid means detaching the existing one.

> But if it's an identity domain, how could the IOMMU driver choose
> between:

The identity domain would never be used for detaching a PASID. The
reason it is in this explanation is because every detach_dev op should
be deleted - and the code that it was doing can remain in the driver
as either a blocking or identity domain.

> > So, the approach here should be to go driver by driver and convert
> > detach_dev to either identity, blocking or just delete it entirely,
> > excluding the above 7 that don't support default domains. And get acks
> > from the driver owners.
 
> Agreed. There seems to be a long way to go. I am wondering if we could
> decouple this refactoring from my new SVA API work? We can easily switch
> .detach_dev_pasid to using blocking domain later.

Well, PASID has nothing to do with this. PASID enabled drivers would
just need:
 - Must be using default domains and must have a NULL detach_dev op
 - Must provide a blocking_domain
 - Must provide set_dev_pasid for the unmanaged and blocking domains
   it creates

That is it.

Realigning the existing drivers for their base RID support is another
task.

The appeal of this is that it matches how base RID support should look
and doesn't continue the confusing appearance that there is a strictly
paired attach/detach operation.

Any domain can be set ony and RID/PASID at any time.

Drivers intended to be used with VFIO really want a blocking_domain
anyhow for efficiency.

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


Re: [PATCH 2/5] iommu: Add blocking_domain_ops field in iommu_ops

2022-05-17 Thread Robin Murphy

On 2022-05-17 03:37, Baolu Lu wrote:

Hi Jason,

On 2022/5/16 21:57, Jason Gunthorpe wrote:

On Mon, May 16, 2022 at 12:22:08PM +0100, Robin Murphy wrote:

On 2022-05-16 02:57, Lu Baolu wrote:

Each IOMMU driver must provide a blocking domain ops. If the hardware
supports detaching domain from device, setting blocking domain equals
detaching the existing domain from the deivce. Otherwise, an UNMANAGED
domain without any mapping will be used instead.
Unfortunately that's backwards - most of the implementations of 
.detach_dev
are disabling translation entirely, meaning the device ends up 
effectively

in passthrough rather than blocked.

Ideally we'd convert the detach_dev of every driver into either
a blocking or identity domain. The trick is knowing which is which..


I am still a bit puzzled about how the blocking_domain should be used 
when it is extended to support ->set_dev_pasid.


If it's a blocking domain, the IOMMU driver knows that setting the
blocking domain to device pasid means detaching the existing one.

But if it's an identity domain, how could the IOMMU driver choose
between:

  - setting the input domain to the pasid on device; or,
  - detaching the existing domain.

I've ever thought about below solutions:

- Checking the domain types and dispatching them to different
   operations.
- Using different blocking domains for different types of domains.

But both look rough.



Guessing going down the list:
  apple dart - blocking, detach_dev calls apple_dart_hw_disable_dma() 
same as

   IOMMU_DOMAIN_BLOCKED
  [I wonder if this drive ris wrong in other ways though because
    I dont see a remove_streams in attach_dev]
  exynos - this seems to disable the 'sysmmu' so I'm guessing this is
   identity
  iommu-vmsa - Comment says 'disable mmu translaction' so I'm guessing
   this is idenity
  mkt_v1 - Code looks similar to mkt, which is probably identity.
  rkt - No idea
  sprd - No idea
  sun50i - This driver confusingly treats identity the same as
   unmanaged, seems wrong, no idea.
  amd - Not sure, clear_dte_entry() seems to set translation on but 
points

    the PTE to 0 ? Based on the spec table 8 I would have expected
    TV to be clear which would be blocking. Maybe a bug??
  arm smmu qcomm - not sure
  intel - blocking

These doesn't support default domains, so detach_dev should return
back to DMA API ownership, which is either identity or something weird:
  fsl_pamu - identity due to the PPC use of dma direct
  msm
  mkt
  omap
  s390 - platform DMA ops
  terga-gart - Usually something called a GART would be 0 length once
   disabled, guessing blocking?
  tegra-smmu

So, the approach here should be to go driver by driver and convert
detach_dev to either identity, blocking or just delete it entirely,
excluding the above 7 that don't support default domains. And get acks
from the driver owners.



Agreed. There seems to be a long way to go. I am wondering if we could
decouple this refactoring from my new SVA API work? We can easily switch
.detach_dev_pasid to using blocking domain later.


FWIW from my point of view I'm happy with having a .detach_dev_pasid op 
meaning implicitly-blocked access for now. On SMMUv3, PASIDs don't mix 
with our current notion of IOMMU_DOMAIN_IDENTITY (nor the potential one 
for IOMMU_DOMAIN_BLOCKED), so giving PASIDs functional symmetry with 
devices would need significantly more work anyway.


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

Re: [PATCH 2/5] iommu: Add blocking_domain_ops field in iommu_ops

2022-05-16 Thread Baolu Lu

Hi Jason,

On 2022/5/16 21:57, Jason Gunthorpe wrote:

On Mon, May 16, 2022 at 12:22:08PM +0100, Robin Murphy wrote:

On 2022-05-16 02:57, Lu Baolu wrote:

Each IOMMU driver must provide a blocking domain ops. If the hardware
supports detaching domain from device, setting blocking domain equals
detaching the existing domain from the deivce. Otherwise, an UNMANAGED
domain without any mapping will be used instead.

Unfortunately that's backwards - most of the implementations of .detach_dev
are disabling translation entirely, meaning the device ends up effectively
in passthrough rather than blocked.

Ideally we'd convert the detach_dev of every driver into either
a blocking or identity domain. The trick is knowing which is which..


I am still a bit puzzled about how the blocking_domain should be used 
when it is extended to support ->set_dev_pasid.


If it's a blocking domain, the IOMMU driver knows that setting the
blocking domain to device pasid means detaching the existing one.

But if it's an identity domain, how could the IOMMU driver choose
between:

 - setting the input domain to the pasid on device; or,
 - detaching the existing domain.

I've ever thought about below solutions:

- Checking the domain types and dispatching them to different
  operations.
- Using different blocking domains for different types of domains.

But both look rough.



Guessing going down the list:
  apple dart - blocking, detach_dev calls apple_dart_hw_disable_dma() same as
   IOMMU_DOMAIN_BLOCKED
  [I wonder if this drive ris wrong in other ways though because
I dont see a remove_streams in attach_dev]
  exynos - this seems to disable the 'sysmmu' so I'm guessing this is
   identity
  iommu-vmsa - Comment says 'disable mmu translaction' so I'm guessing
   this is idenity
  mkt_v1 - Code looks similar to mkt, which is probably identity.
  rkt - No idea
  sprd - No idea
  sun50i - This driver confusingly treats identity the same as
   unmanaged, seems wrong, no idea.
  amd - Not sure, clear_dte_entry() seems to set translation on but points
the PTE to 0 ? Based on the spec table 8 I would have expected
TV to be clear which would be blocking. Maybe a bug??
  arm smmu qcomm - not sure
  intel - blocking

These doesn't support default domains, so detach_dev should return
back to DMA API ownership, which is either identity or something weird:
  fsl_pamu - identity due to the PPC use of dma direct
  msm
  mkt
  omap
  s390 - platform DMA ops
  terga-gart - Usually something called a GART would be 0 length once
   disabled, guessing blocking?
  tegra-smmu

So, the approach here should be to go driver by driver and convert
detach_dev to either identity, blocking or just delete it entirely,
excluding the above 7 that don't support default domains. And get acks
from the driver owners.



Agreed. There seems to be a long way to go. I am wondering if we could
decouple this refactoring from my new SVA API work? We can easily switch
.detach_dev_pasid to using blocking domain later.

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


Re: [PATCH 2/5] iommu: Add blocking_domain_ops field in iommu_ops

2022-05-16 Thread Jason Gunthorpe via iommu
On Mon, May 16, 2022 at 12:22:08PM +0100, Robin Murphy wrote:
> On 2022-05-16 02:57, Lu Baolu wrote:
> > Each IOMMU driver must provide a blocking domain ops. If the hardware
> > supports detaching domain from device, setting blocking domain equals
> > detaching the existing domain from the deivce. Otherwise, an UNMANAGED
> > domain without any mapping will be used instead.
> 
> Unfortunately that's backwards - most of the implementations of .detach_dev
> are disabling translation entirely, meaning the device ends up effectively
> in passthrough rather than blocked.

Ideally we'd convert the detach_dev of every driver into either
a blocking or identity domain. The trick is knowing which is which..

Guessing going down the list:
 apple dart - blocking, detach_dev calls apple_dart_hw_disable_dma() same as
  IOMMU_DOMAIN_BLOCKED
  [I wonder if this drive ris wrong in other ways though because
   I dont see a remove_streams in attach_dev]
 exynos - this seems to disable the 'sysmmu' so I'm guessing this is
  identity
 iommu-vmsa - Comment says 'disable mmu translaction' so I'm guessing
  this is idenity
 mkt_v1 - Code looks similar to mkt, which is probably identity.
 rkt - No idea
 sprd - No idea
 sun50i - This driver confusingly treats identity the same as
  unmanaged, seems wrong, no idea.
 amd - Not sure, clear_dte_entry() seems to set translation on but points
   the PTE to 0 ? Based on the spec table 8 I would have expected
   TV to be clear which would be blocking. Maybe a bug??
 arm smmu qcomm - not sure
 intel - blocking

These doesn't support default domains, so detach_dev should return 
back to DMA API ownership, which is either identity or something weird:
 fsl_pamu - identity due to the PPC use of dma direct
 msm
 mkt
 omap
 s390 - platform DMA ops
 terga-gart - Usually something called a GART would be 0 length once
  disabled, guessing blocking?
 tegra-smmu

So, the approach here should be to go driver by driver and convert
detach_dev to either identity, blocking or just delete it entirely,
excluding the above 7 that don't support default domains. And get acks
from the driver owners.

> Conversely, at least arm-smmu and arm-smmu-v3 could implement
> IOMMU_DOMAIN_BLOCKED properly with fault-type S2CRs and STEs
> respectively, it just needs a bit of wiring up.

Given that vfio now uses them it seems worthwhile to do..

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


Re: [PATCH 2/5] iommu: Add blocking_domain_ops field in iommu_ops

2022-05-16 Thread Baolu Lu

Hi Robin,

On 2022/5/16 19:22, Robin Murphy wrote:

On 2022-05-16 02:57, Lu Baolu wrote:

Each IOMMU driver must provide a blocking domain ops. If the hardware
supports detaching domain from device, setting blocking domain equals
detaching the existing domain from the deivce. Otherwise, an UNMANAGED
domain without any mapping will be used instead.


Unfortunately that's backwards - most of the implementations of 
.detach_dev are disabling translation entirely, meaning the device ends 
up effectively in passthrough rather than blocked. Conversely, at least 
arm-smmu and arm-smmu-v3 could implement IOMMU_DOMAIN_BLOCKED properly 
with fault-type S2CRs and STEs respectively, it just needs a bit of 
wiring up.


Thank you for letting me know this.

This means that we need to add an additional UNMANAGED domain for each
iommu group, although it is not used most of the time. If most IOMMU
drivers could implement real dumb blocking domains, this burden may be
reduced.

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


Re: [PATCH 2/5] iommu: Add blocking_domain_ops field in iommu_ops

2022-05-16 Thread Jason Gunthorpe via iommu
On Mon, May 16, 2022 at 12:27:41AM -0700, Christoph Hellwig wrote:
> On Mon, May 16, 2022 at 09:57:56AM +0800, Lu Baolu wrote:
> > Each IOMMU driver must provide a blocking domain ops. If the hardware
> > supports detaching domain from device, setting blocking domain equals
> > detaching the existing domain from the deivce. Otherwise, an UNMANAGED
> > domain without any mapping will be used instead.
> 
> blocking in this case means not allowing any access?  The naming
> sounds a bit odd to me as blocking in the kernel has a specific
> meaning.  Maybe something like noaccess ops might be a better name?

It is because of this:

include/linux/iommu.h: *IOMMU_DOMAIN_BLOCKED- All DMA is blocked, 
can be used to isolate
include/linux/iommu.h:#define IOMMU_DOMAIN_BLOCKED  (0U)

noaccess might be clearer

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


Re: [PATCH 2/5] iommu: Add blocking_domain_ops field in iommu_ops

2022-05-16 Thread Robin Murphy

On 2022-05-16 02:57, Lu Baolu wrote:

Each IOMMU driver must provide a blocking domain ops. If the hardware
supports detaching domain from device, setting blocking domain equals
detaching the existing domain from the deivce. Otherwise, an UNMANAGED
domain without any mapping will be used instead.


Unfortunately that's backwards - most of the implementations of 
.detach_dev are disabling translation entirely, meaning the device ends 
up effectively in passthrough rather than blocked. Conversely, at least 
arm-smmu and arm-smmu-v3 could implement IOMMU_DOMAIN_BLOCKED properly 
with fault-type S2CRs and STEs respectively, it just needs a bit of 
wiring up.


Thanks,
Robin.


Signed-off-by: Lu Baolu 
---
  include/linux/iommu.h   |  7 +++
  drivers/iommu/amd/iommu.c   | 12 
  drivers/iommu/apple-dart.c  | 12 
  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  3 +++
  drivers/iommu/arm/arm-smmu/arm-smmu.c   |  3 +++
  drivers/iommu/arm/arm-smmu/qcom_iommu.c | 12 
  drivers/iommu/exynos-iommu.c| 12 
  drivers/iommu/fsl_pamu_domain.c | 12 
  drivers/iommu/intel/iommu.c | 12 
  drivers/iommu/ipmmu-vmsa.c  | 12 
  drivers/iommu/msm_iommu.c   | 12 
  drivers/iommu/mtk_iommu.c   | 12 
  drivers/iommu/mtk_iommu_v1.c| 12 
  drivers/iommu/omap-iommu.c  | 12 
  drivers/iommu/rockchip-iommu.c  | 12 
  drivers/iommu/s390-iommu.c  | 12 
  drivers/iommu/sprd-iommu.c  | 11 +++
  drivers/iommu/sun50i-iommu.c| 12 
  drivers/iommu/tegra-gart.c  | 12 
  drivers/iommu/tegra-smmu.c  | 12 
  drivers/iommu/virtio-iommu.c|  3 +++
  21 files changed, 219 insertions(+)

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 572399ac1d83..5e228aad0ef6 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -216,6 +216,7 @@ struct iommu_iotlb_gather {
   *- IOMMU_DOMAIN_DMA: must use a dma domain
   *- 0: use the default setting
   * @default_domain_ops: the default ops for domains
+ * @blocking_domain_ops: the blocking ops for domains
   * @pgsize_bitmap: bitmap of all possible supported page sizes
   * @owner: Driver module providing these ops
   */
@@ -255,6 +256,7 @@ struct iommu_ops {
int (*def_domain_type)(struct device *dev);
  
  	const struct iommu_domain_ops *default_domain_ops;

+   const struct iommu_domain_ops *blocking_domain_ops;
unsigned long pgsize_bitmap;
struct module *owner;
  };
@@ -279,6 +281,9 @@ struct iommu_ops {
   * @enable_nesting: Enable nesting
   * @set_pgtable_quirks: Set io page table quirks (IO_PGTABLE_QUIRK_*)
   * @free: Release the domain after use.
+ * @blocking_domain_detach: iommu hardware support detaching a domain from
+ * a device, hence setting blocking domain to a device equals to
+ * detach the existing domain from it.
   */
  struct iommu_domain_ops {
int (*set_dev)(struct iommu_domain *domain, struct device *dev);
@@ -310,6 +315,8 @@ struct iommu_domain_ops {
  unsigned long quirks);
  
  	void (*free)(struct iommu_domain *domain);

+
+   unsigned int blocking_domain_detach:1;
  };
  
  /**

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 01b8668ef46d..c66713439824 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2272,6 +2272,14 @@ static bool amd_iommu_enforce_cache_coherency(struct 
iommu_domain *domain)
return true;
  }
  
+static int amd_blocking_domain_set_dev(struct iommu_domain *domain,

+  struct device *dev)
+{
+   amd_iommu_detach_device(domain, dev);
+
+   return 0;
+}
+
  const struct iommu_ops amd_iommu_ops = {
.capable = amd_iommu_capable,
.domain_alloc = amd_iommu_domain_alloc,
@@ -2295,6 +2303,10 @@ const struct iommu_ops amd_iommu_ops = {
.iotlb_sync = amd_iommu_iotlb_sync,
.free   = amd_iommu_domain_free,
.enforce_cache_coherency = amd_iommu_enforce_cache_coherency,
+   },
+   .blocking_domain_ops = &(const struct iommu_domain_ops) {
+   .set_dev= amd_blocking_domain_set_dev,
+   .blocking_domain_detach = true,
}
  };
  
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c

index a0b7281f1989..3c37762e01ec 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -763,6 +763,14 @@ static void apple_dart_get_resv_regions(struct device *dev,
iommu_dma_get_resv_regions(dev, head);
  }
  

Re: [PATCH 2/5] iommu: Add blocking_domain_ops field in iommu_ops

2022-05-16 Thread Christoph Hellwig
On Mon, May 16, 2022 at 09:57:56AM +0800, Lu Baolu wrote:
> Each IOMMU driver must provide a blocking domain ops. If the hardware
> supports detaching domain from device, setting blocking domain equals
> detaching the existing domain from the deivce. Otherwise, an UNMANAGED
> domain without any mapping will be used instead.

blocking in this case means not allowing any access?  The naming
sounds a bit odd to me as blocking in the kernel has a specific
meaning.  Maybe something like noaccess ops might be a better name?
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 2/5] iommu: Add blocking_domain_ops field in iommu_ops

2022-05-15 Thread Lu Baolu
Each IOMMU driver must provide a blocking domain ops. If the hardware
supports detaching domain from device, setting blocking domain equals
detaching the existing domain from the deivce. Otherwise, an UNMANAGED
domain without any mapping will be used instead.

Signed-off-by: Lu Baolu 
---
 include/linux/iommu.h   |  7 +++
 drivers/iommu/amd/iommu.c   | 12 
 drivers/iommu/apple-dart.c  | 12 
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  3 +++
 drivers/iommu/arm/arm-smmu/arm-smmu.c   |  3 +++
 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 12 
 drivers/iommu/exynos-iommu.c| 12 
 drivers/iommu/fsl_pamu_domain.c | 12 
 drivers/iommu/intel/iommu.c | 12 
 drivers/iommu/ipmmu-vmsa.c  | 12 
 drivers/iommu/msm_iommu.c   | 12 
 drivers/iommu/mtk_iommu.c   | 12 
 drivers/iommu/mtk_iommu_v1.c| 12 
 drivers/iommu/omap-iommu.c  | 12 
 drivers/iommu/rockchip-iommu.c  | 12 
 drivers/iommu/s390-iommu.c  | 12 
 drivers/iommu/sprd-iommu.c  | 11 +++
 drivers/iommu/sun50i-iommu.c| 12 
 drivers/iommu/tegra-gart.c  | 12 
 drivers/iommu/tegra-smmu.c  | 12 
 drivers/iommu/virtio-iommu.c|  3 +++
 21 files changed, 219 insertions(+)

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 572399ac1d83..5e228aad0ef6 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -216,6 +216,7 @@ struct iommu_iotlb_gather {
  * - IOMMU_DOMAIN_DMA: must use a dma domain
  * - 0: use the default setting
  * @default_domain_ops: the default ops for domains
+ * @blocking_domain_ops: the blocking ops for domains
  * @pgsize_bitmap: bitmap of all possible supported page sizes
  * @owner: Driver module providing these ops
  */
@@ -255,6 +256,7 @@ struct iommu_ops {
int (*def_domain_type)(struct device *dev);
 
const struct iommu_domain_ops *default_domain_ops;
+   const struct iommu_domain_ops *blocking_domain_ops;
unsigned long pgsize_bitmap;
struct module *owner;
 };
@@ -279,6 +281,9 @@ struct iommu_ops {
  * @enable_nesting: Enable nesting
  * @set_pgtable_quirks: Set io page table quirks (IO_PGTABLE_QUIRK_*)
  * @free: Release the domain after use.
+ * @blocking_domain_detach: iommu hardware support detaching a domain from
+ * a device, hence setting blocking domain to a device equals to
+ * detach the existing domain from it.
  */
 struct iommu_domain_ops {
int (*set_dev)(struct iommu_domain *domain, struct device *dev);
@@ -310,6 +315,8 @@ struct iommu_domain_ops {
  unsigned long quirks);
 
void (*free)(struct iommu_domain *domain);
+
+   unsigned int blocking_domain_detach:1;
 };
 
 /**
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 01b8668ef46d..c66713439824 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2272,6 +2272,14 @@ static bool amd_iommu_enforce_cache_coherency(struct 
iommu_domain *domain)
return true;
 }
 
+static int amd_blocking_domain_set_dev(struct iommu_domain *domain,
+  struct device *dev)
+{
+   amd_iommu_detach_device(domain, dev);
+
+   return 0;
+}
+
 const struct iommu_ops amd_iommu_ops = {
.capable = amd_iommu_capable,
.domain_alloc = amd_iommu_domain_alloc,
@@ -2295,6 +2303,10 @@ const struct iommu_ops amd_iommu_ops = {
.iotlb_sync = amd_iommu_iotlb_sync,
.free   = amd_iommu_domain_free,
.enforce_cache_coherency = amd_iommu_enforce_cache_coherency,
+   },
+   .blocking_domain_ops = &(const struct iommu_domain_ops) {
+   .set_dev= amd_blocking_domain_set_dev,
+   .blocking_domain_detach = true,
}
 };
 
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index a0b7281f1989..3c37762e01ec 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -763,6 +763,14 @@ static void apple_dart_get_resv_regions(struct device *dev,
iommu_dma_get_resv_regions(dev, head);
 }
 
+static int apple_dart_blocking_domain_set_dev(struct iommu_domain *domain,
+ struct device *dev)
+{
+   apple_dart_detach_dev(domain, dev);
+
+   return 0;
+}
+
 static const struct iommu_ops apple_dart_iommu_ops = {
.domain_alloc = apple_dart_domain_alloc,
.probe_device = apple_dart_probe_device,
@@ -784,6 +792,10 @@ static const struct iommu_ops apple_dart_iommu_ops = {