aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2009-11-23 06:50:00 -0500
committerJoerg Roedel <joerg.roedel@amd.com>2009-11-23 06:54:17 -0500
commitbe831297716036de5b24308447ecb69f1706a846 (patch)
tree3e4fa3c904f9ea8dd55fb7226d49df9fab71920c /arch
parent9f800de38b05d84809e89f16671d636a140eede7 (diff)
x86/amd-iommu: attach devices to pre-allocated domains early
For some devices the ACPI table may define unity map requirements which must me met when the IOMMU is enabled. So we need to attach devices to their domains as early as possible so that these mappings are in place when needed. This patch assigns the domains right after they are allocated. Otherwise this can result in I/O page faults before a driver binds to a device and BIOS is still using it. Cc: stable@kernel.org Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/amd_iommu.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 093bd526c949..b74b21247584 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -2047,10 +2047,10 @@ static void prealloc_protection_domains(void)
2047 struct pci_dev *dev = NULL; 2047 struct pci_dev *dev = NULL;
2048 struct dma_ops_domain *dma_dom; 2048 struct dma_ops_domain *dma_dom;
2049 struct amd_iommu *iommu; 2049 struct amd_iommu *iommu;
2050 u16 devid; 2050 u16 devid, __devid;
2051 2051
2052 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { 2052 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
2053 devid = calc_devid(dev->bus->number, dev->devfn); 2053 __devid = devid = calc_devid(dev->bus->number, dev->devfn);
2054 if (devid > amd_iommu_last_bdf) 2054 if (devid > amd_iommu_last_bdf)
2055 continue; 2055 continue;
2056 devid = amd_iommu_alias_table[devid]; 2056 devid = amd_iommu_alias_table[devid];
@@ -2065,6 +2065,10 @@ static void prealloc_protection_domains(void)
2065 init_unity_mappings_for_device(dma_dom, devid); 2065 init_unity_mappings_for_device(dma_dom, devid);
2066 dma_dom->target_dev = devid; 2066 dma_dom->target_dev = devid;
2067 2067
2068 attach_device(iommu, &dma_dom->domain, devid);
2069 if (__devid != devid)
2070 attach_device(iommu, &dma_dom->domain, __devid);
2071
2068 list_add_tail(&dma_dom->list, &iommu_pd_list); 2072 list_add_tail(&dma_dom->list, &iommu_pd_list);
2069 } 2073 }
2070} 2074}