aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2009-11-10 05:46:20 -0500
committerIngo Molnar <mingo@elte.hu>2009-11-10 06:32:07 -0500
commit75f1cdf1dda92cae037ec848ae63690d91913eac (patch)
tree9c12705002ebfa2d75333c20a19d0ac15f1db1d9 /drivers
parentad32e8cb86e7894aac51c8963eaa9f36bb8a4e14 (diff)
x86: Handle HW IOMMU initialization failure gracefully
If HW IOMMU initialization fails (Intel VT-d often does this, typically due to BIOS bugs), we fall back to nommu. It doesn't work for the majority since nowadays we have more than 4GB memory so we must use swiotlb instead of nommu. The problem is that it's too late to initialize swiotlb when HW IOMMU initialization fails. We need to allocate swiotlb memory earlier from bootmem allocator. Chris explained the issue in detail: http://marc.info/?l=linux-kernel&m=125657444317079&w=2 The current x86 IOMMU initialization sequence is too complicated and handling the above issue makes it more hacky. This patch changes x86 IOMMU initialization sequence to handle the above issue cleanly. The new x86 IOMMU initialization sequence are: 1. we initialize the swiotlb (and setting swiotlb to 1) in the case of (max_pfn > MAX_DMA32_PFN && !no_iommu). dma_ops is set to swiotlb_dma_ops or nommu_dma_ops. if swiotlb usage is forced by the boot option, we finish here. 2. we call the detection functions of all the IOMMUs 3. the detection function sets x86_init.iommu.iommu_init to the IOMMU initialization function (so we can avoid calling the initialization functions of all the IOMMUs needlessly). 4. if the IOMMU initialization function doesn't need to swiotlb then sets swiotlb to zero (e.g. the initialization is sucessful). 5. if we find that swiotlb is set to zero, we free swiotlb resource. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: chrisw@sous-sol.org Cc: dwmw2@infradead.org Cc: joerg.roedel@amd.com Cc: muli@il.ibm.com LKML-Reference: <1257849980-22640-10-git-send-email-fujita.tomonori@lab.ntt.co.jp> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/dmar.c3
-rw-r--r--drivers/pci/intel-iommu.c6
2 files changed, 5 insertions, 4 deletions
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index bce9cd7c755a..437399667e5a 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -613,8 +613,7 @@ void __init detect_intel_iommu(void)
613 "x2apic and Intr-remapping.\n"); 613 "x2apic and Intr-remapping.\n");
614#endif 614#endif
615#ifdef CONFIG_DMAR 615#ifdef CONFIG_DMAR
616 if (ret && !no_iommu && !iommu_detected && !swiotlb && 616 if (ret && !no_iommu && !iommu_detected && !dmar_disabled)
617 !dmar_disabled)
618 iommu_detected = 1; 617 iommu_detected = 1;
619#endif 618#endif
620#ifdef CONFIG_X86 619#ifdef CONFIG_X86
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index b1e97e682500..43d755a2e14a 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -3231,7 +3231,7 @@ int __init intel_iommu_init(void)
3231 * Check the need for DMA-remapping initialization now. 3231 * Check the need for DMA-remapping initialization now.
3232 * Above initialization will also be used by Interrupt-remapping. 3232 * Above initialization will also be used by Interrupt-remapping.
3233 */ 3233 */
3234 if (no_iommu || swiotlb || dmar_disabled) 3234 if (no_iommu || dmar_disabled)
3235 return -ENODEV; 3235 return -ENODEV;
3236 3236
3237 iommu_init_mempool(); 3237 iommu_init_mempool();
@@ -3252,7 +3252,9 @@ int __init intel_iommu_init(void)
3252 "PCI-DMA: Intel(R) Virtualization Technology for Directed I/O\n"); 3252 "PCI-DMA: Intel(R) Virtualization Technology for Directed I/O\n");
3253 3253
3254 init_timer(&unmap_timer); 3254 init_timer(&unmap_timer);
3255 force_iommu = 1; 3255#ifdef CONFIG_SWIOTLB
3256 swiotlb = 0;
3257#endif
3256 dma_ops = &intel_dma_ops; 3258 dma_ops = &intel_dma_ops;
3257 3259
3258 init_iommu_sysfs(); 3260 init_iommu_sysfs();