Loading drivers/iommu/intel-iommu.c +46 −32 Original line number Diff line number Diff line Loading @@ -664,35 +664,51 @@ static void domain_update_iommu_cap(struct dmar_domain *domain) domain_update_iommu_superpage(domain); } static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn) static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn) { struct dmar_drhd_unit *drhd = NULL; struct intel_iommu *iommu; struct device *dev; struct pci_dev *pdev; struct device *tmp; struct pci_dev *ptmp, *pdev = NULL; u16 segment; int i; if (dev_is_pci(dev)) { pdev = to_pci_dev(dev); segment = pci_domain_nr(pdev->bus); } else if (ACPI_COMPANION(dev)) dev = &ACPI_COMPANION(dev)->dev; rcu_read_lock(); for_each_active_iommu(iommu, drhd) { if (segment != drhd->segment) if (pdev && segment != drhd->segment) continue; for_each_active_dev_scope(drhd->devices, drhd->devices_cnt, i, dev) { if (!dev_is_pci(dev)) continue; pdev = to_pci_dev(dev); if (pdev->bus->number == bus && pdev->devfn == devfn) goto out; if (pdev->subordinate && pdev->subordinate->number <= bus && pdev->subordinate->busn_res.end >= bus) drhd->devices_cnt, i, tmp) { if (tmp == dev) { *bus = drhd->devices[i].bus; *devfn = drhd->devices[i].devfn; goto out; } if (drhd->include_all) if (!pdev || !dev_is_pci(tmp)) continue; ptmp = to_pci_dev(tmp); if (ptmp->subordinate && ptmp->subordinate->number <= pdev->bus->number && ptmp->subordinate->busn_res.end >= pdev->bus->number) goto got_pdev; } if (pdev && drhd->include_all) { got_pdev: *bus = pdev->bus->number; *devfn = pdev->devfn; goto out; } } iommu = NULL; out: rcu_read_unlock(); Loading Loading @@ -1830,14 +1846,13 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev, int ret; struct pci_dev *tmp, *parent; struct intel_iommu *iommu; u8 bus, devfn; iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number, pdev->devfn); iommu = device_to_iommu(&pdev->dev, &bus, &devfn); if (!iommu) return -ENODEV; ret = domain_context_mapping_one(domain, iommu, pdev->bus->number, pdev->devfn, ret = domain_context_mapping_one(domain, iommu, bus, devfn, translation); if (ret) return ret; Loading Loading @@ -1872,13 +1887,13 @@ static int domain_context_mapped(struct pci_dev *pdev) int ret; struct pci_dev *tmp, *parent; struct intel_iommu *iommu; u8 bus, devfn; iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number, pdev->devfn); iommu = device_to_iommu(&pdev->dev, &bus, &devfn); if (!iommu) return -ENODEV; ret = device_context_mapped(iommu, pdev->bus->number, pdev->devfn); ret = device_context_mapped(iommu, bus, devfn); if (!ret) return ret; /* dependent device mapping */ Loading Loading @@ -2459,15 +2474,14 @@ static int domain_add_dev_info(struct dmar_domain *domain, { struct dmar_domain *ndomain; struct intel_iommu *iommu; u8 bus, devfn; int ret; iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number, pdev->devfn); iommu = device_to_iommu(&pdev->dev, &bus, &devfn); if (!iommu) return -ENODEV; ndomain = dmar_insert_dev_info(iommu, pdev->bus->number, pdev->devfn, &pdev->dev, domain); ndomain = dmar_insert_dev_info(iommu, bus, devfn, &pdev->dev, domain); if (ndomain != domain) return -EBUSY; Loading Loading @@ -4020,9 +4034,9 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain, struct intel_iommu *iommu; unsigned long flags; int found = 0; u8 bus, devfn; iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number, pdev->devfn); iommu = device_to_iommu(&pdev->dev, &bus, &devfn); if (!iommu) return; Loading Loading @@ -4142,6 +4156,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, struct pci_dev *pdev = to_pci_dev(dev); struct intel_iommu *iommu; int addr_width; u8 bus, devfn; /* normally pdev is not mapped */ if (unlikely(domain_context_mapped(pdev))) { Loading @@ -4157,8 +4172,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, } } iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number, pdev->devfn); iommu = device_to_iommu(dev, &bus, &devfn); if (!iommu) return -ENODEV; Loading Loading @@ -4324,9 +4338,9 @@ static int intel_iommu_add_device(struct device *dev) struct pci_dev *bridge, *dma_pdev = NULL; struct iommu_group *group; int ret; u8 bus, devfn; if (!device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number, pdev->devfn)) if (!device_to_iommu(dev, &bus, &devfn)) return -ENODEV; bridge = pci_find_upstream_pcie_bridge(pdev); Loading Loading
drivers/iommu/intel-iommu.c +46 −32 Original line number Diff line number Diff line Loading @@ -664,35 +664,51 @@ static void domain_update_iommu_cap(struct dmar_domain *domain) domain_update_iommu_superpage(domain); } static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn) static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn) { struct dmar_drhd_unit *drhd = NULL; struct intel_iommu *iommu; struct device *dev; struct pci_dev *pdev; struct device *tmp; struct pci_dev *ptmp, *pdev = NULL; u16 segment; int i; if (dev_is_pci(dev)) { pdev = to_pci_dev(dev); segment = pci_domain_nr(pdev->bus); } else if (ACPI_COMPANION(dev)) dev = &ACPI_COMPANION(dev)->dev; rcu_read_lock(); for_each_active_iommu(iommu, drhd) { if (segment != drhd->segment) if (pdev && segment != drhd->segment) continue; for_each_active_dev_scope(drhd->devices, drhd->devices_cnt, i, dev) { if (!dev_is_pci(dev)) continue; pdev = to_pci_dev(dev); if (pdev->bus->number == bus && pdev->devfn == devfn) goto out; if (pdev->subordinate && pdev->subordinate->number <= bus && pdev->subordinate->busn_res.end >= bus) drhd->devices_cnt, i, tmp) { if (tmp == dev) { *bus = drhd->devices[i].bus; *devfn = drhd->devices[i].devfn; goto out; } if (drhd->include_all) if (!pdev || !dev_is_pci(tmp)) continue; ptmp = to_pci_dev(tmp); if (ptmp->subordinate && ptmp->subordinate->number <= pdev->bus->number && ptmp->subordinate->busn_res.end >= pdev->bus->number) goto got_pdev; } if (pdev && drhd->include_all) { got_pdev: *bus = pdev->bus->number; *devfn = pdev->devfn; goto out; } } iommu = NULL; out: rcu_read_unlock(); Loading Loading @@ -1830,14 +1846,13 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev, int ret; struct pci_dev *tmp, *parent; struct intel_iommu *iommu; u8 bus, devfn; iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number, pdev->devfn); iommu = device_to_iommu(&pdev->dev, &bus, &devfn); if (!iommu) return -ENODEV; ret = domain_context_mapping_one(domain, iommu, pdev->bus->number, pdev->devfn, ret = domain_context_mapping_one(domain, iommu, bus, devfn, translation); if (ret) return ret; Loading Loading @@ -1872,13 +1887,13 @@ static int domain_context_mapped(struct pci_dev *pdev) int ret; struct pci_dev *tmp, *parent; struct intel_iommu *iommu; u8 bus, devfn; iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number, pdev->devfn); iommu = device_to_iommu(&pdev->dev, &bus, &devfn); if (!iommu) return -ENODEV; ret = device_context_mapped(iommu, pdev->bus->number, pdev->devfn); ret = device_context_mapped(iommu, bus, devfn); if (!ret) return ret; /* dependent device mapping */ Loading Loading @@ -2459,15 +2474,14 @@ static int domain_add_dev_info(struct dmar_domain *domain, { struct dmar_domain *ndomain; struct intel_iommu *iommu; u8 bus, devfn; int ret; iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number, pdev->devfn); iommu = device_to_iommu(&pdev->dev, &bus, &devfn); if (!iommu) return -ENODEV; ndomain = dmar_insert_dev_info(iommu, pdev->bus->number, pdev->devfn, &pdev->dev, domain); ndomain = dmar_insert_dev_info(iommu, bus, devfn, &pdev->dev, domain); if (ndomain != domain) return -EBUSY; Loading Loading @@ -4020,9 +4034,9 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain, struct intel_iommu *iommu; unsigned long flags; int found = 0; u8 bus, devfn; iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number, pdev->devfn); iommu = device_to_iommu(&pdev->dev, &bus, &devfn); if (!iommu) return; Loading Loading @@ -4142,6 +4156,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, struct pci_dev *pdev = to_pci_dev(dev); struct intel_iommu *iommu; int addr_width; u8 bus, devfn; /* normally pdev is not mapped */ if (unlikely(domain_context_mapped(pdev))) { Loading @@ -4157,8 +4172,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, } } iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number, pdev->devfn); iommu = device_to_iommu(dev, &bus, &devfn); if (!iommu) return -ENODEV; Loading Loading @@ -4324,9 +4338,9 @@ static int intel_iommu_add_device(struct device *dev) struct pci_dev *bridge, *dma_pdev = NULL; struct iommu_group *group; int ret; u8 bus, devfn; if (!device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number, pdev->devfn)) if (!device_to_iommu(dev, &bus, &devfn)) return -ENODEV; bridge = pci_find_upstream_pcie_bridge(pdev); Loading