summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2009-11-23 12:50:00 +0100
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-18 13:43:38 -0800
commit8126ef0cb78bd3c269566b275e631a4c94f0bede (patch)
treefc974ce2ee8d73acfb812314164a2650698ded5b /arch
parentba585c2b49ddcbfe80d59f7e85251da800dea5d9 (diff)
downloadlwn-8126ef0cb78bd3c269566b275e631a4c94f0bede.tar.gz
lwn-8126ef0cb78bd3c269566b275e631a4c94f0bede.zip
x86/amd-iommu: attach devices to pre-allocated domains early
commit be831297716036de5b24308447ecb69f1706a846 upstream. 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. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
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 f5cb46a09e60..d7be38c297b0 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -1873,10 +1873,10 @@ static void prealloc_protection_domains(void)
struct pci_dev *dev = NULL;
struct dma_ops_domain *dma_dom;
struct amd_iommu *iommu;
- u16 devid;
+ u16 devid, __devid;
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- devid = calc_devid(dev->bus->number, dev->devfn);
+ __devid = devid = calc_devid(dev->bus->number, dev->devfn);
if (devid > amd_iommu_last_bdf)
continue;
devid = amd_iommu_alias_table[devid];
@@ -1891,6 +1891,10 @@ static void prealloc_protection_domains(void)
init_unity_mappings_for_device(dma_dom, devid);
dma_dom->target_dev = devid;
+ attach_device(iommu, &dma_dom->domain, devid);
+ if (__devid != devid)
+ attach_device(iommu, &dma_dom->domain, __devid);
+
list_add_tail(&dma_dom->list, &iommu_pd_list);
}
}