diff options
| -rw-r--r-- | arch/ia64/include/asm/iommu_table.h | 6 | ||||
| -rw-r--r-- | arch/x86/include/asm/amd_iommu.h | 4 | ||||
| -rw-r--r-- | arch/x86/include/asm/calgary.h | 4 | ||||
| -rw-r--r-- | arch/x86/include/asm/gart.h | 5 | ||||
| -rw-r--r-- | arch/x86/include/asm/iommu_table.h | 100 | ||||
| -rw-r--r-- | arch/x86/include/asm/swiotlb.h | 13 | ||||
| -rw-r--r-- | arch/x86/kernel/Makefile | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/amd_iommu_init.c | 15 | ||||
| -rw-r--r-- | arch/x86/kernel/aperture_64.c | 11 | ||||
| -rw-r--r-- | arch/x86/kernel/pci-calgary_64.c | 18 | ||||
| -rw-r--r-- | arch/x86/kernel/pci-dma.c | 44 | ||||
| -rw-r--r-- | arch/x86/kernel/pci-gart_64.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/pci-iommu_table.c | 89 | ||||
| -rw-r--r-- | arch/x86/kernel/pci-swiotlb.c | 44 | ||||
| -rw-r--r-- | arch/x86/kernel/vmlinux.lds.S | 28 | ||||
| -rw-r--r-- | arch/x86/xen/pci-swiotlb-xen.c | 5 | ||||
| -rw-r--r-- | drivers/pci/dmar.c | 6 | ||||
| -rw-r--r-- | include/linux/dmar.h | 6 |
18 files changed, 344 insertions, 57 deletions
diff --git a/arch/ia64/include/asm/iommu_table.h b/arch/ia64/include/asm/iommu_table.h new file mode 100644 index 000000000000..92c8d36ae5ae --- /dev/null +++ b/arch/ia64/include/asm/iommu_table.h | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #ifndef _ASM_IA64_IOMMU_TABLE_H | ||
| 2 | #define _ASM_IA64_IOMMU_TABLE_H | ||
| 3 | |||
| 4 | #define IOMMU_INIT_POST(_detect) | ||
| 5 | |||
| 6 | #endif /* _ASM_IA64_IOMMU_TABLE_H */ | ||
diff --git a/arch/x86/include/asm/amd_iommu.h b/arch/x86/include/asm/amd_iommu.h index f16a2caca1e0..a6863a2dec1f 100644 --- a/arch/x86/include/asm/amd_iommu.h +++ b/arch/x86/include/asm/amd_iommu.h | |||
| @@ -24,11 +24,11 @@ | |||
| 24 | 24 | ||
| 25 | #ifdef CONFIG_AMD_IOMMU | 25 | #ifdef CONFIG_AMD_IOMMU |
| 26 | 26 | ||
| 27 | extern void amd_iommu_detect(void); | 27 | extern int amd_iommu_detect(void); |
| 28 | 28 | ||
| 29 | #else | 29 | #else |
| 30 | 30 | ||
| 31 | static inline void amd_iommu_detect(void) { } | 31 | static inline int amd_iommu_detect(void) { return -ENODEV; } |
| 32 | 32 | ||
| 33 | #endif | 33 | #endif |
| 34 | 34 | ||
diff --git a/arch/x86/include/asm/calgary.h b/arch/x86/include/asm/calgary.h index 0918654305af..0d467b338835 100644 --- a/arch/x86/include/asm/calgary.h +++ b/arch/x86/include/asm/calgary.h | |||
| @@ -62,9 +62,9 @@ struct cal_chipset_ops { | |||
| 62 | extern int use_calgary; | 62 | extern int use_calgary; |
| 63 | 63 | ||
| 64 | #ifdef CONFIG_CALGARY_IOMMU | 64 | #ifdef CONFIG_CALGARY_IOMMU |
| 65 | extern void detect_calgary(void); | 65 | extern int detect_calgary(void); |
| 66 | #else | 66 | #else |
| 67 | static inline void detect_calgary(void) { return; } | 67 | static inline int detect_calgary(void) { return -ENODEV; } |
| 68 | #endif | 68 | #endif |
| 69 | 69 | ||
| 70 | #endif /* _ASM_X86_CALGARY_H */ | 70 | #endif /* _ASM_X86_CALGARY_H */ |
diff --git a/arch/x86/include/asm/gart.h b/arch/x86/include/asm/gart.h index bf357f9b25f0..43085bfc99c3 100644 --- a/arch/x86/include/asm/gart.h +++ b/arch/x86/include/asm/gart.h | |||
| @@ -37,7 +37,7 @@ extern int gart_iommu_aperture_disabled; | |||
| 37 | extern void early_gart_iommu_check(void); | 37 | extern void early_gart_iommu_check(void); |
| 38 | extern int gart_iommu_init(void); | 38 | extern int gart_iommu_init(void); |
| 39 | extern void __init gart_parse_options(char *); | 39 | extern void __init gart_parse_options(char *); |
| 40 | extern void gart_iommu_hole_init(void); | 40 | extern int gart_iommu_hole_init(void); |
| 41 | 41 | ||
| 42 | #else | 42 | #else |
| 43 | #define gart_iommu_aperture 0 | 43 | #define gart_iommu_aperture 0 |
| @@ -50,8 +50,9 @@ static inline void early_gart_iommu_check(void) | |||
| 50 | static inline void gart_parse_options(char *options) | 50 | static inline void gart_parse_options(char *options) |
| 51 | { | 51 | { |
| 52 | } | 52 | } |
| 53 | static inline void gart_iommu_hole_init(void) | 53 | static inline int gart_iommu_hole_init(void) |
| 54 | { | 54 | { |
| 55 | return -ENODEV; | ||
| 55 | } | 56 | } |
| 56 | #endif | 57 | #endif |
| 57 | 58 | ||
diff --git a/arch/x86/include/asm/iommu_table.h b/arch/x86/include/asm/iommu_table.h new file mode 100644 index 000000000000..f229b13a5f30 --- /dev/null +++ b/arch/x86/include/asm/iommu_table.h | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | #ifndef _ASM_X86_IOMMU_TABLE_H | ||
| 2 | #define _ASM_X86_IOMMU_TABLE_H | ||
| 3 | |||
| 4 | #include <asm/swiotlb.h> | ||
| 5 | |||
| 6 | /* | ||
| 7 | * History lesson: | ||
| 8 | * The execution chain of IOMMUs in 2.6.36 looks as so: | ||
| 9 | * | ||
| 10 | * [xen-swiotlb] | ||
| 11 | * | | ||
| 12 | * +----[swiotlb *]--+ | ||
| 13 | * / | \ | ||
| 14 | * / | \ | ||
| 15 | * [GART] [Calgary] [Intel VT-d] | ||
| 16 | * / | ||
| 17 | * / | ||
| 18 | * [AMD-Vi] | ||
| 19 | * | ||
| 20 | * *: if SWIOTLB detected 'iommu=soft'/'swiotlb=force' it would skip | ||
| 21 | * over the rest of IOMMUs and unconditionally initialize the SWIOTLB. | ||
| 22 | * Also it would surreptitiously initialize set the swiotlb=1 if there were | ||
| 23 | * more than 4GB and if the user did not pass in 'iommu=off'. The swiotlb | ||
| 24 | * flag would be turned off by all IOMMUs except the Calgary one. | ||
| 25 | * | ||
| 26 | * The IOMMU_INIT* macros allow a similar tree (or more complex if desired) | ||
| 27 | * to be built by defining who we depend on. | ||
| 28 | * | ||
| 29 | * And all that needs to be done is to use one of the macros in the IOMMU | ||
| 30 | * and the pci-dma.c will take care of the rest. | ||
| 31 | */ | ||
| 32 | |||
| 33 | struct iommu_table_entry { | ||
| 34 | initcall_t detect; | ||
| 35 | initcall_t depend; | ||
| 36 | void (*early_init)(void); /* No memory allocate available. */ | ||
| 37 | void (*late_init)(void); /* Yes, can allocate memory. */ | ||
| 38 | #define IOMMU_FINISH_IF_DETECTED (1<<0) | ||
| 39 | #define IOMMU_DETECTED (1<<1) | ||
| 40 | int flags; | ||
| 41 | }; | ||
| 42 | /* | ||
| 43 | * Macro fills out an entry in the .iommu_table that is equivalent | ||
| 44 | * to the fields that 'struct iommu_table_entry' has. The entries | ||
| 45 | * that are put in the .iommu_table section are not put in any order | ||
| 46 | * hence during boot-time we will have to resort them based on | ||
| 47 | * dependency. */ | ||
| 48 | |||
| 49 | |||
| 50 | #define __IOMMU_INIT(_detect, _depend, _early_init, _late_init, _finish)\ | ||
| 51 | static const struct iommu_table_entry const \ | ||
| 52 | __iommu_entry_##_detect __used \ | ||
| 53 | __attribute__ ((unused, __section__(".iommu_table"), \ | ||
| 54 | aligned((sizeof(void *))))) \ | ||
| 55 | = {_detect, _depend, _early_init, _late_init, \ | ||
| 56 | _finish ? IOMMU_FINISH_IF_DETECTED : 0} | ||
| 57 | /* | ||
| 58 | * The simplest IOMMU definition. Provide the detection routine | ||
| 59 | * and it will be run after the SWIOTLB and the other IOMMUs | ||
| 60 | * that utilize this macro. If the IOMMU is detected (ie, the | ||
| 61 | * detect routine returns a positive value), the other IOMMUs | ||
| 62 | * are also checked. You can use IOMMU_INIT_POST_FINISH if you prefer | ||
| 63 | * to stop detecting the other IOMMUs after yours has been detected. | ||
| 64 | */ | ||
| 65 | #define IOMMU_INIT_POST(_detect) \ | ||
| 66 | __IOMMU_INIT(_detect, pci_swiotlb_detect_4gb, 0, 0, 0) | ||
| 67 | |||
| 68 | #define IOMMU_INIT_POST_FINISH(detect) \ | ||
| 69 | __IOMMU_INIT(_detect, pci_swiotlb_detect_4gb, 0, 0, 1) | ||
| 70 | |||
| 71 | /* | ||
| 72 | * A more sophisticated version of IOMMU_INIT. This variant requires: | ||
| 73 | * a). A detection routine function. | ||
| 74 | * b). The name of the detection routine we depend on to get called | ||
| 75 | * before us. | ||
| 76 | * c). The init routine which gets called if the detection routine | ||
| 77 | * returns a positive value from the pci_iommu_alloc. This means | ||
| 78 | * no presence of a memory allocator. | ||
| 79 | * d). Similar to the 'init', except that this gets called from pci_iommu_init | ||
| 80 | * where we do have a memory allocator. | ||
| 81 | * | ||
| 82 | * The standard vs the _FINISH differs in that the _FINISH variant will | ||
| 83 | * continue detecting other IOMMUs in the call list after the | ||
| 84 | * the detection routine returns a positive number. The _FINISH will | ||
| 85 | * stop the execution chain. Both will still call the 'init' and | ||
| 86 | * 'late_init' functions if they are set. | ||
| 87 | */ | ||
| 88 | #define IOMMU_INIT_FINISH(_detect, _depend, _init, _late_init) \ | ||
| 89 | __IOMMU_INIT(_detect, _depend, _init, _late_init, 1) | ||
| 90 | |||
| 91 | #define IOMMU_INIT(_detect, _depend, _init, _late_init) \ | ||
| 92 | __IOMMU_INIT(_detect, _depend, _init, _late_init, 0) | ||
| 93 | |||
| 94 | void sort_iommu_table(struct iommu_table_entry *start, | ||
| 95 | struct iommu_table_entry *finish); | ||
| 96 | |||
| 97 | void check_iommu_entries(struct iommu_table_entry *start, | ||
| 98 | struct iommu_table_entry *finish); | ||
| 99 | |||
| 100 | #endif /* _ASM_X86_IOMMU_TABLE_H */ | ||
diff --git a/arch/x86/include/asm/swiotlb.h b/arch/x86/include/asm/swiotlb.h index 8085277e1b8b..977f1761a25d 100644 --- a/arch/x86/include/asm/swiotlb.h +++ b/arch/x86/include/asm/swiotlb.h | |||
| @@ -5,17 +5,26 @@ | |||
| 5 | 5 | ||
| 6 | #ifdef CONFIG_SWIOTLB | 6 | #ifdef CONFIG_SWIOTLB |
| 7 | extern int swiotlb; | 7 | extern int swiotlb; |
| 8 | extern int __init pci_swiotlb_detect(void); | 8 | extern int __init pci_swiotlb_detect_override(void); |
| 9 | extern int __init pci_swiotlb_detect_4gb(void); | ||
| 9 | extern void __init pci_swiotlb_init(void); | 10 | extern void __init pci_swiotlb_init(void); |
| 11 | extern void __init pci_swiotlb_late_init(void); | ||
| 10 | #else | 12 | #else |
| 11 | #define swiotlb 0 | 13 | #define swiotlb 0 |
| 12 | static inline int pci_swiotlb_detect(void) | 14 | static inline int pci_swiotlb_detect_override(void) |
| 15 | { | ||
| 16 | return 0; | ||
| 17 | } | ||
| 18 | static inline int pci_swiotlb_detect_4gb(void) | ||
| 13 | { | 19 | { |
| 14 | return 0; | 20 | return 0; |
| 15 | } | 21 | } |
| 16 | static inline void pci_swiotlb_init(void) | 22 | static inline void pci_swiotlb_init(void) |
| 17 | { | 23 | { |
| 18 | } | 24 | } |
| 25 | static inline void pci_swiotlb_late_init(void) | ||
| 26 | { | ||
| 27 | } | ||
| 19 | #endif | 28 | #endif |
| 20 | 29 | ||
| 21 | static inline void dma_mark_clean(void *addr, size_t size) {} | 30 | static inline void dma_mark_clean(void *addr, size_t size) {} |
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 80a93dc99076..2c833d8c4141 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
| @@ -45,6 +45,7 @@ obj-y += bootflag.o e820.o | |||
| 45 | obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o | 45 | obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o |
| 46 | obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o | 46 | obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o |
| 47 | obj-y += tsc.o io_delay.o rtc.o | 47 | obj-y += tsc.o io_delay.o rtc.o |
| 48 | obj-y += pci-iommu_table.o | ||
| 48 | 49 | ||
| 49 | obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o | 50 | obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o |
| 50 | obj-y += process.o | 51 | obj-y += process.o |
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 3cb482e123de..6e11c8134158 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
| @@ -31,7 +31,7 @@ | |||
| 31 | #include <asm/iommu.h> | 31 | #include <asm/iommu.h> |
| 32 | #include <asm/gart.h> | 32 | #include <asm/gart.h> |
| 33 | #include <asm/x86_init.h> | 33 | #include <asm/x86_init.h> |
| 34 | 34 | #include <asm/iommu_table.h> | |
| 35 | /* | 35 | /* |
| 36 | * definitions for the ACPI scanning code | 36 | * definitions for the ACPI scanning code |
| 37 | */ | 37 | */ |
| @@ -1499,13 +1499,13 @@ static int __init early_amd_iommu_detect(struct acpi_table_header *table) | |||
| 1499 | return 0; | 1499 | return 0; |
| 1500 | } | 1500 | } |
| 1501 | 1501 | ||
| 1502 | void __init amd_iommu_detect(void) | 1502 | int __init amd_iommu_detect(void) |
| 1503 | { | 1503 | { |
| 1504 | if (no_iommu || (iommu_detected && !gart_iommu_aperture)) | 1504 | if (no_iommu || (iommu_detected && !gart_iommu_aperture)) |
| 1505 | return; | 1505 | return -ENODEV; |
| 1506 | 1506 | ||
| 1507 | if (amd_iommu_disabled) | 1507 | if (amd_iommu_disabled) |
| 1508 | return; | 1508 | return -ENODEV; |
| 1509 | 1509 | ||
| 1510 | if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) { | 1510 | if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) { |
| 1511 | iommu_detected = 1; | 1511 | iommu_detected = 1; |
| @@ -1514,7 +1514,9 @@ void __init amd_iommu_detect(void) | |||
| 1514 | 1514 | ||
| 1515 | /* Make sure ACS will be enabled */ | 1515 | /* Make sure ACS will be enabled */ |
| 1516 | pci_request_acs(); | 1516 | pci_request_acs(); |
| 1517 | return 1; | ||
| 1517 | } | 1518 | } |
| 1519 | return -ENODEV; | ||
| 1518 | } | 1520 | } |
| 1519 | 1521 | ||
| 1520 | /**************************************************************************** | 1522 | /**************************************************************************** |
| @@ -1545,3 +1547,8 @@ static int __init parse_amd_iommu_options(char *str) | |||
| 1545 | 1547 | ||
| 1546 | __setup("amd_iommu_dump", parse_amd_iommu_dump); | 1548 | __setup("amd_iommu_dump", parse_amd_iommu_dump); |
| 1547 | __setup("amd_iommu=", parse_amd_iommu_options); | 1549 | __setup("amd_iommu=", parse_amd_iommu_options); |
| 1550 | |||
| 1551 | IOMMU_INIT_FINISH(amd_iommu_detect, | ||
| 1552 | gart_iommu_hole_init, | ||
| 1553 | 0, | ||
| 1554 | 0); | ||
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index 377f5db3b8b4..b3a16e8f0703 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c | |||
| @@ -371,7 +371,7 @@ void __init early_gart_iommu_check(void) | |||
| 371 | 371 | ||
| 372 | static int __initdata printed_gart_size_msg; | 372 | static int __initdata printed_gart_size_msg; |
| 373 | 373 | ||
| 374 | void __init gart_iommu_hole_init(void) | 374 | int __init gart_iommu_hole_init(void) |
| 375 | { | 375 | { |
| 376 | u32 agp_aper_base = 0, agp_aper_order = 0; | 376 | u32 agp_aper_base = 0, agp_aper_order = 0; |
| 377 | u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0; | 377 | u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0; |
| @@ -381,7 +381,7 @@ void __init gart_iommu_hole_init(void) | |||
| 381 | 381 | ||
| 382 | if (gart_iommu_aperture_disabled || !fix_aperture || | 382 | if (gart_iommu_aperture_disabled || !fix_aperture || |
| 383 | !early_pci_allowed()) | 383 | !early_pci_allowed()) |
| 384 | return; | 384 | return -ENODEV; |
| 385 | 385 | ||
| 386 | printk(KERN_INFO "Checking aperture...\n"); | 386 | printk(KERN_INFO "Checking aperture...\n"); |
| 387 | 387 | ||
| @@ -463,8 +463,9 @@ out: | |||
| 463 | unsigned long n = (32 * 1024 * 1024) << last_aper_order; | 463 | unsigned long n = (32 * 1024 * 1024) << last_aper_order; |
| 464 | 464 | ||
| 465 | insert_aperture_resource((u32)last_aper_base, n); | 465 | insert_aperture_resource((u32)last_aper_base, n); |
| 466 | return 1; | ||
| 466 | } | 467 | } |
| 467 | return; | 468 | return 0; |
| 468 | } | 469 | } |
| 469 | 470 | ||
| 470 | if (!fallback_aper_force) { | 471 | if (!fallback_aper_force) { |
| @@ -500,7 +501,7 @@ out: | |||
| 500 | panic("Not enough memory for aperture"); | 501 | panic("Not enough memory for aperture"); |
| 501 | } | 502 | } |
| 502 | } else { | 503 | } else { |
| 503 | return; | 504 | return 0; |
| 504 | } | 505 | } |
| 505 | 506 | ||
| 506 | /* Fix up the north bridges */ | 507 | /* Fix up the north bridges */ |
| @@ -526,4 +527,6 @@ out: | |||
| 526 | } | 527 | } |
| 527 | 528 | ||
| 528 | set_up_gart_resume(aper_order, aper_alloc); | 529 | set_up_gart_resume(aper_order, aper_alloc); |
| 530 | |||
| 531 | return 1; | ||
| 529 | } | 532 | } |
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 078d4ec1a9d9..f56a117cef68 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | #include <asm/rio.h> | 47 | #include <asm/rio.h> |
| 48 | #include <asm/bios_ebda.h> | 48 | #include <asm/bios_ebda.h> |
| 49 | #include <asm/x86_init.h> | 49 | #include <asm/x86_init.h> |
| 50 | #include <asm/iommu_table.h> | ||
| 50 | 51 | ||
| 51 | #ifdef CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT | 52 | #ifdef CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT |
| 52 | int use_calgary __read_mostly = 1; | 53 | int use_calgary __read_mostly = 1; |
| @@ -1364,7 +1365,7 @@ static int __init calgary_iommu_init(void) | |||
| 1364 | return 0; | 1365 | return 0; |
| 1365 | } | 1366 | } |
| 1366 | 1367 | ||
| 1367 | void __init detect_calgary(void) | 1368 | int __init detect_calgary(void) |
| 1368 | { | 1369 | { |
| 1369 | int bus; | 1370 | int bus; |
| 1370 | void *tbl; | 1371 | void *tbl; |
| @@ -1378,13 +1379,13 @@ void __init detect_calgary(void) | |||
| 1378 | * another HW IOMMU already, bail out. | 1379 | * another HW IOMMU already, bail out. |
| 1379 | */ | 1380 | */ |
| 1380 | if (no_iommu || iommu_detected) | 1381 | if (no_iommu || iommu_detected) |
| 1381 | return; | 1382 | return -ENODEV; |
| 1382 | 1383 | ||
| 1383 | if (!use_calgary) | 1384 | if (!use_calgary) |
| 1384 | return; | 1385 | return -ENODEV; |
| 1385 | 1386 | ||
| 1386 | if (!early_pci_allowed()) | 1387 | if (!early_pci_allowed()) |
| 1387 | return; | 1388 | return -ENODEV; |
| 1388 | 1389 | ||
| 1389 | printk(KERN_DEBUG "Calgary: detecting Calgary via BIOS EBDA area\n"); | 1390 | printk(KERN_DEBUG "Calgary: detecting Calgary via BIOS EBDA area\n"); |
| 1390 | 1391 | ||
| @@ -1410,13 +1411,13 @@ void __init detect_calgary(void) | |||
| 1410 | if (!rio_table_hdr) { | 1411 | if (!rio_table_hdr) { |
| 1411 | printk(KERN_DEBUG "Calgary: Unable to locate Rio Grande table " | 1412 | printk(KERN_DEBUG "Calgary: Unable to locate Rio Grande table " |
| 1412 | "in EBDA - bailing!\n"); | 1413 | "in EBDA - bailing!\n"); |
| 1413 | return; | 1414 | return -ENODEV; |
| 1414 | } | 1415 | } |
| 1415 | 1416 | ||
| 1416 | ret = build_detail_arrays(); | 1417 | ret = build_detail_arrays(); |
| 1417 | if (ret) { | 1418 | if (ret) { |
| 1418 | printk(KERN_DEBUG "Calgary: build_detail_arrays ret %d\n", ret); | 1419 | printk(KERN_DEBUG "Calgary: build_detail_arrays ret %d\n", ret); |
| 1419 | return; | 1420 | return -ENOMEM; |
| 1420 | } | 1421 | } |
| 1421 | 1422 | ||
| 1422 | specified_table_size = determine_tce_table_size((is_kdump_kernel() ? | 1423 | specified_table_size = determine_tce_table_size((is_kdump_kernel() ? |
| @@ -1464,7 +1465,7 @@ void __init detect_calgary(void) | |||
| 1464 | 1465 | ||
| 1465 | x86_init.iommu.iommu_init = calgary_iommu_init; | 1466 | x86_init.iommu.iommu_init = calgary_iommu_init; |
| 1466 | } | 1467 | } |
| 1467 | return; | 1468 | return calgary_found; |
| 1468 | 1469 | ||
| 1469 | cleanup: | 1470 | cleanup: |
| 1470 | for (--bus; bus >= 0; --bus) { | 1471 | for (--bus; bus >= 0; --bus) { |
| @@ -1473,6 +1474,7 @@ cleanup: | |||
| 1473 | if (info->tce_space) | 1474 | if (info->tce_space) |
| 1474 | free_tce_table(info->tce_space); | 1475 | free_tce_table(info->tce_space); |
| 1475 | } | 1476 | } |
| 1477 | return -ENOMEM; | ||
| 1476 | } | 1478 | } |
| 1477 | 1479 | ||
| 1478 | static int __init calgary_parse_options(char *p) | 1480 | static int __init calgary_parse_options(char *p) |
| @@ -1594,3 +1596,5 @@ static int __init calgary_fixup_tce_spaces(void) | |||
| 1594 | * and before device_initcall. | 1596 | * and before device_initcall. |
| 1595 | */ | 1597 | */ |
| 1596 | rootfs_initcall(calgary_fixup_tce_spaces); | 1598 | rootfs_initcall(calgary_fixup_tce_spaces); |
| 1599 | |||
| 1600 | IOMMU_INIT_POST(detect_calgary); | ||
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 9f07cfcbd3a5..9ea999a4dcc1 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
| @@ -11,9 +11,8 @@ | |||
| 11 | #include <asm/iommu.h> | 11 | #include <asm/iommu.h> |
| 12 | #include <asm/gart.h> | 12 | #include <asm/gart.h> |
| 13 | #include <asm/calgary.h> | 13 | #include <asm/calgary.h> |
| 14 | #include <asm/amd_iommu.h> | ||
| 15 | #include <asm/x86_init.h> | 14 | #include <asm/x86_init.h> |
| 16 | #include <asm/xen/swiotlb-xen.h> | 15 | #include <asm/iommu_table.h> |
| 17 | 16 | ||
| 18 | static int forbid_dac __read_mostly; | 17 | static int forbid_dac __read_mostly; |
| 19 | 18 | ||
| @@ -45,6 +44,8 @@ int iommu_detected __read_mostly = 0; | |||
| 45 | */ | 44 | */ |
| 46 | int iommu_pass_through __read_mostly; | 45 | int iommu_pass_through __read_mostly; |
| 47 | 46 | ||
| 47 | extern struct iommu_table_entry __iommu_table[], __iommu_table_end[]; | ||
| 48 | |||
| 48 | /* Dummy device used for NULL arguments (normally ISA). */ | 49 | /* Dummy device used for NULL arguments (normally ISA). */ |
| 49 | struct device x86_dma_fallback_dev = { | 50 | struct device x86_dma_fallback_dev = { |
| 50 | .init_name = "fallback device", | 51 | .init_name = "fallback device", |
| @@ -130,26 +131,24 @@ static void __init dma32_free_bootmem(void) | |||
| 130 | 131 | ||
| 131 | void __init pci_iommu_alloc(void) | 132 | void __init pci_iommu_alloc(void) |
| 132 | { | 133 | { |
| 134 | struct iommu_table_entry *p; | ||
| 135 | |||
| 133 | /* free the range so iommu could get some range less than 4G */ | 136 | /* free the range so iommu could get some range less than 4G */ |
| 134 | dma32_free_bootmem(); | 137 | dma32_free_bootmem(); |
| 135 | 138 | ||
| 136 | if (pci_xen_swiotlb_detect() || pci_swiotlb_detect()) | 139 | sort_iommu_table(__iommu_table, __iommu_table_end); |
| 137 | goto out; | 140 | check_iommu_entries(__iommu_table, __iommu_table_end); |
| 138 | |||
| 139 | gart_iommu_hole_init(); | ||
| 140 | |||
| 141 | detect_calgary(); | ||
| 142 | |||
| 143 | detect_intel_iommu(); | ||
| 144 | 141 | ||
| 145 | /* needs to be called after gart_iommu_hole_init */ | 142 | for (p = __iommu_table; p < __iommu_table_end; p++) { |
| 146 | amd_iommu_detect(); | 143 | if (p && p->detect && p->detect() > 0) { |
| 147 | out: | 144 | p->flags |= IOMMU_DETECTED; |
| 148 | pci_xen_swiotlb_init(); | 145 | if (p->early_init) |
| 149 | 146 | p->early_init(); | |
| 150 | pci_swiotlb_init(); | 147 | if (p->flags & IOMMU_FINISH_IF_DETECTED) |
| 148 | break; | ||
| 149 | } | ||
| 150 | } | ||
| 151 | } | 151 | } |
| 152 | |||
| 153 | void *dma_generic_alloc_coherent(struct device *dev, size_t size, | 152 | void *dma_generic_alloc_coherent(struct device *dev, size_t size, |
| 154 | dma_addr_t *dma_addr, gfp_t flag) | 153 | dma_addr_t *dma_addr, gfp_t flag) |
| 155 | { | 154 | { |
| @@ -292,6 +291,7 @@ EXPORT_SYMBOL(dma_supported); | |||
| 292 | 291 | ||
| 293 | static int __init pci_iommu_init(void) | 292 | static int __init pci_iommu_init(void) |
| 294 | { | 293 | { |
| 294 | struct iommu_table_entry *p; | ||
| 295 | dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); | 295 | dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); |
| 296 | 296 | ||
| 297 | #ifdef CONFIG_PCI | 297 | #ifdef CONFIG_PCI |
| @@ -299,12 +299,10 @@ static int __init pci_iommu_init(void) | |||
| 299 | #endif | 299 | #endif |
| 300 | x86_init.iommu.iommu_init(); | 300 | x86_init.iommu.iommu_init(); |
| 301 | 301 | ||
| 302 | if (swiotlb || xen_swiotlb) { | 302 | for (p = __iommu_table; p < __iommu_table_end; p++) { |
| 303 | printk(KERN_INFO "PCI-DMA: " | 303 | if (p && (p->flags & IOMMU_DETECTED) && p->late_init) |
| 304 | "Using software bounce buffering for IO (SWIOTLB)\n"); | 304 | p->late_init(); |
| 305 | swiotlb_print_info(); | 305 | } |
| 306 | } else | ||
| 307 | swiotlb_free(); | ||
| 308 | 306 | ||
| 309 | return 0; | 307 | return 0; |
| 310 | } | 308 | } |
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index c562207b1b3d..ba0f0ca9f280 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <asm/dma.h> | 41 | #include <asm/dma.h> |
| 42 | #include <asm/amd_nb.h> | 42 | #include <asm/amd_nb.h> |
| 43 | #include <asm/x86_init.h> | 43 | #include <asm/x86_init.h> |
| 44 | #include <asm/iommu_table.h> | ||
| 44 | 45 | ||
| 45 | static unsigned long iommu_bus_base; /* GART remapping area (physical) */ | 46 | static unsigned long iommu_bus_base; /* GART remapping area (physical) */ |
| 46 | static unsigned long iommu_size; /* size of remapping area bytes */ | 47 | static unsigned long iommu_size; /* size of remapping area bytes */ |
| @@ -905,3 +906,4 @@ void __init gart_parse_options(char *p) | |||
| 905 | } | 906 | } |
| 906 | } | 907 | } |
| 907 | } | 908 | } |
| 909 | IOMMU_INIT_POST(gart_iommu_hole_init); | ||
diff --git a/arch/x86/kernel/pci-iommu_table.c b/arch/x86/kernel/pci-iommu_table.c new file mode 100644 index 000000000000..55d745ec1181 --- /dev/null +++ b/arch/x86/kernel/pci-iommu_table.c | |||
| @@ -0,0 +1,89 @@ | |||
| 1 | #include <linux/dma-mapping.h> | ||
| 2 | #include <asm/iommu_table.h> | ||
| 3 | #include <linux/string.h> | ||
| 4 | #include <linux/kallsyms.h> | ||
| 5 | |||
| 6 | |||
| 7 | #define DEBUG 1 | ||
| 8 | |||
| 9 | static struct iommu_table_entry * __init | ||
| 10 | find_dependents_of(struct iommu_table_entry *start, | ||
| 11 | struct iommu_table_entry *finish, | ||
| 12 | struct iommu_table_entry *q) | ||
| 13 | { | ||
| 14 | struct iommu_table_entry *p; | ||
| 15 | |||
| 16 | if (!q) | ||
| 17 | return NULL; | ||
| 18 | |||
| 19 | for (p = start; p < finish; p++) | ||
| 20 | if (p->detect == q->depend) | ||
| 21 | return p; | ||
| 22 | |||
| 23 | return NULL; | ||
| 24 | } | ||
| 25 | |||
| 26 | |||
| 27 | void __init sort_iommu_table(struct iommu_table_entry *start, | ||
| 28 | struct iommu_table_entry *finish) { | ||
| 29 | |||
| 30 | struct iommu_table_entry *p, *q, tmp; | ||
| 31 | |||
| 32 | for (p = start; p < finish; p++) { | ||
| 33 | again: | ||
| 34 | q = find_dependents_of(start, finish, p); | ||
| 35 | /* We are bit sneaky here. We use the memory address to figure | ||
| 36 | * out if the node we depend on is past our point, if so, swap. | ||
| 37 | */ | ||
| 38 | if (q > p) { | ||
| 39 | tmp = *p; | ||
| 40 | memmove(p, q, sizeof(*p)); | ||
| 41 | *q = tmp; | ||
| 42 | goto again; | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 | } | ||
| 47 | |||
| 48 | #ifdef DEBUG | ||
| 49 | void __init check_iommu_entries(struct iommu_table_entry *start, | ||
| 50 | struct iommu_table_entry *finish) | ||
| 51 | { | ||
| 52 | struct iommu_table_entry *p, *q, *x; | ||
| 53 | char sym_p[KSYM_SYMBOL_LEN]; | ||
| 54 | char sym_q[KSYM_SYMBOL_LEN]; | ||
| 55 | |||
| 56 | /* Simple cyclic dependency checker. */ | ||
| 57 | for (p = start; p < finish; p++) { | ||
| 58 | q = find_dependents_of(start, finish, p); | ||
| 59 | x = find_dependents_of(start, finish, q); | ||
| 60 | if (p == x) { | ||
| 61 | sprint_symbol(sym_p, (unsigned long)p->detect); | ||
| 62 | sprint_symbol(sym_q, (unsigned long)q->detect); | ||
| 63 | |||
| 64 | printk(KERN_ERR "CYCLIC DEPENDENCY FOUND! %s depends" \ | ||
| 65 | " on %s and vice-versa. BREAKING IT.\n", | ||
| 66 | sym_p, sym_q); | ||
| 67 | /* Heavy handed way..*/ | ||
| 68 | x->depend = 0; | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | for (p = start; p < finish; p++) { | ||
| 73 | q = find_dependents_of(p, finish, p); | ||
| 74 | if (q && q > p) { | ||
| 75 | sprint_symbol(sym_p, (unsigned long)p->detect); | ||
| 76 | sprint_symbol(sym_q, (unsigned long)q->detect); | ||
| 77 | |||
| 78 | printk(KERN_ERR "EXECUTION ORDER INVALID! %s "\ | ||
| 79 | "should be called before %s!\n", | ||
| 80 | sym_p, sym_q); | ||
| 81 | } | ||
| 82 | } | ||
| 83 | } | ||
| 84 | #else | ||
| 85 | inline void check_iommu_entries(struct iommu_table_entry *start, | ||
| 86 | struct iommu_table_entry *finish) | ||
| 87 | { | ||
| 88 | } | ||
| 89 | #endif | ||
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c index a5bc528d4328..8f972cbddef0 100644 --- a/arch/x86/kernel/pci-swiotlb.c +++ b/arch/x86/kernel/pci-swiotlb.c | |||
| @@ -10,7 +10,8 @@ | |||
| 10 | #include <asm/iommu.h> | 10 | #include <asm/iommu.h> |
| 11 | #include <asm/swiotlb.h> | 11 | #include <asm/swiotlb.h> |
| 12 | #include <asm/dma.h> | 12 | #include <asm/dma.h> |
| 13 | 13 | #include <asm/xen/swiotlb-xen.h> | |
| 14 | #include <asm/iommu_table.h> | ||
| 14 | int swiotlb __read_mostly; | 15 | int swiotlb __read_mostly; |
| 15 | 16 | ||
| 16 | static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, | 17 | static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, |
| @@ -41,25 +42,42 @@ static struct dma_map_ops swiotlb_dma_ops = { | |||
| 41 | }; | 42 | }; |
| 42 | 43 | ||
| 43 | /* | 44 | /* |
| 44 | * pci_swiotlb_detect - set swiotlb to 1 if necessary | 45 | * pci_swiotlb_detect_override - set swiotlb to 1 if necessary |
| 45 | * | 46 | * |
| 46 | * This returns non-zero if we are forced to use swiotlb (by the boot | 47 | * This returns non-zero if we are forced to use swiotlb (by the boot |
| 47 | * option). | 48 | * option). |
| 48 | */ | 49 | */ |
| 49 | int __init pci_swiotlb_detect(void) | 50 | int __init pci_swiotlb_detect_override(void) |
| 50 | { | 51 | { |
| 51 | int use_swiotlb = swiotlb | swiotlb_force; | 52 | int use_swiotlb = swiotlb | swiotlb_force; |
| 52 | 53 | ||
| 54 | if (swiotlb_force) | ||
| 55 | swiotlb = 1; | ||
| 56 | |||
| 57 | return use_swiotlb; | ||
| 58 | } | ||
| 59 | IOMMU_INIT_FINISH(pci_swiotlb_detect_override, | ||
| 60 | pci_xen_swiotlb_detect, | ||
| 61 | pci_swiotlb_init, | ||
| 62 | pci_swiotlb_late_init); | ||
| 63 | |||
| 64 | /* | ||
| 65 | * if 4GB or more detected (and iommu=off not set) return 1 | ||
| 66 | * and set swiotlb to 1. | ||
| 67 | */ | ||
| 68 | int __init pci_swiotlb_detect_4gb(void) | ||
| 69 | { | ||
| 53 | /* don't initialize swiotlb if iommu=off (no_iommu=1) */ | 70 | /* don't initialize swiotlb if iommu=off (no_iommu=1) */ |
| 54 | #ifdef CONFIG_X86_64 | 71 | #ifdef CONFIG_X86_64 |
| 55 | if (!no_iommu && max_pfn > MAX_DMA32_PFN) | 72 | if (!no_iommu && max_pfn > MAX_DMA32_PFN) |
| 56 | swiotlb = 1; | 73 | swiotlb = 1; |
| 57 | #endif | 74 | #endif |
| 58 | if (swiotlb_force) | 75 | return swiotlb; |
| 59 | swiotlb = 1; | ||
| 60 | |||
| 61 | return use_swiotlb; | ||
| 62 | } | 76 | } |
| 77 | IOMMU_INIT(pci_swiotlb_detect_4gb, | ||
| 78 | pci_swiotlb_detect_override, | ||
| 79 | pci_swiotlb_init, | ||
| 80 | pci_swiotlb_late_init); | ||
| 63 | 81 | ||
| 64 | void __init pci_swiotlb_init(void) | 82 | void __init pci_swiotlb_init(void) |
| 65 | { | 83 | { |
| @@ -68,3 +86,15 @@ void __init pci_swiotlb_init(void) | |||
| 68 | dma_ops = &swiotlb_dma_ops; | 86 | dma_ops = &swiotlb_dma_ops; |
| 69 | } | 87 | } |
| 70 | } | 88 | } |
| 89 | |||
| 90 | void __init pci_swiotlb_late_init(void) | ||
| 91 | { | ||
| 92 | /* An IOMMU turned us off. */ | ||
| 93 | if (!swiotlb) | ||
| 94 | swiotlb_free(); | ||
| 95 | else { | ||
| 96 | printk(KERN_INFO "PCI-DMA: " | ||
| 97 | "Using software bounce buffering for IO (SWIOTLB)\n"); | ||
| 98 | swiotlb_print_info(); | ||
| 99 | } | ||
| 100 | } | ||
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index d0bb52296fa3..38e2b67807e1 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S | |||
| @@ -242,6 +242,12 @@ SECTIONS | |||
| 242 | __x86_cpu_dev_end = .; | 242 | __x86_cpu_dev_end = .; |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | /* | ||
| 246 | * start address and size of operations which during runtime | ||
| 247 | * can be patched with virtualization friendly instructions or | ||
| 248 | * baremetal native ones. Think page table operations. | ||
| 249 | * Details in paravirt_types.h | ||
| 250 | */ | ||
| 245 | . = ALIGN(8); | 251 | . = ALIGN(8); |
| 246 | .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { | 252 | .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { |
| 247 | __parainstructions = .; | 253 | __parainstructions = .; |
| @@ -249,6 +255,11 @@ SECTIONS | |||
| 249 | __parainstructions_end = .; | 255 | __parainstructions_end = .; |
| 250 | } | 256 | } |
| 251 | 257 | ||
| 258 | /* | ||
| 259 | * struct alt_inst entries. From the header (alternative.h): | ||
| 260 | * "Alternative instructions for different CPU types or capabilities" | ||
| 261 | * Think locking instructions on spinlocks. | ||
| 262 | */ | ||
| 252 | . = ALIGN(8); | 263 | . = ALIGN(8); |
| 253 | .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { | 264 | .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { |
| 254 | __alt_instructions = .; | 265 | __alt_instructions = .; |
| @@ -256,11 +267,28 @@ SECTIONS | |||
| 256 | __alt_instructions_end = .; | 267 | __alt_instructions_end = .; |
| 257 | } | 268 | } |
| 258 | 269 | ||
| 270 | /* | ||
| 271 | * And here are the replacement instructions. The linker sticks | ||
| 272 | * them as binary blobs. The .altinstructions has enough data to | ||
| 273 | * get the address and the length of them to patch the kernel safely. | ||
| 274 | */ | ||
| 259 | .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { | 275 | .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { |
| 260 | *(.altinstr_replacement) | 276 | *(.altinstr_replacement) |
| 261 | } | 277 | } |
| 262 | 278 | ||
| 263 | /* | 279 | /* |
| 280 | * struct iommu_table_entry entries are injected in this section. | ||
| 281 | * It is an array of IOMMUs which during run time gets sorted depending | ||
| 282 | * on its dependency order. After rootfs_initcall is complete | ||
| 283 | * this section can be safely removed. | ||
| 284 | */ | ||
| 285 | .iommu_table : AT(ADDR(.iommu_table) - LOAD_OFFSET) { | ||
| 286 | __iommu_table = .; | ||
| 287 | *(.iommu_table) | ||
| 288 | __iommu_table_end = .; | ||
| 289 | } | ||
| 290 | . = ALIGN(8); | ||
| 291 | /* | ||
| 264 | * .exit.text is discard at runtime, not link time, to deal with | 292 | * .exit.text is discard at runtime, not link time, to deal with |
| 265 | * references from .altinstructions and .eh_frame | 293 | * references from .altinstructions and .eh_frame |
| 266 | */ | 294 | */ |
diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c index a013ec9d0c54..22471001b74c 100644 --- a/arch/x86/xen/pci-swiotlb-xen.c +++ b/arch/x86/xen/pci-swiotlb-xen.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | #include <asm/xen/hypervisor.h> | 6 | #include <asm/xen/hypervisor.h> |
| 7 | #include <xen/xen.h> | 7 | #include <xen/xen.h> |
| 8 | #include <asm/iommu_table.h> | ||
| 8 | 9 | ||
| 9 | int xen_swiotlb __read_mostly; | 10 | int xen_swiotlb __read_mostly; |
| 10 | 11 | ||
| @@ -56,3 +57,7 @@ void __init pci_xen_swiotlb_init(void) | |||
| 56 | dma_ops = &xen_swiotlb_dma_ops; | 57 | dma_ops = &xen_swiotlb_dma_ops; |
| 57 | } | 58 | } |
| 58 | } | 59 | } |
| 60 | IOMMU_INIT_FINISH(pci_xen_swiotlb_detect, | ||
| 61 | 0, | ||
| 62 | pci_xen_swiotlb_init, | ||
| 63 | 0); | ||
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 3de3a436a432..0157708d474d 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include <linux/tboot.h> | 36 | #include <linux/tboot.h> |
| 37 | #include <linux/dmi.h> | 37 | #include <linux/dmi.h> |
| 38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
| 39 | #include <asm/iommu_table.h> | ||
| 39 | 40 | ||
| 40 | #define PREFIX "DMAR: " | 41 | #define PREFIX "DMAR: " |
| 41 | 42 | ||
| @@ -687,7 +688,7 @@ failed: | |||
| 687 | return 0; | 688 | return 0; |
| 688 | } | 689 | } |
| 689 | 690 | ||
| 690 | void __init detect_intel_iommu(void) | 691 | int __init detect_intel_iommu(void) |
| 691 | { | 692 | { |
| 692 | int ret; | 693 | int ret; |
| 693 | 694 | ||
| @@ -723,6 +724,8 @@ void __init detect_intel_iommu(void) | |||
| 723 | } | 724 | } |
| 724 | early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size); | 725 | early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size); |
| 725 | dmar_tbl = NULL; | 726 | dmar_tbl = NULL; |
| 727 | |||
| 728 | return ret ? 1 : -ENODEV; | ||
| 726 | } | 729 | } |
| 727 | 730 | ||
| 728 | 731 | ||
| @@ -1455,3 +1458,4 @@ int __init dmar_ir_support(void) | |||
| 1455 | return 0; | 1458 | return 0; |
| 1456 | return dmar->flags & 0x1; | 1459 | return dmar->flags & 0x1; |
| 1457 | } | 1460 | } |
| 1461 | IOMMU_INIT_POST(detect_intel_iommu); | ||
diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 51651b76d40f..a7d9dc21391d 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h | |||
| @@ -57,15 +57,15 @@ extern int dmar_table_init(void); | |||
| 57 | extern int dmar_dev_scope_init(void); | 57 | extern int dmar_dev_scope_init(void); |
| 58 | 58 | ||
| 59 | /* Intel IOMMU detection */ | 59 | /* Intel IOMMU detection */ |
| 60 | extern void detect_intel_iommu(void); | 60 | extern int detect_intel_iommu(void); |
| 61 | extern int enable_drhd_fault_handling(void); | 61 | extern int enable_drhd_fault_handling(void); |
| 62 | 62 | ||
| 63 | extern int parse_ioapics_under_ir(void); | 63 | extern int parse_ioapics_under_ir(void); |
| 64 | extern int alloc_iommu(struct dmar_drhd_unit *); | 64 | extern int alloc_iommu(struct dmar_drhd_unit *); |
| 65 | #else | 65 | #else |
| 66 | static inline void detect_intel_iommu(void) | 66 | static inline int detect_intel_iommu(void) |
| 67 | { | 67 | { |
| 68 | return; | 68 | return -ENODEV; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | static inline int dmar_table_init(void) | 71 | static inline int dmar_table_init(void) |
