Commit b683b230 authored by Jiang Liu's avatar Jiang Liu Committed by Joerg Roedel

iommu/vt-d: Introduce macro for_each_dev_scope() to walk device scope entries

Introduce for_each_dev_scope()/for_each_active_dev_scope() to walk
{active} device scope entries. This will help following RCU lock
related patches.
Signed-off-by: default avatarJiang Liu <jiang.liu@linux.intel.com>
Signed-off-by: default avatarJoerg Roedel <joro@8bytes.org>
parent b5f82ddf
...@@ -170,9 +170,12 @@ int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, ...@@ -170,9 +170,12 @@ int __init dmar_parse_dev_scope(void *start, void *end, int *cnt,
void dmar_free_dev_scope(struct pci_dev ***devices, int *cnt) void dmar_free_dev_scope(struct pci_dev ***devices, int *cnt)
{ {
int i;
struct pci_dev *tmp_dev;
if (*devices && *cnt) { if (*devices && *cnt) {
while (--*cnt >= 0) for_each_active_dev_scope(*devices, *cnt, i, tmp_dev)
pci_dev_put((*devices)[*cnt]); pci_dev_put(tmp_dev);
kfree(*devices); kfree(*devices);
*devices = NULL; *devices = NULL;
*cnt = 0; *cnt = 0;
...@@ -402,10 +405,11 @@ static int dmar_pci_device_match(struct pci_dev *devices[], int cnt, ...@@ -402,10 +405,11 @@ static int dmar_pci_device_match(struct pci_dev *devices[], int cnt,
struct pci_dev *dev) struct pci_dev *dev)
{ {
int index; int index;
struct pci_dev *tmp;
while (dev) { while (dev) {
for (index = 0; index < cnt; index++) for_each_active_dev_scope(devices, cnt, index, tmp)
if (dev == devices[index]) if (dev == tmp)
return 1; return 1;
/* Check our parent */ /* Check our parent */
...@@ -452,7 +456,7 @@ int __init dmar_dev_scope_init(void) ...@@ -452,7 +456,7 @@ int __init dmar_dev_scope_init(void)
if (list_empty(&dmar_drhd_units)) if (list_empty(&dmar_drhd_units))
goto fail; goto fail;
list_for_each_entry(drhd, &dmar_drhd_units, list) { for_each_drhd_unit(drhd) {
ret = dmar_parse_dev(drhd); ret = dmar_parse_dev(drhd);
if (ret) if (ret)
goto fail; goto fail;
......
...@@ -654,29 +654,31 @@ static void domain_update_iommu_cap(struct dmar_domain *domain) ...@@ -654,29 +654,31 @@ static void domain_update_iommu_cap(struct dmar_domain *domain)
static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn) static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn)
{ {
struct dmar_drhd_unit *drhd = NULL; struct dmar_drhd_unit *drhd = NULL;
struct intel_iommu *iommu;
struct pci_dev *dev;
int i; int i;
for_each_active_drhd_unit(drhd) { for_each_active_iommu(iommu, drhd) {
if (segment != drhd->segment) if (segment != drhd->segment)
continue; continue;
for (i = 0; i < drhd->devices_cnt; i++) { for_each_active_dev_scope(drhd->devices,
if (drhd->devices[i] && drhd->devices_cnt, i, dev) {
drhd->devices[i]->bus->number == bus && if (dev->bus->number == bus && dev->devfn == devfn)
drhd->devices[i]->devfn == devfn) goto out;
return drhd->iommu; if (dev->subordinate &&
if (drhd->devices[i] && dev->subordinate->number <= bus &&
drhd->devices[i]->subordinate && dev->subordinate->busn_res.end >= bus)
drhd->devices[i]->subordinate->number <= bus && goto out;
drhd->devices[i]->subordinate->busn_res.end >= bus)
return drhd->iommu;
} }
if (drhd->include_all) if (drhd->include_all)
return drhd->iommu; goto out;
} }
iommu = NULL;
out:
return NULL; return iommu;
} }
static void domain_flush_cache(struct dmar_domain *domain, static void domain_flush_cache(struct dmar_domain *domain,
...@@ -2333,17 +2335,19 @@ static int domain_add_dev_info(struct dmar_domain *domain, ...@@ -2333,17 +2335,19 @@ static int domain_add_dev_info(struct dmar_domain *domain,
static bool device_has_rmrr(struct pci_dev *dev) static bool device_has_rmrr(struct pci_dev *dev)
{ {
struct dmar_rmrr_unit *rmrr; struct dmar_rmrr_unit *rmrr;
struct pci_dev *tmp;
int i; int i;
for_each_rmrr_units(rmrr) { for_each_rmrr_units(rmrr) {
for (i = 0; i < rmrr->devices_cnt; i++) { /*
/* * Return TRUE if this RMRR contains the device that
* Return TRUE if this RMRR contains the device that * is passed in.
* is passed in. */
*/ for_each_active_dev_scope(rmrr->devices,
if (rmrr->devices[i] == dev) rmrr->devices_cnt, i, tmp)
if (tmp == dev) {
return true; return true;
} }
} }
return false; return false;
} }
...@@ -2593,14 +2597,9 @@ static int __init init_dmars(void) ...@@ -2593,14 +2597,9 @@ static int __init init_dmars(void)
*/ */
printk(KERN_INFO "IOMMU: Setting RMRR:\n"); printk(KERN_INFO "IOMMU: Setting RMRR:\n");
for_each_rmrr_units(rmrr) { for_each_rmrr_units(rmrr) {
for (i = 0; i < rmrr->devices_cnt; i++) { /* some BIOS lists non-exist devices in DMAR table. */
pdev = rmrr->devices[i]; for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
/* i, pdev) {
* some BIOS lists non-exist devices in DMAR
* table.
*/
if (!pdev)
continue;
ret = iommu_prepare_rmrr_dev(rmrr, pdev); ret = iommu_prepare_rmrr_dev(rmrr, pdev);
if (ret) if (ret)
printk(KERN_ERR printk(KERN_ERR
...@@ -3288,13 +3287,14 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quir ...@@ -3288,13 +3287,14 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quir
static void __init init_no_remapping_devices(void) static void __init init_no_remapping_devices(void)
{ {
struct dmar_drhd_unit *drhd; struct dmar_drhd_unit *drhd;
struct pci_dev *dev;
int i;
for_each_drhd_unit(drhd) { for_each_drhd_unit(drhd) {
if (!drhd->include_all) { if (!drhd->include_all) {
int i; for_each_active_dev_scope(drhd->devices,
for (i = 0; i < drhd->devices_cnt; i++) drhd->devices_cnt, i, dev)
if (drhd->devices[i] != NULL) break;
break;
/* ignore DMAR unit if no pci devices exist */ /* ignore DMAR unit if no pci devices exist */
if (i == drhd->devices_cnt) if (i == drhd->devices_cnt)
drhd->ignored = 1; drhd->ignored = 1;
...@@ -3302,15 +3302,13 @@ static void __init init_no_remapping_devices(void) ...@@ -3302,15 +3302,13 @@ static void __init init_no_remapping_devices(void)
} }
for_each_active_drhd_unit(drhd) { for_each_active_drhd_unit(drhd) {
int i;
if (drhd->include_all) if (drhd->include_all)
continue; continue;
for (i = 0; i < drhd->devices_cnt; i++) for_each_active_dev_scope(drhd->devices,
if (drhd->devices[i] && drhd->devices_cnt, i, dev)
!IS_GFX_DEVICE(drhd->devices[i])) if (!IS_GFX_DEVICE(dev))
break; break;
if (i < drhd->devices_cnt) if (i < drhd->devices_cnt)
continue; continue;
...@@ -3320,11 +3318,9 @@ static void __init init_no_remapping_devices(void) ...@@ -3320,11 +3318,9 @@ static void __init init_no_remapping_devices(void)
intel_iommu_gfx_mapped = 1; intel_iommu_gfx_mapped = 1;
} else { } else {
drhd->ignored = 1; drhd->ignored = 1;
for (i = 0; i < drhd->devices_cnt; i++) { for_each_active_dev_scope(drhd->devices,
if (!drhd->devices[i]) drhd->devices_cnt, i, dev)
continue; dev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
drhd->devices[i]->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
}
} }
} }
} }
...@@ -3560,9 +3556,9 @@ static void intel_iommu_free_dmars(void) ...@@ -3560,9 +3556,9 @@ static void intel_iommu_free_dmars(void)
int dmar_find_matched_atsr_unit(struct pci_dev *dev) int dmar_find_matched_atsr_unit(struct pci_dev *dev)
{ {
int i; int i, ret = 1;
struct pci_bus *bus; struct pci_bus *bus;
struct pci_dev *bridge = NULL; struct pci_dev *bridge = NULL, *tmp;
struct acpi_dmar_atsr *atsr; struct acpi_dmar_atsr *atsr;
struct dmar_atsr_unit *atsru; struct dmar_atsr_unit *atsru;
...@@ -3583,22 +3579,24 @@ int dmar_find_matched_atsr_unit(struct pci_dev *dev) ...@@ -3583,22 +3579,24 @@ int dmar_find_matched_atsr_unit(struct pci_dev *dev)
if (atsr->segment != pci_domain_nr(dev->bus)) if (atsr->segment != pci_domain_nr(dev->bus))
continue; continue;
for (i = 0; i < atsru->devices_cnt; i++) for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp)
if (atsru->devices[i] == bridge) if (tmp == bridge)
return 1; goto out;
if (atsru->include_all) if (atsru->include_all)
return 1; goto out;
} }
ret = 0;
out:
return 0; return ret;
} }
int __init dmar_parse_rmrr_atsr_dev(void) int __init dmar_parse_rmrr_atsr_dev(void)
{ {
struct dmar_rmrr_unit *rmrr; struct dmar_rmrr_unit *rmrr;
struct dmar_atsr_unit *atsr; struct dmar_atsr_unit *atsr;
int ret = 0; int ret;
list_for_each_entry(rmrr, &dmar_rmrr_units, list) { list_for_each_entry(rmrr, &dmar_rmrr_units, list) {
ret = rmrr_parse_dev(rmrr); ret = rmrr_parse_dev(rmrr);
...@@ -3612,7 +3610,7 @@ int __init dmar_parse_rmrr_atsr_dev(void) ...@@ -3612,7 +3610,7 @@ int __init dmar_parse_rmrr_atsr_dev(void)
return ret; return ret;
} }
return ret; return 0;
} }
/* /*
......
...@@ -65,6 +65,12 @@ extern struct list_head dmar_drhd_units; ...@@ -65,6 +65,12 @@ extern struct list_head dmar_drhd_units;
list_for_each_entry(drhd, &dmar_drhd_units, list) \ list_for_each_entry(drhd, &dmar_drhd_units, list) \
if (i=drhd->iommu, 0) {} else if (i=drhd->iommu, 0) {} else
#define for_each_dev_scope(a, c, p, d) \
for ((p) = 0; ((d) = (p) < (c) ? (a)[(p)] : NULL, (p) < (c)); (p)++)
#define for_each_active_dev_scope(a, c, p, d) \
for_each_dev_scope((a), (c), (p), (d)) if (!(d)) { continue; } else
extern int dmar_table_init(void); extern int dmar_table_init(void);
extern int dmar_dev_scope_init(void); extern int dmar_dev_scope_init(void);
extern int dmar_parse_dev_scope(void *start, void *end, int *cnt, extern int dmar_parse_dev_scope(void *start, void *end, int *cnt,
......
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