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:
parent
e1f167f3fd
commit
146922ec79
|
@ -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));
|
||||||
|
|
Loading…
Reference in a new issue