Per our discussion at: http://lkml.org/lkml/2010/8/2/282 I've implemented an RFC set of patches to address the problem. This patch set adds a mechanism to "modularize" the IOMMUs we have on X86. Currently the count of IOMMUs is up to six and they have a complex relationship that requires careful execution order. 'pci_iommu_alloc' does that today, but most folks are unhappy with how it does it. This patch set addresses this and also paves a mechanism to jettison unused IOMMUs during run-time. The first solution that comes to mind is to convert wholesale the IOMMU detection routines to be called during initcall time frame. Unfortunately that misses the dependency relationship that some of the IOMMUs have (for example: for AMD-Vi IOMMU to work, GART detection MUST run first, and before all of that SWIOTLB MUST run). The second solution would be to introduce a registration call wherein the IOMMU would provide its detection/init routines and as well on what MUST run before it. That would work, except that the 'pci_iommu_alloc' which would run through this list, is called during mem_init. This means we don't have any memory allocator, and it is so early that we haven't yet started running through the initcall_t list. This solution borrows concepts from the 2nd idea and from how MODULE_INIT works. A macro is provided that each IOMMU uses to define it's detect function and early_init (before the memory allocate is active), and as well what other IOMMU MUST run before us. Since most IOMMUs depend on having SWIOTLB run first ("pci_swiotlb_detect") a convenience macro to depends on that is also provided. This macro is similar in design to MODULE_PARAM macro wherein we setup a .iommu_table section in which we populate it with the values that match a struct iommu_table_entry. During bootup we will sort through the array so that the IOMMUs that MUST run before us are first elements in the array. And then we just iterate through them calling the detection routine and if appropriate, ...
We utilize the IOMMU_INIT macros to create this dependency:
[null]
|
[pci_xen_swiotlb_detect]
|
[pci_swiotlb_detect_override]
|
[pci_swiotlb_detect_4gb]
|
+-------+--------+
/ \
[detect_calgary] [gart_iommu_hole_init]
|
[amd_iommu_detect]
Meaning that 'amd_iommu_detect' will be called after
'gart_iommu_hole_init'.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
CC: H. Peter Anvin <hpa@zytor.com>
CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp>
CC: Joerg Roedel <joerg.roedel@amd.com>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Ingo Molnar <mingo@redhat.com>
---
arch/x86/kernel/amd_iommu_init.c | 8 +++++++-
arch/x86/kernel/pci-gart_64.c | 2 ++
2 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index 0b9e2dc..3ca6728 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -31,7 +31,7 @@
#include <asm/iommu.h>
#include <asm/gart.h>
#include <asm/x86_init.h>
-
+#include <asm/iommu_table.h>
/*
* definitions for the ACPI scanning code
*/
@@ -1430,3 +1430,9 @@ static int __init parse_amd_iommu_options(char *str)
__setup("amd_iommu_dump", parse_amd_iommu_dump);
__setup("amd_iommu=", parse_amd_iommu_options);
+
+IOMMU_INIT_FINISH(amd_iommu_detect,
+ gart_iommu_hole_init,
+ 0,
+ 0);
+
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 0f7f130..de9734b 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -41,6 +41,7 @@
#include <asm/dma.h>
#include <asm/k8.h>
#include <asm/x86_init.h>
+#include <asm/iommu_table.h>
static unsigned long iommu_bus_base; /* GART remapping area (physical) */
static unsigned long iommu_size; /* size of remapping area ...Commit-ID: 22e6daf41ba28ddc06295e42859b266f737b3e99 Gitweb: http://git.kernel.org/tip/22e6daf41ba28ddc06295e42859b266f737b3e99 Author: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> AuthorDate: Thu, 26 Aug 2010 13:58:03 -0400 Committer: H. Peter Anvin <hpa@linux.intel.com> CommitDate: Thu, 26 Aug 2010 15:14:30 -0700 x86, GART/AMD-VI: Make AMD GART and IOMMU use IOMMU_INIT_* macros. We utilize the IOMMU_INIT macros to create this dependency: [null] | [pci_xen_swiotlb_detect] | [pci_swiotlb_detect_override] | [pci_swiotlb_detect_4gb] | +-------+--------+ / \ [detect_calgary] [gart_iommu_hole_init] | [amd_iommu_detect] Meaning that 'amd_iommu_detect' will be called after 'gart_iommu_hole_init'. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> LKML-Reference: <1282845485-8991-9-git-send-email-konrad.wilk@oracle.com> CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp> CC: Joerg Roedel <joerg.roedel@amd.com> CC: Thomas Gleixner <tglx@linutronix.de> CC: Ingo Molnar <mingo@redhat.com> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> --- arch/x86/kernel/amd_iommu_init.c | 7 ++++++- arch/x86/kernel/pci-gart_64.c | 2 ++ 2 files changed, 8 insertions(+), 1 deletions(-) diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 0b9e2dc..26a5e43 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -31,7 +31,7 @@ #include <asm/iommu.h> #include <asm/gart.h> #include <asm/x86_init.h> - +#include <asm/iommu_table.h> /* * definitions for the ACPI scanning code */ @@ -1430,3 +1430,8 @@ static int __init parse_amd_iommu_options(char *str) __setup("amd_iommu_dump", parse_amd_iommu_dump); __setup("amd_iommu=", ...
We utilize the IOMMU_INIT macros to create this dependency:
[null]
|
[pci_xen_swiotlb_detect]
|
[pci_swiotlb_detect_override]
|
[pci_swiotlb_detect_4gb]
|
+-------+--------+---------------------+
/ \ \
[detect_calgary] [gart_iommu_hole_init] [detect_intel_iommu]
|
[amd_iommu_detect]
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
CC: H. Peter Anvin <hpa@zytor.com>
CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp>
CC: Jesse Barnes <jbarnes@virtuousgeek.org>
CC: David Woodhouse <David.Woodhouse@intel.com>
CC: Len Brown <len.brown@intel.com>
CC: Chris Wright <chrisw@sous-sol.org>
CC: Yinghai Lu <yinghai@kernel.org>
---
drivers/pci/dmar.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 5fa64ea..4ef56a0 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -36,6 +36,7 @@
#include <linux/tboot.h>
#include <linux/dmi.h>
#include <linux/slab.h>
+#include <asm/iommu_table.h>
#define PREFIX "DMAR: "
@@ -724,7 +725,7 @@ int __init detect_intel_iommu(void)
early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size);
dmar_tbl = NULL;
- return (ret ? 1 : -ENODEV);
+ return ret ? 1 : -ENODEV;
}
@@ -1457,3 +1458,4 @@ int __init dmar_ir_support(void)
return 0;
return dmar->flags & 0x1;
}
+IOMMU_INIT_POST(detect_intel_iommu);
--
1.7.0.1
--
Commit-ID: 4db77ff3237a88ea74f691dd776e92b2f86a8f3f Gitweb: http://git.kernel.org/tip/4db77ff3237a88ea74f691dd776e92b2f86a8f3f Author: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> AuthorDate: Thu, 26 Aug 2010 13:58:04 -0400 Committer: H. Peter Anvin <hpa@linux.intel.com> CommitDate: Thu, 26 Aug 2010 15:14:40 -0700 x86, VT-d: Make Intel VT-d IOMMU use IOMMU_INIT_* macros. We utilize the IOMMU_INIT macros to create this dependency: [null] | [pci_xen_swiotlb_detect] | [pci_swiotlb_detect_override] | [pci_swiotlb_detect_4gb] | +-------+--------+---------------------+ / \ \ [detect_calgary] [gart_iommu_hole_init] [detect_intel_iommu] | [amd_iommu_detect] Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> LKML-Reference: <1282845485-8991-10-git-send-email-konrad.wilk@oracle.com> CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp> CC: Jesse Barnes <jbarnes@virtuousgeek.org> CC: David Woodhouse <David.Woodhouse@intel.com> CC: Len Brown <len.brown@intel.com> CC: Chris Wright <chrisw@sous-sol.org> CC: Yinghai Lu <yinghai@kernel.org> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> --- drivers/pci/dmar.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 5fa64ea..4ef56a0 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -36,6 +36,7 @@ #include <linux/tboot.h> #include <linux/dmi.h> #include <linux/slab.h> +#include <asm/iommu_table.h> #define PREFIX "DMAR: " @@ -724,7 +725,7 @@ int __init detect_intel_iommu(void) early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size); dmar_tbl = NULL; - return (ret ? 1 : -ENODEV); + return ret ? 1 : -ENODEV; } @@ -1457,3 +1458,4 @@ int __init dmar_ir_support(void) return 0; return ...
On Thu, Aug 26, 2010 at 10:58 AM, Konrad Rzeszutek Wilk This breaks ia64 - since you didn't make an asm/iommu_table.h for it :-( Just copying the x86 one led to complaints about pci_swiotlb_detect_4gb() not being declared ... so I think I need a bit more of the same infrastructure you made of x86. Pointers & hints please? -Tony --
Oh no! Well, perhaps moving it to a wider audience is the right thing.. Under ia64 you only have to IOMMUs right? DMAR and SWIOTLB? If you do this patch it should compile fine, let me think a bit about how to make the iommu_* pieces platform-agnostic. From 863a8f5f2ef36f0ceafbee046766b0e484f64a13 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk <konrad@dumpdata.com> Date: Tue, 7 Sep 2010 15:01:45 -0400 Subject: [PATCH] ia64/iommu: Add a dummy iommu_table.h file in IA64. We don't need a comlex IOMMU dependency list on IA64 so we just define the IOMMU_* macro as a dummy. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> --- arch/ia64/include/asm/iommu_table.h | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) create mode 100644 arch/ia64/include/asm/iommu_table.h diff --git a/arch/ia64/include/asm/iommu_table.h b/arch/ia64/include/asm/iommu_table.h new file mode 100644 index 0000000..6793601 --- /dev/null +++ b/arch/ia64/include/asm/iommu_table.h @@ -0,0 +1,6 @@ +#ifndef _ASM_X86_IOMMU_TABLE_H +#define _ASM_X86_IOMMU_TABLE_H + +#define IOMMU_INIT_POST(_detect) + +#endif /* _ASM_X86_IOMMU_TABLE_H */ -- 1.7.0.4 --
Yes. That fixes the compliation problem. -Tony --
We remove all of the sub-platform detection/init routines and instead use on the .iommu_table array of structs to call the .early_init if .detect returned a positive value. Also we can stop detecting other IOMMUs if the IOMMU used the _FINISH type macro. During the 'pci_iommu_init' stage, we call .init for the second-stage initialization if it was defined. Currently only SWIOTLB has this defined and it used to de-allocate the SWIOTLB if the other detected IOMMUs have deemed it unnecessary to use SWIOTLB. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> CC: H. Peter Anvin <hpa@zytor.com> CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp> CC: Thomas Gleixner <tglx@linutronix.de> CC: Ingo Molnar <mingo@redhat.com> CC: x86@kernel.org Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> --- arch/x86/kernel/pci-dma.c | 46 ++++++++++++++++++++------------------------ 1 files changed, 21 insertions(+), 25 deletions(-) diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 1b3beb5..9ea999a 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -11,9 +11,8 @@ #include <asm/iommu.h> #include <asm/gart.h> #include <asm/calgary.h> -#include <asm/amd_iommu.h> #include <asm/x86_init.h> -#include <asm/xen/swiotlb-xen.h> +#include <asm/iommu_table.h> static int forbid_dac __read_mostly; @@ -45,6 +44,8 @@ int iommu_detected __read_mostly = 0; */ int iommu_pass_through __read_mostly; +extern struct iommu_table_entry __iommu_table[], __iommu_table_end[]; + /* Dummy device used for NULL arguments (normally ISA). */ struct device x86_dma_fallback_dev = { .init_name = "fallback device", @@ -130,28 +131,24 @@ static void __init dma32_free_bootmem(void) void __init pci_iommu_alloc(void) { + struct iommu_table_entry *p; + /* free the range so iommu could get some range less than 4G */ dma32_free_bootmem(); - if (pci_xen_swiotlb_detect() || pci_swiotlb_detect_override()) - goto ...
Commit-ID: ee1f284f38c8dfcbc7b656915a039dde016de7d3 Gitweb: http://git.kernel.org/tip/ee1f284f38c8dfcbc7b656915a039dde016de7d3 Author: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> AuthorDate: Thu, 26 Aug 2010 13:58:05 -0400 Committer: H. Peter Anvin <hpa@linux.intel.com> CommitDate: Thu, 26 Aug 2010 15:14:52 -0700 x86, iommu: Utilize the IOMMU_INIT macros functionality. We remove all of the sub-platform detection/init routines and instead use on the .iommu_table array of structs to call the .early_init if .detect returned a positive value. Also we can stop detecting other IOMMUs if the IOMMU used the _FINISH type macro. During the 'pci_iommu_init' stage, we call .init for the second-stage initialization if it was defined. Currently only SWIOTLB has this defined and it used to de-allocate the SWIOTLB if the other detected IOMMUs have deemed it unnecessary to use SWIOTLB. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> LKML-Reference: <1282845485-8991-11-git-send-email-konrad.wilk@oracle.com> CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp> CC: Thomas Gleixner <tglx@linutronix.de> CC: Ingo Molnar <mingo@redhat.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> --- arch/x86/kernel/pci-dma.c | 46 ++++++++++++++++++++------------------------ 1 files changed, 21 insertions(+), 25 deletions(-) diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 1b3beb5..9ea999a 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -11,9 +11,8 @@ #include <asm/iommu.h> #include <asm/gart.h> #include <asm/calgary.h> -#include <asm/amd_iommu.h> #include <asm/x86_init.h> -#include <asm/xen/swiotlb-xen.h> +#include <asm/iommu_table.h> static int forbid_dac __read_mostly; @@ -45,6 +44,8 @@ int iommu_detected __read_mostly = 0; */ int iommu_pass_through __read_mostly; +extern struct iommu_table_entry __iommu_table[], ...
This patch set adds a mechanism to "modularize" the IOMMUs we have on X86. Currently the count of IOMMUs is up to six and they have a complex relationship that requires careful execution order. 'pci_iommu_alloc' does that today, but most folks are unhappy with how it does it. This patch set addresses this and also paves a mechanism to jettison unused IOMMUs during run-time. For details that sparked this, please refer to: http://lkml.org/lkml/2010/8/2/282 The first solution that comes to mind is to convert wholesale the IOMMU detection routines to be called during initcall time frame. Unfortunately that misses the dependency relationship that some of the IOMMUs have (for example: for AMD-Vi IOMMU to work, GART detection MUST run first, and before all of that SWIOTLB MUST run). The second solution would be to introduce a registration call wherein the IOMMU would provide its detection/init routines and as well on what MUST run before it. That would work, except that the 'pci_iommu_alloc' which would run through this list, is called during mem_init. This means we don't have any memory allocator, and it is so early that we haven't yet started running through the initcall_t list. This solution borrows concepts from the 2nd idea and from how MODULE_INIT works. A macro is provided that each IOMMU uses to define it's detect function and early_init (before the memory allocate is active), and as well what other IOMMU MUST run before us. Since most IOMMUs depend on having SWIOTLB run first ("pci_swiotlb_detect") a convenience macro to depends on that is also provided. This macro is similar in design to MODULE_PARAM macro wherein we setup a .iommu_table section in which we populate it with the values that match a struct iommu_table_entry. During bootup we will sort through the array so that the IOMMUs that MUST run before us are first elements in the array. And then we just iterate through them calling the detection routine and if appropiate, the init routines. This patchset is ...
So we have yet another magic section in vmlinux.lds.S A nice comemnt that expalins what this is used for and why it is discardable etc. would be nice. Lots of magic sections in same file miss this, but thats not an example to follwow. Sam --
Honestly, I think we this kind of problem -- a mergeable table -- often
enough that we should implement a generic facility for it. It obviously
has to be based on sections, but I think we could automate its creation.
The gPXE people have done that, and this is more or less a summary of
their technique.
Basically, you have a set of sections with names like:
.table.<symbol>.<priority>
... then the linker script looks something like:
.table : {
SORT_BY_NAME(.table.*)
}
use SORT_BY_NAME() in the linker script. To get the start and end
symbols, we define them as solo symbols inside sections designed to sort
first and last (written by hand into email, so adjustments may be
needed, void where prohibited):
#define TABLE(name, priority) \
__section(".table." ## name ## "." ## priority)
#define DECLARE_TABLE(type, name) \
extern type __table ## name ## _start[0]; \
extern type __table ## name ## _end[0];
#define DEFINE_TABLE(type, name) \
type __table ## name ## _start[0] TABLE(name, 0); \
type __table ## name ## _end[0] TABLE(name, 9);
Here "priority" is a digit from 1 (first) to 8 (last); 0 and 9 are used
for the capstones.
Presumably we need a few different flavors for init tables and so on,
but this would make it a generic mechanism.
-hpa
--
I added this series to tip:x86/iommu, but please do provide an incremental patch with a comment. Thanks, -hpa --
Sure. Will provide one and also explain the other sections that I am familiar with. Thanks for your feedback! --
Updating the linker section with comments about .iommu_table and
some other ones that I know of.
CC: Sam Ravnborg <sam@ravnborg.org>
CC: H. Peter Anvin <hpa@zytor.com>
CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Ingo Molnar <mingo@redhat.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
arch/x86/kernel/vmlinux.lds.S | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index b92e040..3f07c37 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -242,6 +242,12 @@ SECTIONS
__x86_cpu_dev_end = .;
}
+ /*
+ * start address and size of operations which during runtime
+ * can be patched with virtualization friendly instructions or
+ * baremetal native ones. Think page table operations.
+ * Details in paravirt_types.h
+ */
. = ALIGN(8);
.parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
__parainstructions = .;
@@ -249,6 +255,11 @@ SECTIONS
__parainstructions_end = .;
}
+ /*
+ * struct alt_inst entries. From the header (alternative.h):
+ * "Alternative instructions for different CPU types or capabilities"
+ * Think locking instructions on spinlocks.
+ */
. = ALIGN(8);
.altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
__alt_instructions = .;
@@ -256,10 +267,21 @@ SECTIONS
__alt_instructions_end = .;
}
+ /*
+ * And here are the replacement instructions. The linker sticks
+ * them as binary blobs. The .altinstructions has enough data to
+ * get the address and the length of them to patch the kernel safely.
+ */
.altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
*(.altinstr_replacement)
}
+ /*
+ * struct iommu_table_entry entries are injected in this section.
+ * It is an array of IOMMUs which during run time gets sorted depending
+ * on its dependency ...Commit-ID: 6f44d0337cc54a46e83b4c8a6195607e78fff71d Gitweb: http://git.kernel.org/tip/6f44d0337cc54a46e83b4c8a6195607e78fff71d Author: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> AuthorDate: Fri, 27 Aug 2010 14:19:33 -0400 Committer: H. Peter Anvin <hpa@zytor.com> CommitDate: Fri, 27 Aug 2010 18:14:31 -0700 x86, doc: Adding comments about .iommu_table and its neighbors. Updating the linker section with comments about .iommu_table and some other ones that I know of. CC: Sam Ravnborg <sam@ravnborg.org> CC: H. Peter Anvin <hpa@zytor.com> CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp> CC: Thomas Gleixner <tglx@linutronix.de> CC: Ingo Molnar <mingo@redhat.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> LKML-Reference: <1282933173-19960-1-git-send-email-konrad.wilk@oracle.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com> --- arch/x86/kernel/vmlinux.lds.S | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+), 0 deletions(-) diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index b92e040..3f07c37 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -242,6 +242,12 @@ SECTIONS __x86_cpu_dev_end = .; } + /* + * start address and size of operations which during runtime + * can be patched with virtualization friendly instructions or + * baremetal native ones. Think page table operations. + * Details in paravirt_types.h + */ . = ALIGN(8); .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { __parainstructions = .; @@ -249,6 +255,11 @@ SECTIONS __parainstructions_end = .; } + /* + * struct alt_inst entries. From the header (alternative.h): + * "Alternative instructions for different CPU types or capabilities" + * Think locking instructions on spinlocks. + */ . = ALIGN(8); .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { __alt_instructions = .; @@ -256,10 +267,21 @@ SECTIONS __alt_instructions_end = ...
Commit-ID: 0444ad93ea2449963132d68753020a6a24d69895 Gitweb: http://git.kernel.org/tip/0444ad93ea2449963132d68753020a6a24d69895 Author: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> AuthorDate: Thu, 26 Aug 2010 13:57:56 -0400 Committer: H. Peter Anvin <hpa@linux.intel.com> CommitDate: Thu, 26 Aug 2010 15:12:53 -0700 x86, iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure This patch set adds a mechanism to "modularize" the IOMMUs we have on X86. Currently the count of IOMMUs is up to six and they have a complex relationship that requires careful execution order. 'pci_iommu_alloc' does that today, but most folks are unhappy with how it does it. This patch set addresses this and also paves a mechanism to jettison unused IOMMUs during run-time. For details that sparked this, please refer to: http://lkml.org/lkml/2010/8/2/282 The first solution that comes to mind is to convert wholesale the IOMMU detection routines to be called during initcall time frame. Unfortunately that misses the dependency relationship that some of the IOMMUs have (for example: for AMD-Vi IOMMU to work, GART detection MUST run first, and before all of that SWIOTLB MUST run). The second solution would be to introduce a registration call wherein the IOMMU would provide its detection/init routines and as well on what MUST run before it. That would work, except that the 'pci_iommu_alloc' which would run through this list, is called during mem_init. This means we don't have any memory allocator, and it is so early that we haven't yet started running through the initcall_t list. This solution borrows concepts from the 2nd idea and from how MODULE_INIT works. A macro is provided that each IOMMU uses to define it's detect function and early_init (before the memory allocate is active), and as well what other IOMMU MUST run before us. Since most IOMMUs depend on having SWIOTLB run first ("pci_swiotlb_detect") a convenience macro to depends on that is also ...
We return 1 if the IOMMU has been detected. Zero or an error number
if we failed to find it. This is in preperation of using the IOMMU_INIT
so that we can detect whether an IOMMU is present. I have not
tested this for regression on Calgary, nor on AMD Vi chipsets as
I don't have that hardware.
CC: Muli Ben-Yehuda <muli@il.ibm.com>
CC: "Jon D. Mason" <jdmason@kudzu.us>
CC: "Darrick J. Wong" <djwong@us.ibm.com>
CC: Jesse Barnes <jbarnes@virtuousgeek.org>
CC: David Woodhouse <David.Woodhouse@intel.com>
CC: Chris Wright <chrisw@sous-sol.org>
CC: Yinghai Lu <yinghai@kernel.org>
CC: Joerg Roedel <joerg.roedel@amd.com>
CC: H. Peter Anvin <hpa@zytor.com>
CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
arch/x86/include/asm/amd_iommu.h | 4 ++--
arch/x86/include/asm/calgary.h | 4 ++--
arch/x86/include/asm/gart.h | 5 +++--
arch/x86/kernel/amd_iommu_init.c | 8 +++++---
arch/x86/kernel/aperture_64.c | 11 +++++++----
arch/x86/kernel/pci-calgary_64.c | 15 ++++++++-------
drivers/pci/dmar.c | 4 +++-
include/linux/dmar.h | 6 +++---
8 files changed, 33 insertions(+), 24 deletions(-)
diff --git a/arch/x86/include/asm/amd_iommu.h b/arch/x86/include/asm/amd_iommu.h
index 5af2982..2798142 100644
--- a/arch/x86/include/asm/amd_iommu.h
+++ b/arch/x86/include/asm/amd_iommu.h
@@ -24,11 +24,11 @@
#ifdef CONFIG_AMD_IOMMU
-extern void amd_iommu_detect(void);
+extern int amd_iommu_detect(void);
#else
-static inline void amd_iommu_detect(void) { }
+static inline int amd_iommu_detect(void) { return -ENODEV; }
#endif
diff --git a/arch/x86/include/asm/calgary.h b/arch/x86/include/asm/calgary.h
index 0918654..0d467b3 100644
--- a/arch/x86/include/asm/calgary.h
+++ b/arch/x86/include/asm/calgary.h
@@ -62,9 +62,9 @@ struct cal_chipset_ops {
extern int use_calgary;
#ifdef CONFIG_CALGARY_IOMMU
-extern void detect_calgary(void);
+extern int ...Commit-ID: 480125ba49ba62be93beea37770f266846e077ab Gitweb: http://git.kernel.org/tip/480125ba49ba62be93beea37770f266846e077ab Author: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> AuthorDate: Thu, 26 Aug 2010 13:57:57 -0400 Committer: H. Peter Anvin <hpa@linux.intel.com> CommitDate: Thu, 26 Aug 2010 15:13:13 -0700 x86, iommu: Make all IOMMU's detection routines return a value. We return 1 if the IOMMU has been detected. Zero or an error number if we failed to find it. This is in preperation of using the IOMMU_INIT so that we can detect whether an IOMMU is present. I have not tested this for regression on Calgary, nor on AMD Vi chipsets as I don't have that hardware. CC: Muli Ben-Yehuda <muli@il.ibm.com> CC: "Jon D. Mason" <jdmason@kudzu.us> CC: "Darrick J. Wong" <djwong@us.ibm.com> CC: Jesse Barnes <jbarnes@virtuousgeek.org> CC: David Woodhouse <David.Woodhouse@intel.com> CC: Chris Wright <chrisw@sous-sol.org> CC: Yinghai Lu <yinghai@kernel.org> CC: Joerg Roedel <joerg.roedel@amd.com> CC: H. Peter Anvin <hpa@zytor.com> CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> LKML-Reference: <1282845485-8991-3-git-send-email-konrad.wilk@oracle.com> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> --- arch/x86/include/asm/amd_iommu.h | 4 ++-- arch/x86/include/asm/calgary.h | 4 ++-- arch/x86/include/asm/gart.h | 5 +++-- arch/x86/kernel/amd_iommu_init.c | 8 +++++--- arch/x86/kernel/aperture_64.c | 11 +++++++---- arch/x86/kernel/pci-calgary_64.c | 15 ++++++++------- drivers/pci/dmar.c | 4 +++- include/linux/dmar.h | 6 +++--- 8 files changed, 33 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/amd_iommu.h b/arch/x86/include/asm/amd_iommu.h index 5af2982..2798142 100644 --- a/arch/x86/include/asm/amd_iommu.h +++ b/arch/x86/include/asm/amd_iommu.h @@ -24,11 +24,11 @@ #ifdef CONFIG_AMD_IOMMU -extern void ...
