Commit 5a8f40e8 authored by David Woodhouse's avatar David Woodhouse

iommu/vt-d: Always store iommu in device_domain_info

Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent e2f8c5f6
...@@ -1274,8 +1274,6 @@ iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu, ...@@ -1274,8 +1274,6 @@ iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
if (!dmar_find_matched_atsr_unit(pdev)) if (!dmar_find_matched_atsr_unit(pdev))
return NULL; return NULL;
info->iommu = iommu;
return info; return info;
} }
...@@ -2134,7 +2132,7 @@ static struct dmar_domain *find_domain(struct device *dev) ...@@ -2134,7 +2132,7 @@ static struct dmar_domain *find_domain(struct device *dev)
return NULL; return NULL;
} }
static inline struct dmar_domain * static inline struct device_domain_info *
dmar_search_domain_by_dev_info(int segment, int bus, int devfn) dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
{ {
struct device_domain_info *info; struct device_domain_info *info;
...@@ -2142,16 +2140,17 @@ dmar_search_domain_by_dev_info(int segment, int bus, int devfn) ...@@ -2142,16 +2140,17 @@ dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
list_for_each_entry(info, &device_domain_list, global) list_for_each_entry(info, &device_domain_list, global)
if (info->segment == segment && info->bus == bus && if (info->segment == segment && info->bus == bus &&
info->devfn == devfn) info->devfn == devfn)
return info->domain; return info;
return NULL; return NULL;
} }
static struct dmar_domain *dmar_insert_dev_info(int segment, int bus, int devfn, static struct dmar_domain *dmar_insert_dev_info(struct intel_iommu *iommu,
int segment, int bus, int devfn,
struct device *dev, struct device *dev,
struct dmar_domain *domain) struct dmar_domain *domain)
{ {
struct dmar_domain *found; struct dmar_domain *found = NULL;
struct device_domain_info *info; struct device_domain_info *info;
unsigned long flags; unsigned long flags;
...@@ -2164,14 +2163,19 @@ static struct dmar_domain *dmar_insert_dev_info(int segment, int bus, int devfn, ...@@ -2164,14 +2163,19 @@ static struct dmar_domain *dmar_insert_dev_info(int segment, int bus, int devfn,
info->devfn = devfn; info->devfn = devfn;
info->dev = dev; info->dev = dev;
info->domain = domain; info->domain = domain;
info->iommu = iommu;
if (!dev) if (!dev)
domain->flags |= DOMAIN_FLAG_P2P_MULTIPLE_DEVICES; domain->flags |= DOMAIN_FLAG_P2P_MULTIPLE_DEVICES;
spin_lock_irqsave(&device_domain_lock, flags); spin_lock_irqsave(&device_domain_lock, flags);
if (dev) if (dev)
found = find_domain(dev); found = find_domain(dev);
else else {
found = dmar_search_domain_by_dev_info(segment, bus, devfn); struct device_domain_info *info2;
info2 = dmar_search_domain_by_dev_info(segment, bus, devfn);
if (info2)
found = info2->domain;
}
if (found) { if (found) {
spin_unlock_irqrestore(&device_domain_lock, flags); spin_unlock_irqrestore(&device_domain_lock, flags);
free_devinfo_mem(info); free_devinfo_mem(info);
...@@ -2192,7 +2196,8 @@ static struct dmar_domain *dmar_insert_dev_info(int segment, int bus, int devfn, ...@@ -2192,7 +2196,8 @@ static struct dmar_domain *dmar_insert_dev_info(int segment, int bus, int devfn,
static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
{ {
struct dmar_domain *domain, *free = NULL; struct dmar_domain *domain, *free = NULL;
struct intel_iommu *iommu; struct intel_iommu *iommu = NULL;
struct device_domain_info *info;
struct dmar_drhd_unit *drhd; struct dmar_drhd_unit *drhd;
struct pci_dev *dev_tmp; struct pci_dev *dev_tmp;
unsigned long flags; unsigned long flags;
...@@ -2215,10 +2220,13 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) ...@@ -2215,10 +2220,13 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
devfn = dev_tmp->devfn; devfn = dev_tmp->devfn;
} }
spin_lock_irqsave(&device_domain_lock, flags); spin_lock_irqsave(&device_domain_lock, flags);
domain = dmar_search_domain_by_dev_info(segment, bus, devfn); info = dmar_search_domain_by_dev_info(segment, bus, devfn);
if (info) {
iommu = info->iommu;
domain = info->domain;
}
spin_unlock_irqrestore(&device_domain_lock, flags); spin_unlock_irqrestore(&device_domain_lock, flags);
/* pcie-pci bridge already has a domain, uses it */ if (info)
if (domain)
goto found_domain; goto found_domain;
} }
...@@ -2244,14 +2252,15 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) ...@@ -2244,14 +2252,15 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
/* register pcie-to-pci device */ /* register pcie-to-pci device */
if (dev_tmp) { if (dev_tmp) {
domain = dmar_insert_dev_info(segment, bus, devfn, NULL, domain); domain = dmar_insert_dev_info(iommu, segment, bus, devfn, NULL,
domain);
if (!domain) if (!domain)
goto error; goto error;
} }
found_domain: found_domain:
domain = dmar_insert_dev_info(segment, pdev->bus->number, pdev->devfn, domain = dmar_insert_dev_info(iommu, segment, pdev->bus->number,
&pdev->dev, domain); pdev->devfn, &pdev->dev, domain);
error: error:
if (free != domain) if (free != domain)
domain_exit(free); domain_exit(free);
...@@ -2453,9 +2462,15 @@ static int domain_add_dev_info(struct dmar_domain *domain, ...@@ -2453,9 +2462,15 @@ static int domain_add_dev_info(struct dmar_domain *domain,
int translation) int translation)
{ {
struct dmar_domain *ndomain; struct dmar_domain *ndomain;
struct intel_iommu *iommu;
int ret; int ret;
ndomain = dmar_insert_dev_info(pci_domain_nr(pdev->bus), iommu = device_to_iommu(pci_domain_nr(pdev->bus),
pdev->bus->number, pdev->devfn);
if (!iommu)
return -ENODEV;
ndomain = dmar_insert_dev_info(iommu, pci_domain_nr(pdev->bus),
pdev->bus->number, pdev->devfn, pdev->bus->number, pdev->devfn,
&pdev->dev, domain); &pdev->dev, domain);
if (ndomain != domain) if (ndomain != domain)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment