* [PATCH 1/2] iommu/vt-d: Split up get_domain_for_dev function
@ 2016-09-05 11:02 Joerg Roede
[not found] ` <1473073350-13591-1-git-send-email-joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
0 siblings, 1 reply; 2+ messages in thread
From: Joerg Roede @ 2016-09-05 11:02 UTC (permalink / raw)
To: David Woodhouse,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Cc: Joerg Roedel, linux-kernel-u79uwXL29TY76Z2rM5mHXA
From: Joerg Roedel <jroedel-l3A5Bk7waGM@public.gmane.org>
Split out the search for an already existing domain and the
context mapping of the device to the new domain.
This allows to map possible RMRR regions into the domain
before it is context mapped.
Signed-off-by: Joerg Roedel <jroedel-l3A5Bk7waGM@public.gmane.org>
---
drivers/iommu/intel-iommu.c | 76 ++++++++++++++++++++++++++++++++-------------
1 file changed, 55 insertions(+), 21 deletions(-)
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index ebb5bf3..bcdbe9d 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2452,20 +2452,15 @@ static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
return 0;
}
-/* domain is initialized */
-static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
+static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw)
{
struct device_domain_info *info = NULL;
- struct dmar_domain *domain, *tmp;
+ struct dmar_domain *domain = NULL;
struct intel_iommu *iommu;
u16 req_id, dma_alias;
unsigned long flags;
u8 bus, devfn;
- domain = find_domain(dev);
- if (domain)
- return domain;
-
iommu = device_to_iommu(dev, &bus, &devfn);
if (!iommu)
return NULL;
@@ -2487,9 +2482,9 @@ static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
}
spin_unlock_irqrestore(&device_domain_lock, flags);
- /* DMA alias already has a domain, uses it */
+ /* DMA alias already has a domain, use it */
if (info)
- goto found_domain;
+ goto out;
}
/* Allocate and initialize new domain for the device */
@@ -2501,28 +2496,67 @@ static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
return NULL;
}
- /* register PCI DMA alias device */
- if (dev_is_pci(dev) && req_id != dma_alias) {
- tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
- dma_alias & 0xff, NULL, domain);
+out:
- if (!tmp || tmp != domain) {
- domain_exit(domain);
- domain = tmp;
- }
+ return domain;
+}
- if (!domain)
- return NULL;
+static struct dmar_domain *set_domain_for_dev(struct device *dev,
+ struct dmar_domain *domain)
+{
+ struct intel_iommu *iommu;
+ struct dmar_domain *tmp;
+ u16 req_id, dma_alias;
+ u8 bus, devfn;
+
+ iommu = device_to_iommu(dev, &bus, &devfn);
+ if (!iommu)
+ return NULL;
+
+ req_id = ((u16)bus << 8) | devfn;
+
+ if (dev_is_pci(dev)) {
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
+
+ /* register PCI DMA alias device */
+ if (req_id != dma_alias) {
+ tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
+ dma_alias & 0xff, NULL, domain);
+
+ if (!tmp || tmp != domain)
+ return tmp;
+ }
}
-found_domain:
tmp = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
+ if (!tmp || tmp != domain)
+ return tmp;
+
+ return domain;
+}
- if (!tmp || tmp != domain) {
+static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
+{
+ struct dmar_domain *domain, *tmp;
+
+ domain = find_domain(dev);
+ if (domain)
+ goto out;
+
+ domain = find_or_alloc_domain(dev, gaw);
+ if (!domain)
+ goto out;
+
+ tmp = set_domain_for_dev(dev, domain);
+ if (!tmp || domain != tmp) {
domain_exit(domain);
domain = tmp;
}
+out:
+
return domain;
}
--
2.6.6
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH 2/2] iommu/vt-d: Make sure RMRRs are mapped before domain goes public
[not found] ` <1473073350-13591-1-git-send-email-joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
@ 2016-09-05 11:02 ` Joerg Roede
0 siblings, 0 replies; 2+ messages in thread
From: Joerg Roede @ 2016-09-05 11:02 UTC (permalink / raw)
To: David Woodhouse,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Cc: Joerg Roedel, linux-kernel-u79uwXL29TY76Z2rM5mHXA
From: Joerg Roedel <jroedel-l3A5Bk7waGM@public.gmane.org>
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-l3A5Bk7waGM@public.gmane.org>
---
drivers/iommu/intel-iommu.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index bcdbe9d..a4407ea 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -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)
{
+ struct dmar_domain *domain, *tmp;
struct dmar_rmrr_unit *rmrr;
- struct dmar_domain *domain;
struct device *i_dev;
int i, ret;
- domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
- if (!domain) {
- pr_err("Allocating domain for %s failed\n",
- dev_name(dev));
- return NULL;
- }
+ domain = find_domain(dev);
+ if (domain)
+ goto out;
+
+ 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 */
rcu_read_lock();
@@ -3457,6 +3458,18 @@ static struct dmar_domain *__get_valid_domain_for_dev(struct device *dev)
}
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;
}
--
2.6.6
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-09-05 11:02 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-09-05 11:02 [PATCH 1/2] iommu/vt-d: Split up get_domain_for_dev function Joerg Roede
[not found] ` <1473073350-13591-1-git-send-email-joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
2016-09-05 11:02 ` [PATCH 2/2] iommu/vt-d: Make sure RMRRs are mapped before domain goes public Joerg Roede
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).