aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeshavamurthy, Anil S <anil.s.keshavamurthy@intel.com>2007-10-21 19:41:59 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-22 11:13:19 -0400
commit358dd8ac53a3bdafe62e3319e30627f3fef3a7b0 (patch)
treeb31a6f707504f8b0257c27bcb3582190f2697c49
parentf76aec76ec7f68829a66624d11a50ed6cb404185 (diff)
intel-iommu: fix for IOMMU early crash
pci_dev's->sysdata is highly overloaded and currently IOMMU is broken due to IOMMU code depending on this field. This patch introduces new field in pci_dev's dev.archdata struct to hold IOMMU specific per device IOMMU private data. Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Greg KH <greg@kroah.com> Cc: Jeff Garzik <jeff@garzik.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/pci/intel-iommu.c22
-rw-r--r--include/asm-x86/device.h3
2 files changed, 14 insertions, 11 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index dab329f01584..8f372c8f3d87 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -1348,7 +1348,7 @@ static void domain_remove_dev_info(struct dmar_domain *domain)
1348 list_del(&info->link); 1348 list_del(&info->link);
1349 list_del(&info->global); 1349 list_del(&info->global);
1350 if (info->dev) 1350 if (info->dev)
1351 info->dev->sysdata = NULL; 1351 info->dev->dev.archdata.iommu = NULL;
1352 spin_unlock_irqrestore(&device_domain_lock, flags); 1352 spin_unlock_irqrestore(&device_domain_lock, flags);
1353 1353
1354 detach_domain_for_dev(info->domain, info->bus, info->devfn); 1354 detach_domain_for_dev(info->domain, info->bus, info->devfn);
@@ -1361,7 +1361,7 @@ static void domain_remove_dev_info(struct dmar_domain *domain)
1361 1361
1362/* 1362/*
1363 * find_domain 1363 * find_domain
1364 * Note: we use struct pci_dev->sysdata stores the info 1364 * Note: we use struct pci_dev->dev.archdata.iommu stores the info
1365 */ 1365 */
1366struct dmar_domain * 1366struct dmar_domain *
1367find_domain(struct pci_dev *pdev) 1367find_domain(struct pci_dev *pdev)
@@ -1369,7 +1369,7 @@ find_domain(struct pci_dev *pdev)
1369 struct device_domain_info *info; 1369 struct device_domain_info *info;
1370 1370
1371 /* No lock here, assumes no domain exit in normal case */ 1371 /* No lock here, assumes no domain exit in normal case */
1372 info = pdev->sysdata; 1372 info = pdev->dev.archdata.iommu;
1373 if (info) 1373 if (info)
1374 return info->domain; 1374 return info->domain;
1375 return NULL; 1375 return NULL;
@@ -1519,7 +1519,7 @@ found_domain:
1519 } 1519 }
1520 list_add(&info->link, &domain->devices); 1520 list_add(&info->link, &domain->devices);
1521 list_add(&info->global, &device_domain_list); 1521 list_add(&info->global, &device_domain_list);
1522 pdev->sysdata = info; 1522 pdev->dev.archdata.iommu = info;
1523 spin_unlock_irqrestore(&device_domain_lock, flags); 1523 spin_unlock_irqrestore(&device_domain_lock, flags);
1524 return domain; 1524 return domain;
1525error: 1525error:
@@ -1579,7 +1579,7 @@ error:
1579static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, 1579static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
1580 struct pci_dev *pdev) 1580 struct pci_dev *pdev)
1581{ 1581{
1582 if (pdev->sysdata == DUMMY_DEVICE_DOMAIN_INFO) 1582 if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
1583 return 0; 1583 return 0;
1584 return iommu_prepare_identity_map(pdev, rmrr->base_address, 1584 return iommu_prepare_identity_map(pdev, rmrr->base_address,
1585 rmrr->end_address + 1); 1585 rmrr->end_address + 1);
@@ -1595,7 +1595,7 @@ static void __init iommu_prepare_gfx_mapping(void)
1595 int ret; 1595 int ret;
1596 1596
1597 for_each_pci_dev(pdev) { 1597 for_each_pci_dev(pdev) {
1598 if (pdev->sysdata == DUMMY_DEVICE_DOMAIN_INFO || 1598 if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO ||
1599 !IS_GFX_DEVICE(pdev)) 1599 !IS_GFX_DEVICE(pdev))
1600 continue; 1600 continue;
1601 printk(KERN_INFO "IOMMU: gfx device %s 1-1 mapping\n", 1601 printk(KERN_INFO "IOMMU: gfx device %s 1-1 mapping\n",
@@ -1836,7 +1836,7 @@ static dma_addr_t intel_map_single(struct device *hwdev, void *addr,
1836 int prot = 0; 1836 int prot = 0;
1837 1837
1838 BUG_ON(dir == DMA_NONE); 1838 BUG_ON(dir == DMA_NONE);
1839 if (pdev->sysdata == DUMMY_DEVICE_DOMAIN_INFO) 1839 if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
1840 return virt_to_bus(addr); 1840 return virt_to_bus(addr);
1841 1841
1842 domain = get_valid_domain_for_dev(pdev); 1842 domain = get_valid_domain_for_dev(pdev);
@@ -1900,7 +1900,7 @@ static void intel_unmap_single(struct device *dev, dma_addr_t dev_addr,
1900 unsigned long start_addr; 1900 unsigned long start_addr;
1901 struct iova *iova; 1901 struct iova *iova;
1902 1902
1903 if (pdev->sysdata == DUMMY_DEVICE_DOMAIN_INFO) 1903 if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
1904 return; 1904 return;
1905 domain = find_domain(pdev); 1905 domain = find_domain(pdev);
1906 BUG_ON(!domain); 1906 BUG_ON(!domain);
@@ -1974,7 +1974,7 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sg,
1974 size_t size = 0; 1974 size_t size = 0;
1975 void *addr; 1975 void *addr;
1976 1976
1977 if (pdev->sysdata == DUMMY_DEVICE_DOMAIN_INFO) 1977 if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
1978 return; 1978 return;
1979 1979
1980 domain = find_domain(pdev); 1980 domain = find_domain(pdev);
@@ -2032,7 +2032,7 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sg,
2032 unsigned long start_addr; 2032 unsigned long start_addr;
2033 2033
2034 BUG_ON(dir == DMA_NONE); 2034 BUG_ON(dir == DMA_NONE);
2035 if (pdev->sysdata == DUMMY_DEVICE_DOMAIN_INFO) 2035 if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
2036 return intel_nontranslate_map_sg(hwdev, sg, nelems, dir); 2036 return intel_nontranslate_map_sg(hwdev, sg, nelems, dir);
2037 2037
2038 domain = get_valid_domain_for_dev(pdev); 2038 domain = get_valid_domain_for_dev(pdev);
@@ -2234,7 +2234,7 @@ static void __init init_no_remapping_devices(void)
2234 for (i = 0; i < drhd->devices_cnt; i++) { 2234 for (i = 0; i < drhd->devices_cnt; i++) {
2235 if (!drhd->devices[i]) 2235 if (!drhd->devices[i])
2236 continue; 2236 continue;
2237 drhd->devices[i]->sysdata = DUMMY_DEVICE_DOMAIN_INFO; 2237 drhd->devices[i]->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
2238 } 2238 }
2239 } 2239 }
2240} 2240}
diff --git a/include/asm-x86/device.h b/include/asm-x86/device.h
index d9ee5e52e91b..87a715367a1b 100644
--- a/include/asm-x86/device.h
+++ b/include/asm-x86/device.h
@@ -5,6 +5,9 @@ struct dev_archdata {
5#ifdef CONFIG_ACPI 5#ifdef CONFIG_ACPI
6 void *acpi_handle; 6 void *acpi_handle;
7#endif 7#endif
8#ifdef CONFIG_DMAR
9 void *iommu; /* hook for IOMMU specific extension */
10#endif
8}; 11};
9 12
10#endif /* _ASM_X86_DEVICE_H */ 13#endif /* _ASM_X86_DEVICE_H */