iommu/vt-d: Make sure RMRRs are mapped before domain goes public

When a domain is allocated through the get_valid_domain_for_dev
path, it will be context-mapped before the RMRR regions are
mapped in the page-table. This opens a short time window
where device-accesses to these regions fail and causing DMAR
faults.

Fix this by mapping the RMRR regions before the domain is
context-mapped.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
Joerg Roedel 2016-08-25 13:52:51 +02:00
parent 76208356a0
commit 1c5ebba95b

View File

@ -3428,17 +3428,18 @@ static unsigned long intel_alloc_iova(struct device *dev,
static struct dmar_domain *__get_valid_domain_for_dev(struct device *dev) static struct dmar_domain *__get_valid_domain_for_dev(struct device *dev)
{ {
struct dmar_domain *domain, *tmp;
struct dmar_rmrr_unit *rmrr; struct dmar_rmrr_unit *rmrr;
struct dmar_domain *domain;
struct device *i_dev; struct device *i_dev;
int i, ret; int i, ret;
domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH); domain = find_domain(dev);
if (!domain) { if (domain)
pr_err("Allocating domain for %s failed\n", goto out;
dev_name(dev));
return NULL; domain = find_or_alloc_domain(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
} if (!domain)
goto out;
/* We have a new domain - setup possible RMRRs for the device */ /* We have a new domain - setup possible RMRRs for the device */
rcu_read_lock(); rcu_read_lock();
@ -3457,6 +3458,18 @@ static struct dmar_domain *__get_valid_domain_for_dev(struct device *dev)
} }
rcu_read_unlock(); rcu_read_unlock();
tmp = set_domain_for_dev(dev, domain);
if (!tmp || domain != tmp) {
domain_exit(domain);
domain = tmp;
}
out:
if (!domain)
pr_err("Allocating domain for %s failed\n", dev_name(dev));
return domain; return domain;
} }