iommu/vt-d: Make get_domain_for_dev() take struct device

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
This commit is contained in:
David Woodhouse 2014-03-09 15:44:17 -07:00
parent e1f167f3fd
commit 146922ec79

View file

@ -2207,52 +2207,51 @@ static struct dmar_domain *dmar_insert_dev_info(struct intel_iommu *iommu,
} }
/* domain is initialized */ /* domain is initialized */
static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
{ {
struct dmar_domain *domain, *free = NULL; struct dmar_domain *domain, *free = NULL;
struct intel_iommu *iommu = NULL; struct intel_iommu *iommu = NULL;
struct device_domain_info *info; struct device_domain_info *info;
struct dmar_drhd_unit *drhd; struct pci_dev *dev_tmp = NULL;
struct pci_dev *dev_tmp;
unsigned long flags; unsigned long flags;
int bus = 0, devfn = 0; u8 bus, devfn, bridge_bus, bridge_devfn;
int segment;
domain = find_domain(&pdev->dev); domain = find_domain(dev);
if (domain) if (domain)
return domain; return domain;
segment = pci_domain_nr(pdev->bus); if (dev_is_pci(dev)) {
struct pci_dev *pdev = to_pci_dev(dev);
u16 segment;
dev_tmp = pci_find_upstream_pcie_bridge(pdev); segment = pci_domain_nr(pdev->bus);
if (dev_tmp) { dev_tmp = pci_find_upstream_pcie_bridge(pdev);
if (pci_is_pcie(dev_tmp)) { if (dev_tmp) {
bus = dev_tmp->subordinate->number; if (pci_is_pcie(dev_tmp)) {
devfn = 0; bridge_bus = dev_tmp->subordinate->number;
} else { bridge_devfn = 0;
bus = dev_tmp->bus->number; } else {
devfn = dev_tmp->devfn; bridge_bus = dev_tmp->bus->number;
bridge_devfn = dev_tmp->devfn;
}
spin_lock_irqsave(&device_domain_lock, flags);
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);
/* pcie-pci bridge already has a domain, uses it */
if (info)
goto found_domain;
} }
spin_lock_irqsave(&device_domain_lock, flags);
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);
if (info)
goto found_domain;
} }
drhd = dmar_find_matched_drhd_unit(pdev); iommu = device_to_iommu(dev, &bus, &devfn);
if (!drhd) { if (!iommu)
printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n", goto error;
pci_name(pdev));
return NULL;
}
iommu = drhd->iommu;
/* Allocate and intialize new domain for the device */ /* Allocate and initialize new domain for the device */
domain = alloc_domain(false); domain = alloc_domain(false);
if (!domain) if (!domain)
goto error; goto error;
@ -2266,15 +2265,14 @@ 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(iommu, bus, devfn, NULL, domain = dmar_insert_dev_info(iommu, bridge_bus, bridge_devfn,
domain); NULL, domain);
if (!domain) if (!domain)
goto error; goto error;
} }
found_domain: found_domain:
domain = dmar_insert_dev_info(iommu, pdev->bus->number, domain = dmar_insert_dev_info(iommu, bus, devfn, dev, domain);
pdev->devfn, &pdev->dev, domain);
error: error:
if (free != domain) if (free != domain)
domain_exit(free); domain_exit(free);
@ -2320,7 +2318,7 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev,
struct dmar_domain *domain; struct dmar_domain *domain;
int ret; int ret;
domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH); domain = get_domain_for_dev(&pdev->dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
if (!domain) if (!domain)
return -ENOMEM; return -ENOMEM;
@ -2864,8 +2862,7 @@ static struct dmar_domain *__get_valid_domain_for_dev(struct pci_dev *pdev)
struct dmar_domain *domain; struct dmar_domain *domain;
int ret; int ret;
domain = get_domain_for_dev(pdev, domain = get_domain_for_dev(&pdev->dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
DEFAULT_DOMAIN_ADDRESS_WIDTH);
if (!domain) { if (!domain) {
printk(KERN_ERR printk(KERN_ERR
"Allocating domain for %s failed", pci_name(pdev)); "Allocating domain for %s failed", pci_name(pdev));