Hi Joerg,

On 11/7/18 12:25 AM, j...@8bytes.org wrote:
On Mon, Oct 22, 2018 at 12:50:56PM +0100, Robin Murphy wrote:
To me, that sounds like a very good argument for having separate "attach as
primary domain" and "attach as aux domain" APIs.

I agree with that, overloading iommu_attach_device() to support
aux-domains is not going to be a maintainable solution. I'd like this
to be a two-level approach, where the aux-domains are sub-domains of a
primary domain (naming is still to-be-improved):


        struct iommu_domain *domain;

        domain = iommu_alloc_aux_domain();

        iommu_attach_device(pdev, domain); /* Fails if device has not
                                              support for this
                                              domain-type */

        /* Bind a process address space to the aux-domain */
        sva_handle = iommu_sva_bind_mm(domain, current, ...);
        pasid = iommu_sva_get_pasid(sva_handle);

        mdev_handle = iommu_mdev_alloc_domain(domain);
        iommu_mdev_map(mdev_handle, ...);
        iommu_mdev_unmap(mdev_handle, ...);

        /* Do more work */

        iommu_sva_unbind_mm(sva_handle);

        iommu_mdev_free_domain(mdev_handle);

        iommu_detach_device(domain, pdev);


Aux-domain is not used for sva case. Please allow me to introduce some
backgrounds of the aux-domain.

Previously we have RID (Request ID) granular DMA translation, hence only
a single domain might be attached to a device. The same domain could be
attached to multiple devices if they are configured to be assigned to a
same application (or VM).

   .--------------.                            .--------------.
   | PCI device A |    .------------------.    | PCI device B |
   |              |<---|   Domain         |--->|              |
   |              |    '------------------'    |              |
   |              |                            |              |
   |              |                            |              |
   |              |                            |              |
   |              |                            |              |
   '--------------'                            '--------------'

Nowadays, we can find PASID granular DMA translation on both ARM and x86
platforms. With PASID granular DMA translation supported in system iommu, if a device divides itself into multiple subsets and tag the DMA
transfers of each subset with a unique PASID, each subset become
assignable. We call the assignable subset as an ADI (Assignable Device
Interface). As the result, each ADI could be attached with a domain.

So for a device described above, a primary domain will be attached to it
for DMA transfers without PASID, and an aux-domain might be attached to
each ADI for transfers tagged with a PASID#xyz.

     .--------------.     .------------------.
     | PCI device A |<----| Primary Domain   |
     |              |     '------------------'
     .--------------.     .------------------.
     | ADI(PASID#x) |<----| Aux Domain1      |
     .--------------.     .------------------.
     | ADI(PASID#y) |<----| Aux Domain2      |
     .--------------.     .------------------.
     | ADI(PASID#z) |<----| Aux Domain3      |
     '--------------'     '------------------'
     |              |
     '--------------'

Conceptually, if we look a domain as an address boundary of each
assignable element, there is no difference between a primary domain and
an aux domain. The difference exists only in the vendor specific iommu
driver, say primary domains and aux domains use different translation
tables.

Further more, a single domain might be attached to an ADI of device A,
while attached to another legacy device B which doesn't support PASID
features. In this case, we say "Domain 4" is attached to ADI(PASID#x) in
aux mode and attached to device B in primary mode.

     .--------------.     .------------------.     .---------------.
     | PCI device A |<----| Primary Domain   |     | PCI device B  |
     |              |     '------------------'     |               |
     .--------------.     .------------------.     |               |
     | ADI(PASID#x) |<----|   Domain 4       |---->|               |
     .--------------.     .------------------.     |               |
     | ADI(PASID#y) |<----| Aux Domain2      |     |               |
     .--------------.     .------------------.     |               |
     | ADI(PASID#z) |<----| Aux Domain3      |     |               |
     '--------------'     '------------------'     |               |
     |              |                              |               |
     '--------------'                              '---------------'

Based on this, actually we can reuse all existing domain APIs for aux
domain.

    iommu_domain_alloc()
    iommu_domain_free()
    iommu_attach_device()
    iommu_detach_device()
    iommu_map()
    iommu_unmap()

During discussion, we found that reusing iommu_at(de)tach_device() will
cause some changes in iommu core due to the implementation of default
domain. So Jean suggested in this thread that we could consider to use
aux domain specific interfaces for domain attaching and detaching.
We followed Jean's suggestion and submitted a new version with aux
domain specific interfaces for domain attaching and detaching.

https://lkml.org/lkml/2018/11/5/209

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

Reply via email to