diff options
author | Keshavamurthy, Anil S <anil.s.keshavamurthy@intel.com> | 2007-10-21 23:41:59 (GMT) |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-22 15:13:19 (GMT) |
commit | 358dd8ac53a3bdafe62e3319e30627f3fef3a7b0 (patch) | |
tree | b31a6f707504f8b0257c27bcb3582190f2697c49 | |
parent | f76aec76ec7f68829a66624d11a50ed6cb404185 (diff) | |
download | linux-358dd8ac53a3bdafe62e3319e30627f3fef3a7b0.tar.xz |
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.c | 22 | ||||
-rw-r--r-- | include/asm-x86/device.h | 3 |
2 files changed, 14 insertions, 11 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index dab329f..8f372c8 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) list_del(&info->link); list_del(&info->global); if (info->dev) - info->dev->sysdata = NULL; + info->dev->dev.archdata.iommu = NULL; spin_unlock_irqrestore(&device_domain_lock, flags); detach_domain_for_dev(info->domain, info->bus, info->devfn); @@ -1361,7 +1361,7 @@ static void domain_remove_dev_info(struct dmar_domain *domain) /* * find_domain - * Note: we use struct pci_dev->sysdata stores the info + * Note: we use struct pci_dev->dev.archdata.iommu stores the info */ struct dmar_domain * find_domain(struct pci_dev *pdev) @@ -1369,7 +1369,7 @@ find_domain(struct pci_dev *pdev) struct device_domain_info *info; /* No lock here, assumes no domain exit in normal case */ - info = pdev->sysdata; + info = pdev->dev.archdata.iommu; if (info) return info->domain; return NULL; @@ -1519,7 +1519,7 @@ found_domain: } list_add(&info->link, &domain->devices); list_add(&info->global, &device_domain_list); - pdev->sysdata = info; + pdev->dev.archdata.iommu = info; spin_unlock_irqrestore(&device_domain_lock, flags); return domain; error: @@ -1579,7 +1579,7 @@ error: static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, struct pci_dev *pdev) { - if (pdev->sysdata == DUMMY_DEVICE_DOMAIN_INFO) + if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) return 0; return iommu_prepare_identity_map(pdev, rmrr->base_address, rmrr->end_address + 1); @@ -1595,7 +1595,7 @@ static void __init iommu_prepare_gfx_mapping(void) int ret; for_each_pci_dev(pdev) { - if (pdev->sysdata == DUMMY_DEVICE_DOMAIN_INFO || + if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO || !IS_GFX_DEVICE(pdev)) continue; 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, int prot = 0; BUG_ON(dir == DMA_NONE); - if (pdev->sysdata == DUMMY_DEVICE_DOMAIN_INFO) + if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) return virt_to_bus(addr); domain = get_valid_domain_for_dev(pdev); @@ -1900,7 +1900,7 @@ static void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, unsigned long start_addr; struct iova *iova; - if (pdev->sysdata == DUMMY_DEVICE_DOMAIN_INFO) + if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) return; domain = find_domain(pdev); BUG_ON(!domain); @@ -1974,7 +1974,7 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sg, size_t size = 0; void *addr; - if (pdev->sysdata == DUMMY_DEVICE_DOMAIN_INFO) + if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) return; domain = find_domain(pdev); @@ -2032,7 +2032,7 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sg, unsigned long start_addr; BUG_ON(dir == DMA_NONE); - if (pdev->sysdata == DUMMY_DEVICE_DOMAIN_INFO) + if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) return intel_nontranslate_map_sg(hwdev, sg, nelems, dir); domain = get_valid_domain_for_dev(pdev); @@ -2234,7 +2234,7 @@ static void __init init_no_remapping_devices(void) for (i = 0; i < drhd->devices_cnt; i++) { if (!drhd->devices[i]) continue; - drhd->devices[i]->sysdata = DUMMY_DEVICE_DOMAIN_INFO; + drhd->devices[i]->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO; } } } diff --git a/include/asm-x86/device.h b/include/asm-x86/device.h index d9ee5e5..87a7153 100644 --- a/include/asm-x86/device.h +++ b/include/asm-x86/device.h @@ -5,6 +5,9 @@ struct dev_archdata { #ifdef CONFIG_ACPI void *acpi_handle; #endif +#ifdef CONFIG_DMAR + void *iommu; /* hook for IOMMU specific extension */ +#endif }; #endif /* _ASM_X86_DEVICE_H */ |