Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

x86: remove the IOMMU table infrastructure

The IOMMU table tries to separate the different IOMMUs into different
backends, but actually requires various cross calls.

Rewrite the code to do the generic swiotlb/swiotlb-xen setup directly
in pci-dma.c and then just call into the IOMMU drivers.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>

+110 -459
-7
arch/ia64/include/asm/iommu_table.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef _ASM_IA64_IOMMU_TABLE_H 3 - #define _ASM_IA64_IOMMU_TABLE_H 4 - 5 - #define IOMMU_INIT_POST(_detect) 6 - 7 - #endif /* _ASM_IA64_IOMMU_TABLE_H */
-1
arch/x86/include/asm/dma-mapping.h
··· 9 9 10 10 #include <linux/scatterlist.h> 11 11 #include <asm/io.h> 12 - #include <asm/swiotlb.h> 13 12 14 13 extern int iommu_merge; 15 14 extern int panic_on_overflow;
+2 -3
arch/x86/include/asm/gart.h
··· 38 38 extern void early_gart_iommu_check(void); 39 39 extern int gart_iommu_init(void); 40 40 extern void __init gart_parse_options(char *); 41 - extern int gart_iommu_hole_init(void); 41 + void gart_iommu_hole_init(void); 42 42 43 43 #else 44 44 #define gart_iommu_aperture 0 ··· 51 51 static inline void gart_parse_options(char *options) 52 52 { 53 53 } 54 - static inline int gart_iommu_hole_init(void) 54 + static inline void gart_iommu_hole_init(void) 55 55 { 56 - return -ENODEV; 57 56 } 58 57 #endif 59 58
+6
arch/x86/include/asm/iommu.h
··· 9 9 extern int force_iommu, no_iommu; 10 10 extern int iommu_detected; 11 11 12 + #ifdef CONFIG_SWIOTLB 13 + extern bool x86_swiotlb_enable; 14 + #else 15 + #define x86_swiotlb_enable false 16 + #endif 17 + 12 18 /* 10 seconds */ 13 19 #define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) 14 20
-102
arch/x86/include/asm/iommu_table.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef _ASM_X86_IOMMU_TABLE_H 3 - #define _ASM_X86_IOMMU_TABLE_H 4 - 5 - #include <asm/swiotlb.h> 6 - 7 - /* 8 - * History lesson: 9 - * The execution chain of IOMMUs in 2.6.36 looks as so: 10 - * 11 - * [xen-swiotlb] 12 - * | 13 - * +----[swiotlb *]--+ 14 - * / | \ 15 - * / | \ 16 - * [GART] [Calgary] [Intel VT-d] 17 - * / 18 - * / 19 - * [AMD-Vi] 20 - * 21 - * *: if SWIOTLB detected 'iommu=soft'/'swiotlb=force' it would skip 22 - * over the rest of IOMMUs and unconditionally initialize the SWIOTLB. 23 - * Also it would surreptitiously initialize set the swiotlb=1 if there were 24 - * more than 4GB and if the user did not pass in 'iommu=off'. The swiotlb 25 - * flag would be turned off by all IOMMUs except the Calgary one. 26 - * 27 - * The IOMMU_INIT* macros allow a similar tree (or more complex if desired) 28 - * to be built by defining who we depend on. 29 - * 30 - * And all that needs to be done is to use one of the macros in the IOMMU 31 - * and the pci-dma.c will take care of the rest. 32 - */ 33 - 34 - struct iommu_table_entry { 35 - initcall_t detect; 36 - initcall_t depend; 37 - void (*early_init)(void); /* No memory allocate available. */ 38 - void (*late_init)(void); /* Yes, can allocate memory. */ 39 - #define IOMMU_FINISH_IF_DETECTED (1<<0) 40 - #define IOMMU_DETECTED (1<<1) 41 - int flags; 42 - }; 43 - /* 44 - * Macro fills out an entry in the .iommu_table that is equivalent 45 - * to the fields that 'struct iommu_table_entry' has. The entries 46 - * that are put in the .iommu_table section are not put in any order 47 - * hence during boot-time we will have to resort them based on 48 - * dependency. */ 49 - 50 - 51 - #define __IOMMU_INIT(_detect, _depend, _early_init, _late_init, _finish)\ 52 - static const struct iommu_table_entry \ 53 - __iommu_entry_##_detect __used \ 54 - __attribute__ ((unused, __section__(".iommu_table"), \ 55 - aligned((sizeof(void *))))) \ 56 - = {_detect, _depend, _early_init, _late_init, \ 57 - _finish ? IOMMU_FINISH_IF_DETECTED : 0} 58 - /* 59 - * The simplest IOMMU definition. Provide the detection routine 60 - * and it will be run after the SWIOTLB and the other IOMMUs 61 - * that utilize this macro. If the IOMMU is detected (ie, the 62 - * detect routine returns a positive value), the other IOMMUs 63 - * are also checked. You can use IOMMU_INIT_POST_FINISH if you prefer 64 - * to stop detecting the other IOMMUs after yours has been detected. 65 - */ 66 - #define IOMMU_INIT_POST(_detect) \ 67 - __IOMMU_INIT(_detect, pci_swiotlb_detect_4gb, NULL, NULL, 0) 68 - 69 - #define IOMMU_INIT_POST_FINISH(detect) \ 70 - __IOMMU_INIT(_detect, pci_swiotlb_detect_4gb, NULL, NULL, 1) 71 - 72 - /* 73 - * A more sophisticated version of IOMMU_INIT. This variant requires: 74 - * a). A detection routine function. 75 - * b). The name of the detection routine we depend on to get called 76 - * before us. 77 - * c). The init routine which gets called if the detection routine 78 - * returns a positive value from the pci_iommu_alloc. This means 79 - * no presence of a memory allocator. 80 - * d). Similar to the 'init', except that this gets called from pci_iommu_init 81 - * where we do have a memory allocator. 82 - * 83 - * The standard IOMMU_INIT differs from the IOMMU_INIT_FINISH variant 84 - * in that the former will continue detecting other IOMMUs in the call 85 - * list after the detection routine returns a positive number, while the 86 - * latter will stop the execution chain upon first successful detection. 87 - * Both variants will still call the 'init' and 'late_init' functions if 88 - * they are set. 89 - */ 90 - #define IOMMU_INIT_FINISH(_detect, _depend, _init, _late_init) \ 91 - __IOMMU_INIT(_detect, _depend, _init, _late_init, 1) 92 - 93 - #define IOMMU_INIT(_detect, _depend, _init, _late_init) \ 94 - __IOMMU_INIT(_detect, _depend, _init, _late_init, 0) 95 - 96 - void sort_iommu_table(struct iommu_table_entry *start, 97 - struct iommu_table_entry *finish); 98 - 99 - void check_iommu_entries(struct iommu_table_entry *start, 100 - struct iommu_table_entry *finish); 101 - 102 - #endif /* _ASM_X86_IOMMU_TABLE_H */
-30
arch/x86/include/asm/swiotlb.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef _ASM_X86_SWIOTLB_H 3 - #define _ASM_X86_SWIOTLB_H 4 - 5 - #include <linux/swiotlb.h> 6 - 7 - #ifdef CONFIG_SWIOTLB 8 - extern int swiotlb; 9 - extern int __init pci_swiotlb_detect_override(void); 10 - extern int __init pci_swiotlb_detect_4gb(void); 11 - extern void __init pci_swiotlb_init(void); 12 - extern void __init pci_swiotlb_late_init(void); 13 - #else 14 - #define swiotlb 0 15 - static inline int pci_swiotlb_detect_override(void) 16 - { 17 - return 0; 18 - } 19 - static inline int pci_swiotlb_detect_4gb(void) 20 - { 21 - return 0; 22 - } 23 - static inline void pci_swiotlb_init(void) 24 - { 25 - } 26 - static inline void pci_swiotlb_late_init(void) 27 - { 28 - } 29 - #endif 30 - #endif /* _ASM_X86_SWIOTLB_H */
-2
arch/x86/include/asm/xen/swiotlb-xen.h
··· 3 3 #define _ASM_X86_SWIOTLB_XEN_H 4 4 5 5 #ifdef CONFIG_SWIOTLB_XEN 6 - extern int __init pci_xen_swiotlb_detect(void); 7 6 extern int pci_xen_swiotlb_init_late(void); 8 7 #else 9 - #define pci_xen_swiotlb_detect NULL 10 8 static inline int pci_xen_swiotlb_init_late(void) { return -ENXIO; } 11 9 #endif 12 10
-2
arch/x86/kernel/Makefile
··· 68 68 obj-y += pci-dma.o quirks.o topology.o kdebugfs.o 69 69 obj-y += alternative.o i8253.o hw_breakpoint.o 70 70 obj-y += tsc.o tsc_msr.o io_delay.o rtc.o 71 - obj-y += pci-iommu_table.o 72 71 obj-y += resource.o 73 72 obj-y += irqflags.o 74 73 obj-y += static_call.o ··· 133 134 134 135 obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o 135 136 136 - obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o 137 137 obj-$(CONFIG_OF) += devicetree.o 138 138 obj-$(CONFIG_UPROBES) += uprobes.o 139 139
+1 -4
arch/x86/kernel/amd_gart_64.c
··· 38 38 #include <asm/iommu.h> 39 39 #include <asm/gart.h> 40 40 #include <asm/set_memory.h> 41 - #include <asm/swiotlb.h> 42 41 #include <asm/dma.h> 43 42 #include <asm/amd_nb.h> 44 43 #include <asm/x86_init.h> 45 - #include <asm/iommu_table.h> 46 44 47 45 static unsigned long iommu_bus_base; /* GART remapping area (physical) */ 48 46 static unsigned long iommu_size; /* size of remapping area bytes */ ··· 806 808 flush_gart(); 807 809 dma_ops = &gart_dma_ops; 808 810 x86_platform.iommu_shutdown = gart_iommu_shutdown; 809 - swiotlb = 0; 811 + x86_swiotlb_enable = false; 810 812 811 813 return 0; 812 814 } ··· 840 842 } 841 843 } 842 844 } 843 - IOMMU_INIT_POST(gart_iommu_hole_init);
+5 -9
arch/x86/kernel/aperture_64.c
··· 392 392 393 393 static int __initdata printed_gart_size_msg; 394 394 395 - int __init gart_iommu_hole_init(void) 395 + void __init gart_iommu_hole_init(void) 396 396 { 397 397 u32 agp_aper_base = 0, agp_aper_order = 0; 398 398 u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0; ··· 401 401 int i, node; 402 402 403 403 if (!amd_gart_present()) 404 - return -ENODEV; 404 + return; 405 405 406 406 if (gart_iommu_aperture_disabled || !fix_aperture || 407 407 !early_pci_allowed()) 408 - return -ENODEV; 408 + return; 409 409 410 410 pr_info("Checking aperture...\n"); 411 411 ··· 491 491 * and fixed up the northbridge 492 492 */ 493 493 exclude_from_core(last_aper_base, last_aper_order); 494 - 495 - return 1; 496 494 } 497 - return 0; 495 + return; 498 496 } 499 497 500 498 if (!fallback_aper_force) { ··· 525 527 panic("Not enough memory for aperture"); 526 528 } 527 529 } else { 528 - return 0; 530 + return; 529 531 } 530 532 531 533 /* ··· 559 561 } 560 562 561 563 set_up_gart_resume(aper_order, aper_alloc); 562 - 563 - return 1; 564 564 }
+86 -21
arch/x86/kernel/pci-dma.c
··· 7 7 #include <linux/memblock.h> 8 8 #include <linux/gfp.h> 9 9 #include <linux/pci.h> 10 + #include <linux/amd-iommu.h> 10 11 11 12 #include <asm/proto.h> 12 13 #include <asm/dma.h> 13 14 #include <asm/iommu.h> 14 15 #include <asm/gart.h> 15 16 #include <asm/x86_init.h> 16 - #include <asm/iommu_table.h> 17 + 18 + #include <xen/xen.h> 19 + #include <xen/swiotlb-xen.h> 17 20 18 21 static bool disable_dac_quirk __read_mostly; 19 22 ··· 37 34 /* Set this to 1 if there is a HW IOMMU in the system */ 38 35 int iommu_detected __read_mostly = 0; 39 36 40 - extern struct iommu_table_entry __iommu_table[], __iommu_table_end[]; 37 + #ifdef CONFIG_SWIOTLB 38 + bool x86_swiotlb_enable; 39 + 40 + static void __init pci_swiotlb_detect(void) 41 + { 42 + /* don't initialize swiotlb if iommu=off (no_iommu=1) */ 43 + if (!no_iommu && max_possible_pfn > MAX_DMA32_PFN) 44 + x86_swiotlb_enable = true; 45 + 46 + /* 47 + * Set swiotlb to 1 so that bounce buffers are allocated and used for 48 + * devices that can't support DMA to encrypted memory. 49 + */ 50 + if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) 51 + x86_swiotlb_enable = true; 52 + 53 + if (swiotlb_force == SWIOTLB_FORCE) 54 + x86_swiotlb_enable = true; 55 + } 56 + #else 57 + static inline void __init pci_swiotlb_detect(void) 58 + { 59 + } 60 + #endif /* CONFIG_SWIOTLB */ 61 + 62 + #ifdef CONFIG_SWIOTLB_XEN 63 + static bool xen_swiotlb; 64 + 65 + static void __init pci_xen_swiotlb_init(void) 66 + { 67 + if (!xen_initial_domain() && !x86_swiotlb_enable && 68 + swiotlb_force != SWIOTLB_FORCE) 69 + return; 70 + x86_swiotlb_enable = true; 71 + xen_swiotlb = true; 72 + xen_swiotlb_init_early(); 73 + dma_ops = &xen_swiotlb_dma_ops; 74 + if (IS_ENABLED(CONFIG_PCI)) 75 + pci_request_acs(); 76 + } 77 + 78 + int pci_xen_swiotlb_init_late(void) 79 + { 80 + int rc; 81 + 82 + if (xen_swiotlb) 83 + return 0; 84 + 85 + rc = xen_swiotlb_init(); 86 + if (rc) 87 + return rc; 88 + 89 + /* XXX: this switches the dma ops under live devices! */ 90 + dma_ops = &xen_swiotlb_dma_ops; 91 + if (IS_ENABLED(CONFIG_PCI)) 92 + pci_request_acs(); 93 + return 0; 94 + } 95 + EXPORT_SYMBOL_GPL(pci_xen_swiotlb_init_late); 96 + #else 97 + static inline void __init pci_xen_swiotlb_init(void) 98 + { 99 + } 100 + #endif /* CONFIG_SWIOTLB_XEN */ 41 101 42 102 void __init pci_iommu_alloc(void) 43 103 { 44 - struct iommu_table_entry *p; 45 - 46 - sort_iommu_table(__iommu_table, __iommu_table_end); 47 - check_iommu_entries(__iommu_table, __iommu_table_end); 48 - 49 - for (p = __iommu_table; p < __iommu_table_end; p++) { 50 - if (p && p->detect && p->detect() > 0) { 51 - p->flags |= IOMMU_DETECTED; 52 - if (p->early_init) 53 - p->early_init(); 54 - if (p->flags & IOMMU_FINISH_IF_DETECTED) 55 - break; 56 - } 104 + if (xen_pv_domain()) { 105 + pci_xen_swiotlb_init(); 106 + return; 57 107 } 108 + pci_swiotlb_detect(); 109 + gart_iommu_hole_init(); 110 + amd_iommu_detect(); 111 + detect_intel_iommu(); 112 + if (x86_swiotlb_enable) 113 + swiotlb_init(0); 58 114 } 59 115 60 116 /* ··· 164 102 } 165 103 #ifdef CONFIG_SWIOTLB 166 104 if (!strncmp(p, "soft", 4)) 167 - swiotlb = 1; 105 + x86_swiotlb_enable = true; 168 106 #endif 169 107 if (!strncmp(p, "pt", 2)) 170 108 iommu_set_default_passthrough(true); ··· 183 121 184 122 static int __init pci_iommu_init(void) 185 123 { 186 - struct iommu_table_entry *p; 187 - 188 124 x86_init.iommu.iommu_init(); 189 125 190 - for (p = __iommu_table; p < __iommu_table_end; p++) { 191 - if (p && (p->flags & IOMMU_DETECTED) && p->late_init) 192 - p->late_init(); 126 + #ifdef CONFIG_SWIOTLB 127 + /* An IOMMU turned us off. */ 128 + if (x86_swiotlb_enable) { 129 + pr_info("PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\n"); 130 + swiotlb_print_info(); 131 + } else { 132 + swiotlb_exit(); 193 133 } 134 + #endif 194 135 195 136 return 0; 196 137 }
-77
arch/x86/kernel/pci-iommu_table.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - #include <linux/dma-mapping.h> 3 - #include <asm/iommu_table.h> 4 - #include <linux/string.h> 5 - #include <linux/kallsyms.h> 6 - 7 - static struct iommu_table_entry * __init 8 - find_dependents_of(struct iommu_table_entry *start, 9 - struct iommu_table_entry *finish, 10 - struct iommu_table_entry *q) 11 - { 12 - struct iommu_table_entry *p; 13 - 14 - if (!q) 15 - return NULL; 16 - 17 - for (p = start; p < finish; p++) 18 - if (p->detect == q->depend) 19 - return p; 20 - 21 - return NULL; 22 - } 23 - 24 - 25 - void __init sort_iommu_table(struct iommu_table_entry *start, 26 - struct iommu_table_entry *finish) { 27 - 28 - struct iommu_table_entry *p, *q, tmp; 29 - 30 - for (p = start; p < finish; p++) { 31 - again: 32 - q = find_dependents_of(start, finish, p); 33 - /* We are bit sneaky here. We use the memory address to figure 34 - * out if the node we depend on is past our point, if so, swap. 35 - */ 36 - if (q > p) { 37 - tmp = *p; 38 - memmove(p, q, sizeof(*p)); 39 - *q = tmp; 40 - goto again; 41 - } 42 - } 43 - 44 - } 45 - 46 - #ifdef DEBUG 47 - void __init check_iommu_entries(struct iommu_table_entry *start, 48 - struct iommu_table_entry *finish) 49 - { 50 - struct iommu_table_entry *p, *q, *x; 51 - 52 - /* Simple cyclic dependency checker. */ 53 - for (p = start; p < finish; p++) { 54 - q = find_dependents_of(start, finish, p); 55 - x = find_dependents_of(start, finish, q); 56 - if (p == x) { 57 - printk(KERN_ERR "CYCLIC DEPENDENCY FOUND! %pS depends on %pS and vice-versa. BREAKING IT.\n", 58 - p->detect, q->detect); 59 - /* Heavy handed way..*/ 60 - x->depend = NULL; 61 - } 62 - } 63 - 64 - for (p = start; p < finish; p++) { 65 - q = find_dependents_of(p, finish, p); 66 - if (q && q > p) { 67 - printk(KERN_ERR "EXECUTION ORDER INVALID! %pS should be called before %pS!\n", 68 - p->detect, q->detect); 69 - } 70 - } 71 - } 72 - #else 73 - void __init check_iommu_entries(struct iommu_table_entry *start, 74 - struct iommu_table_entry *finish) 75 - { 76 - } 77 - #endif
-77
arch/x86/kernel/pci-swiotlb.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - 3 - #include <linux/pci.h> 4 - #include <linux/cache.h> 5 - #include <linux/init.h> 6 - #include <linux/swiotlb.h> 7 - #include <linux/memblock.h> 8 - #include <linux/dma-direct.h> 9 - #include <linux/cc_platform.h> 10 - 11 - #include <asm/iommu.h> 12 - #include <asm/swiotlb.h> 13 - #include <asm/dma.h> 14 - #include <asm/xen/swiotlb-xen.h> 15 - #include <asm/iommu_table.h> 16 - 17 - int swiotlb __read_mostly; 18 - 19 - /* 20 - * pci_swiotlb_detect_override - set swiotlb to 1 if necessary 21 - * 22 - * This returns non-zero if we are forced to use swiotlb (by the boot 23 - * option). 24 - */ 25 - int __init pci_swiotlb_detect_override(void) 26 - { 27 - if (swiotlb_force == SWIOTLB_FORCE) 28 - swiotlb = 1; 29 - 30 - return swiotlb; 31 - } 32 - IOMMU_INIT_FINISH(pci_swiotlb_detect_override, 33 - pci_xen_swiotlb_detect, 34 - pci_swiotlb_init, 35 - pci_swiotlb_late_init); 36 - 37 - /* 38 - * If 4GB or more detected (and iommu=off not set) or if SME is active 39 - * then set swiotlb to 1 and return 1. 40 - */ 41 - int __init pci_swiotlb_detect_4gb(void) 42 - { 43 - /* don't initialize swiotlb if iommu=off (no_iommu=1) */ 44 - if (!no_iommu && max_possible_pfn > MAX_DMA32_PFN) 45 - swiotlb = 1; 46 - 47 - /* 48 - * Set swiotlb to 1 so that bounce buffers are allocated and used for 49 - * devices that can't support DMA to encrypted memory. 50 - */ 51 - if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) 52 - swiotlb = 1; 53 - 54 - return swiotlb; 55 - } 56 - IOMMU_INIT(pci_swiotlb_detect_4gb, 57 - pci_swiotlb_detect_override, 58 - pci_swiotlb_init, 59 - pci_swiotlb_late_init); 60 - 61 - void __init pci_swiotlb_init(void) 62 - { 63 - if (swiotlb) 64 - swiotlb_init(0); 65 - } 66 - 67 - void __init pci_swiotlb_late_init(void) 68 - { 69 - /* An IOMMU turned us off. */ 70 - if (!swiotlb) 71 - swiotlb_exit(); 72 - else { 73 - printk(KERN_INFO "PCI-DMA: " 74 - "Using software bounce buffering for IO (SWIOTLB)\n"); 75 - swiotlb_print_info(); 76 - } 77 - }
-1
arch/x86/kernel/tboot.c
··· 24 24 #include <asm/processor.h> 25 25 #include <asm/bootparam.h> 26 26 #include <asm/pgalloc.h> 27 - #include <asm/swiotlb.h> 28 27 #include <asm/fixmap.h> 29 28 #include <asm/proto.h> 30 29 #include <asm/setup.h>
-12
arch/x86/kernel/vmlinux.lds.S
··· 315 315 *(.altinstr_replacement) 316 316 } 317 317 318 - /* 319 - * struct iommu_table_entry entries are injected in this section. 320 - * It is an array of IOMMUs which during run time gets sorted depending 321 - * on its dependency order. After rootfs_initcall is complete 322 - * this section can be safely removed. 323 - */ 324 - .iommu_table : AT(ADDR(.iommu_table) - LOAD_OFFSET) { 325 - __iommu_table = .; 326 - *(.iommu_table) 327 - __iommu_table_end = .; 328 - } 329 - 330 318 . = ALIGN(8); 331 319 .apicdrivers : AT(ADDR(.apicdrivers) - LOAD_OFFSET) { 332 320 __apicdrivers = .;
-2
arch/x86/xen/Makefile
··· 47 47 48 48 obj-$(CONFIG_XEN_PV_DOM0) += vga.o 49 49 50 - obj-$(CONFIG_SWIOTLB_XEN) += pci-swiotlb-xen.o 51 - 52 50 obj-$(CONFIG_XEN_EFI) += efi.o
-96
arch/x86/xen/pci-swiotlb-xen.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - 3 - /* Glue code to lib/swiotlb-xen.c */ 4 - 5 - #include <linux/dma-map-ops.h> 6 - #include <linux/pci.h> 7 - #include <xen/swiotlb-xen.h> 8 - 9 - #include <asm/xen/hypervisor.h> 10 - #include <xen/xen.h> 11 - #include <asm/iommu_table.h> 12 - 13 - 14 - #include <asm/xen/swiotlb-xen.h> 15 - #ifdef CONFIG_X86_64 16 - #include <asm/iommu.h> 17 - #include <asm/dma.h> 18 - #endif 19 - #include <linux/export.h> 20 - 21 - static int xen_swiotlb __read_mostly; 22 - 23 - /* 24 - * pci_xen_swiotlb_detect - set xen_swiotlb to 1 if necessary 25 - * 26 - * This returns non-zero if we are forced to use xen_swiotlb (by the boot 27 - * option). 28 - */ 29 - int __init pci_xen_swiotlb_detect(void) 30 - { 31 - 32 - if (!xen_pv_domain()) 33 - return 0; 34 - 35 - /* If running as PV guest, either iommu=soft, or swiotlb=force will 36 - * activate this IOMMU. If running as PV privileged, activate it 37 - * irregardless. 38 - */ 39 - if (xen_initial_domain() || swiotlb || swiotlb_force == SWIOTLB_FORCE) 40 - xen_swiotlb = 1; 41 - 42 - /* If we are running under Xen, we MUST disable the native SWIOTLB. 43 - * Don't worry about swiotlb_force flag activating the native, as 44 - * the 'swiotlb' flag is the only one turning it on. */ 45 - swiotlb = 0; 46 - 47 - #ifdef CONFIG_X86_64 48 - /* pci_swiotlb_detect_4gb turns on native SWIOTLB if no_iommu == 0 49 - * (so no iommu=X command line over-writes). 50 - * Considering that PV guests do not want the *native SWIOTLB* but 51 - * only Xen SWIOTLB it is not useful to us so set no_iommu=1 here. 52 - */ 53 - if (max_pfn > MAX_DMA32_PFN) 54 - no_iommu = 1; 55 - #endif 56 - return xen_swiotlb; 57 - } 58 - 59 - static void __init pci_xen_swiotlb_init(void) 60 - { 61 - if (xen_swiotlb) { 62 - xen_swiotlb_init_early(); 63 - dma_ops = &xen_swiotlb_dma_ops; 64 - 65 - #ifdef CONFIG_PCI 66 - /* Make sure ACS will be enabled */ 67 - pci_request_acs(); 68 - #endif 69 - } 70 - } 71 - 72 - int pci_xen_swiotlb_init_late(void) 73 - { 74 - int rc; 75 - 76 - if (xen_swiotlb) 77 - return 0; 78 - 79 - rc = xen_swiotlb_init(); 80 - if (rc) 81 - return rc; 82 - 83 - dma_ops = &xen_swiotlb_dma_ops; 84 - #ifdef CONFIG_PCI 85 - /* Make sure ACS will be enabled */ 86 - pci_request_acs(); 87 - #endif 88 - 89 - return 0; 90 - } 91 - EXPORT_SYMBOL_GPL(pci_xen_swiotlb_init_late); 92 - 93 - IOMMU_INIT_FINISH(pci_xen_swiotlb_detect, 94 - NULL, 95 - pci_xen_swiotlb_init, 96 - NULL);
-6
drivers/iommu/amd/init.c
··· 27 27 #include <asm/apic.h> 28 28 #include <asm/gart.h> 29 29 #include <asm/x86_init.h> 30 - #include <asm/iommu_table.h> 31 30 #include <asm/io_apic.h> 32 31 #include <asm/irq_remapping.h> 33 32 #include <asm/set_memory.h> ··· 3255 3256 __setup("ivrs_ioapic", parse_ivrs_ioapic); 3256 3257 __setup("ivrs_hpet", parse_ivrs_hpet); 3257 3258 __setup("ivrs_acpihid", parse_ivrs_acpihid); 3258 - 3259 - IOMMU_INIT_FINISH(amd_iommu_detect, 3260 - gart_iommu_hole_init, 3261 - NULL, 3262 - NULL); 3263 3259 3264 3260 bool amd_iommu_v2_supported(void) 3265 3261 {
+4 -1
drivers/iommu/amd/iommu.c
··· 1840 1840 1841 1841 static void __init amd_iommu_init_dma_ops(void) 1842 1842 { 1843 - swiotlb = (iommu_default_passthrough() || sme_me_mask) ? 1 : 0; 1843 + if (iommu_default_passthrough() || sme_me_mask) 1844 + x86_swiotlb_enable = true; 1845 + else 1846 + x86_swiotlb_enable = false; 1844 1847 } 1845 1848 1846 1849 int __init amd_iommu_init_api(void)
+1 -5
drivers/iommu/intel/dmar.c
··· 30 30 #include <linux/numa.h> 31 31 #include <linux/limits.h> 32 32 #include <asm/irq_remapping.h> 33 - #include <asm/iommu_table.h> 34 33 #include <trace/events/intel_iommu.h> 35 34 36 35 #include "../irq_remapping.h" ··· 911 912 return 0; 912 913 } 913 914 914 - int __init detect_intel_iommu(void) 915 + void __init detect_intel_iommu(void) 915 916 { 916 917 int ret; 917 918 struct dmar_res_callback validate_drhd_cb = { ··· 944 945 dmar_tbl = NULL; 945 946 } 946 947 up_write(&dmar_global_lock); 947 - 948 - return ret ? ret : 1; 949 948 } 950 949 951 950 static void unmap_iommu(struct intel_iommu *iommu) ··· 2161 2164 } 2162 2165 2163 2166 late_initcall(dmar_free_unused_resources); 2164 - IOMMU_INIT_POST(detect_intel_iommu); 2165 2167 2166 2168 /* 2167 2169 * DMAR Hotplug Support
+5 -1
include/linux/dmar.h
··· 121 121 u16 segment, struct dmar_dev_scope *devices, 122 122 int count); 123 123 /* Intel IOMMU detection */ 124 - extern int detect_intel_iommu(void); 124 + void detect_intel_iommu(void); 125 125 extern int enable_drhd_fault_handling(void); 126 126 extern int dmar_device_add(acpi_handle handle); 127 127 extern int dmar_device_remove(acpi_handle handle); ··· 195 195 static inline bool dmar_platform_optin(void) 196 196 { 197 197 return false; 198 + } 199 + 200 + static inline void detect_intel_iommu(void) 201 + { 198 202 } 199 203 200 204 #endif /* CONFIG_DMAR_TABLE */