OSDN Git Service

iommu: introduce DOMAIN_ATTR_DYNAMIC
authorJeremy Gebben <jgebben@codeaurora.org>
Fri, 10 Jul 2015 22:43:23 +0000 (16:43 -0600)
committerDavid Keitel <dkeitel@codeaurora.org>
Tue, 22 Mar 2016 18:13:37 +0000 (11:13 -0700)
commit36e4ea4ac1063624ee470f9769f47cf93a13e777
tree28b99b390f69267d5cf1f9517559516c5e2b4c8a
parent930d3bcb94eeff1773bccf221274b110d9517fb6
iommu: introduce DOMAIN_ATTR_DYNAMIC

Some devices can support per-process iommu domains, which are used
asynchronously by the hardware which directly updates to the TTBR0
and CONTEXTIDR registers.

Add DOMAIN_ATTR_DYNAMIC to do indicate a domain may be used dynamically.
This attribute must be set before attaching, as it changes what
domain and hardware configuration is done by the iommu driver.
Before attaching any dynamic domains, the driver must first attach
a non-dynamic domain to do initial hardware configuration.

A simplified example:

void use_domain(struct iommu_domain *domain, struct job *job)
{
u64 ttbr0;
u32 contextidr;

iommu_domain_get_attr(domain, DOMAIN_ATTR_TTBR0, &ttbr0);
iommu_domain_get_attr(domain, DOMAIN_ATTR_CONTEXTIDR, &contextidr);

/*
 * Schedule work on the hardware, which is time sliced between
 * clients. Each client has a separate iommu domain and when
 * a job is run, the hardware first programs TTBR0 and
 * CONTEXTIDR to use the appropriate domain.
 */
submit_job(ttbr0, contextidr, job);
}

void init(void)
{
struct iommu_domain *master_domain, *dyn_domain1, *dyn_domain2;
int dynamic = 1;
master_domain = iommu_domain_alloc(bus);
dyn_domain1 = iommu_domain_alloc(bus);
dyn_domain2 = iommu_domain_alloc(bus);
iommu_attach_device(base_domain, dev);
iommu_domain_set_attr(dyn_domain1, DOMAIN_ATTR_DYNAMIC, &dynamic);
iommu_domain_set_attr(dyn_domain2, DOMAIN_ATTR_DYNAMIC, &dynamic);
iommu_attach_device(dyn_domain1, dev);
iommu_attach_device(dyn_domain2, dev);
while (keep_going) {
iommu_map(dyn_domain1, ...);
iommu_map(dyn_domain2, ...);
use_domain(dyn_domain1, job1);
use_domain(dyn_domain2, job2);
iommu_unmap(dyn_domain1, ...);
iommu_unmap(dyn_domain2, ...);
}
iommu_detach_device(dyn_domain2, dev);
iommu_detach_device(dyn_domain1, dev);
iommu_detach_device(master_domain, dev);
}

Change-Id: Ic4fa0a831751eb4b10fff5d9aec28a411856fbd1
Signed-off-by: Jeremy Gebben <jgebben@codeaurora.org>
include/linux/iommu.h