diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2009-11-11 20:08:46 +1100 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2009-11-11 20:08:46 +1100 |
commit | c75429b46af611833c4c0dcb7929cfccd03b4e92 (patch) | |
tree | aa22f5204162ae57c9acf2cd8f4a3466d769b489 | |
parent | cd1af99a4e38a84740d3650a8fe18d39fe922c23 (diff) |
Revert "x86: Handle HW IOMMU initialization failure gracefully"
This reverts commit 75f1cdf1dda92cae037ec848ae63690d91913eac.
-rw-r--r-- | arch/x86/include/asm/iommu.h | 1 | ||||
-rw-r--r-- | arch/x86/kernel/amd_iommu.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/amd_iommu_init.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/aperture_64.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/pci-calgary_64.c | 10 | ||||
-rw-r--r-- | arch/x86/kernel/pci-dma.c | 21 | ||||
-rw-r--r-- | arch/x86/kernel/pci-gart_64.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/pci-nommu.c | 9 | ||||
-rw-r--r-- | arch/x86/kernel/pci-swiotlb.c | 7 | ||||
-rw-r--r-- | drivers/pci/dmar.c | 3 | ||||
-rw-r--r-- | drivers/pci/intel-iommu.c | 6 | ||||
-rw-r--r-- | lib/swiotlb.c | 4 |
12 files changed, 39 insertions, 29 deletions
diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h index df42a712361f..878b30715766 100644 --- a/arch/x86/include/asm/iommu.h +++ b/arch/x86/include/asm/iommu.h @@ -2,6 +2,7 @@ #define _ASM_X86_IOMMU_H static inline void iommu_shutdown_noop(void) {} +extern void no_iommu_init(void); extern struct dma_map_ops nommu_dma_ops; extern int force_iommu, no_iommu; extern int iommu_detected; diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 66237fde758f..0285521e0a99 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -2110,8 +2110,8 @@ int __init amd_iommu_init_dma_ops(void) prealloc_protection_domains(); iommu_detected = 1; + force_iommu = 1; bad_dma_address = 0; - swiotlb = 0; #ifdef CONFIG_GART_IOMMU gart_iommu_aperture_disabled = 1; gart_iommu_aperture = 0; diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 0d4581e602a4..c41aabddaa2a 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -1330,7 +1330,7 @@ static int __init early_amd_iommu_detect(struct acpi_table_header *table) void __init amd_iommu_detect(void) { - if (no_iommu || (iommu_detected && !gart_iommu_aperture)) + if (swiotlb || no_iommu || (iommu_detected && !gart_iommu_aperture)) return; if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) { diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index e0dfb6856aa2..03933cf0b63c 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c @@ -458,7 +458,7 @@ out: if (aper_alloc) { /* Got the aperture from the AGP bridge */ - } else if (!valid_agp) { + } else if (swiotlb && !valid_agp) { /* Do nothing */ } else if ((!no_iommu && max_pfn > MAX_DMA32_PFN) || force_iommu || diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 833f491440b9..47bd419ea4d2 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c @@ -1360,7 +1360,7 @@ void __init detect_calgary(void) * if the user specified iommu=off or iommu=soft or we found * another HW IOMMU already, bail out. */ - if (no_iommu || iommu_detected) + if (swiotlb || no_iommu || iommu_detected) return; if (!use_calgary) @@ -1445,6 +1445,10 @@ void __init detect_calgary(void) printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d\n", specified_table_size); + /* swiotlb for devices that aren't behind the Calgary. */ + if (max_pfn > MAX_DMA32_PFN) + swiotlb = 1; + x86_init.iommu.iommu_init = calgary_iommu_init; } return; @@ -1472,7 +1476,11 @@ int __init calgary_iommu_init(void) return ret; } + force_iommu = 1; bad_dma_address = 0x0; + /* dma_ops is set to swiotlb or nommu */ + if (!dma_ops) + dma_ops = &nommu_dma_ops; return 0; } diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 835f09af77cf..5bd31553d2f2 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -123,26 +123,26 @@ static void __init dma32_free_bootmem(void) void __init pci_iommu_alloc(void) { - /* swiotlb is forced by the boot option */ - int use_swiotlb = swiotlb; #ifdef CONFIG_X86_64 /* free the range so iommu could get some range less than 4G */ dma32_free_bootmem(); #else dma_ops = &nommu_dma_ops; #endif - pci_swiotlb_init(); - if (use_swiotlb) - return; + /* + * The order of these functions is important for + * fall-back/fail-over reasons + */ gart_iommu_hole_init(); detect_calgary(); detect_intel_iommu(); - /* needs to be called after gart_iommu_hole_init */ amd_iommu_detect(); + + pci_swiotlb_init(); } void *dma_generic_alloc_coherent(struct device *dev, size_t size, @@ -292,15 +292,10 @@ static int __init pci_iommu_init(void) #ifdef CONFIG_PCI dma_debug_add_bus(&pci_bus_type); #endif - x86_init.iommu.iommu_init(); - if (swiotlb) { - printk(KERN_INFO "PCI-DMA: " - "Using software bounce buffering for IO (SWIOTLB)\n"); - swiotlb_print_info(); - } else - swiotlb_free(); + x86_init.iommu.iommu_init(); + no_iommu_init(); return 0; } /* Must execute after PCI subsystem */ diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index 919182e15d1e..0410bd30060d 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -833,7 +833,6 @@ int __init gart_iommu_init(void) flush_gart(); dma_ops = &gart_dma_ops; x86_platform.iommu_shutdown = gart_iommu_shutdown; - swiotlb = 0; return 0; } diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c index 875e3822ae61..a3933d4330cd 100644 --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c @@ -103,3 +103,12 @@ struct dma_map_ops nommu_dma_ops = { .sync_sg_for_device = nommu_sync_sg_for_device, .is_phys = 1, }; + +void __init no_iommu_init(void) +{ + if (dma_ops) + return; + + force_iommu = 0; /* no HW IOMMU */ + dma_ops = &nommu_dma_ops; +} diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c index 17ce4221bd03..ea20ef7ca523 100644 --- a/arch/x86/kernel/pci-swiotlb.c +++ b/arch/x86/kernel/pci-swiotlb.c @@ -46,12 +46,13 @@ void __init pci_swiotlb_init(void) { /* don't initialize swiotlb if iommu=off (no_iommu=1) */ #ifdef CONFIG_X86_64 - if (!no_iommu && max_pfn > MAX_DMA32_PFN) + if ((!iommu_detected && !no_iommu && max_pfn > MAX_DMA32_PFN)) swiotlb = 1; #endif + if (swiotlb_force) + swiotlb = 1; if (swiotlb) { swiotlb_init(0); dma_ops = &swiotlb_dma_ops; - } else - dma_ops = &nommu_dma_ops; + } } diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index bab8c6e1ee6f..09598c8feb4d 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -644,7 +644,8 @@ void __init detect_intel_iommu(void) "x2apic and Intr-remapping.\n"); #endif #ifdef CONFIG_DMAR - if (ret && !no_iommu && !iommu_detected && !dmar_disabled) + if (ret && !no_iommu && !iommu_detected && !swiotlb && + !dmar_disabled) iommu_detected = 1; #endif #ifdef CONFIG_X86 diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 34c8bbe6f9ec..c83113646223 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -3240,7 +3240,7 @@ int __init intel_iommu_init(void) * Check the need for DMA-remapping initialization now. * Above initialization will also be used by Interrupt-remapping. */ - if (no_iommu || dmar_disabled) + if (no_iommu || swiotlb || dmar_disabled) return -ENODEV; iommu_init_mempool(); @@ -3261,9 +3261,7 @@ int __init intel_iommu_init(void) "PCI-DMA: Intel(R) Virtualization Technology for Directed I/O\n"); init_timer(&unmap_timer); -#ifdef CONFIG_SWIOTLB - swiotlb = 0; -#endif + force_iommu = 1; dma_ops = &intel_dma_ops; init_iommu_sysfs(); diff --git a/lib/swiotlb.c b/lib/swiotlb.c index e6755a0574fb..0c12d7cce300 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -109,10 +109,8 @@ setup_io_tlb_npages(char *str) } if (*str == ',') ++str; - if (!strcmp(str, "force")) { + if (!strcmp(str, "force")) swiotlb_force = 1; - swiotlb = 1; - } return 1; } __setup("swiotlb=", setup_io_tlb_npages); |