OSDN Git Service
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>