All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v2] Modularize IOMMUs detection/init for X86
@ 2010-08-26 17:57 Konrad Rzeszutek Wilk
  2010-08-26 17:57 ` [PATCH 01/10] x86/iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure Konrad Rzeszutek Wilk
                   ` (9 more replies)
  0 siblings, 10 replies; 31+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-08-26 17:57 UTC (permalink / raw)
  To: hpa, fujita.tomonori, linux-kernel

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, the init routines.

Testing:
I've done testing on machines with Intel VT-d, SWIOTLB, and GART for regressions.
I sadly don't have machines with the Calgary nor the AMD-Vi chipsets.

Enhancements:

Jeremy suggested that we could get rid of the macro and instead provide
an registration API, such as:

static void __init_early register_my_iommu() {

	register_iommu(&my_iommu_details);
}

where the __init_early would put the address of the function in an
-1 level of .initcall list. This -1 level of init that would run
right before the pci_iommu_alloc is called (or perhaps during earlier
setup).  The register_iommu would have a static list allocated, and the
structure passed in would have a 'list_head' value that we would use to
stitch the structs together. Then the 'sort_iommu' function would take care of
sorting the elements in order of dependency.

This patchset is also available on git:
git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb-2.6.git devel/iommu-0.2

 arch/x86/include/asm/amd_iommu.h   |    4 +-
 arch/x86/include/asm/calgary.h     |    4 +-
 arch/x86/include/asm/gart.h        |    5 +-
 arch/x86/include/asm/iommu_table.h |  101 ++++++++++++++++++++++++++++++++++++
 arch/x86/include/asm/swiotlb.h     |   13 ++++-
 arch/x86/kernel/Makefile           |    1 +
 arch/x86/kernel/amd_iommu_init.c   |   16 ++++--
 arch/x86/kernel/aperture_64.c      |   11 +++--
 arch/x86/kernel/pci-calgary_64.c   |   18 ++++---
 arch/x86/kernel/pci-dma.c          |   44 ++++++++--------
 arch/x86/kernel/pci-gart_64.c      |    2 +
 arch/x86/kernel/pci-iommu_table.c  |   90 ++++++++++++++++++++++++++++++++
 arch/x86/kernel/pci-swiotlb.c      |   45 +++++++++++++---
 arch/x86/kernel/vmlinux.lds.S      |    7 +++
 arch/x86/xen/pci-swiotlb-xen.c     |    5 ++
 drivers/pci/dmar.c                 |    6 ++-
 include/linux/dmar.h               |    6 +-
 17 files changed, 321 insertions(+), 57 deletions(-)

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 01/10] x86/iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure.
  2010-08-26 17:57 [RFC PATCH v2] Modularize IOMMUs detection/init for X86 Konrad Rzeszutek Wilk
@ 2010-08-26 17:57 ` Konrad Rzeszutek Wilk
  2010-08-26 18:19   ` Sam Ravnborg
  2010-08-26 23:27   ` [tip:x86/iommu] x86, iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure tip-bot for Konrad Rzeszutek Wilk
  2010-08-26 17:57 ` [PATCH 02/10] x86/iommu: Make all IOMMU's detection routines return a value Konrad Rzeszutek Wilk
                   ` (8 subsequent siblings)
  9 siblings, 2 replies; 31+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-08-26 17:57 UTC (permalink / raw)
  To: hpa, fujita.tomonori, linux-kernel
  Cc: Konrad Rzeszutek Wilk, x86, Thomas Gleixner, Ingo Molnar

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 also available on git:
git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb-2.6.git devel/iommu-0.2

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: x86@kernel.org
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Ingo Molnar <mingo@redhat.com>
---
 arch/x86/include/asm/iommu_table.h |   95 ++++++++++++++++++++++++++++++++++++
 arch/x86/kernel/vmlinux.lds.S      |    7 +++
 2 files changed, 102 insertions(+), 0 deletions(-)
 create mode 100644 arch/x86/include/asm/iommu_table.h

diff --git a/arch/x86/include/asm/iommu_table.h b/arch/x86/include/asm/iommu_table.h
new file mode 100644
index 0000000..435176f
--- /dev/null
+++ b/arch/x86/include/asm/iommu_table.h
@@ -0,0 +1,95 @@
+
+#ifndef _ASM_X86_IOMMU_TABLE_H
+#define _ASM_X86_IOMMU_TABLE_H
+
+#include <asm/swiotlb.h>
+
+/*
+ * History lesson:
+ * The execution chain of IOMMUs in 2.6.36 looks as so:
+ *
+ *            [xen-swiotlb]
+ *                 |
+ *         +----[swiotlb *]--+
+ *        /         |         \
+ *       /          |          \
+ *    [GART]     [Calgary]  [Intel VT-d]
+ *     /
+ *    /
+ * [AMD-Vi]
+ *
+ * *: if SWIOTLB detected 'iommu=soft'/'swiotlb=force' it would skip
+ * over the rest of IOMMUs and unconditionally initialize the SWIOTLB.
+ * Also it would surreptitiously initialize set the swiotlb=1 if there were
+ * more than 4GB and if the user did not pass in 'iommu=off'. The swiotlb
+ * flag would be turned off by all IOMMUs except the Calgary one.
+ *
+ * The IOMMU_INIT* macros allow a similar tree (or more complex if desired)
+ * to be built by defining who we depend on.
+ *
+ * And all that needs to be done is to use one of the macros in the IOMMU
+ * and the pci-dma.c will take care of the rest.
+ */
+
+struct iommu_table_entry {
+	initcall_t	detect;
+	initcall_t	depend;
+	void		(*early_init)(void); /* No memory allocate available. */
+	void		(*late_init)(void); /* Yes, can allocate memory. */
+#define IOMMU_FINISH_IF_DETECTED (1<<0)
+#define IOMMU_DETECTED		 (1<<1)
+	int		flags;
+};
+/*
+ * Macro fills out an entry in the .iommu_table that is equivalent
+ * to the fields that 'struct iommu_table_entry' has. The entries
+ * that are put in the .iommu_table section are not put in any order
+ * hence during boot-time we will have to resort them based on
+ * dependency. */
+
+
+#define __IOMMU_INIT(_detect, _depend, _early_init, _late_init, _finish)\
+	static const struct iommu_table_entry const			\
+		__iommu_entry_##_detect __used				\
+	__attribute__ ((unused, __section__(".iommu_table"),		\
+			aligned((sizeof(void *)))))	\
+	= {_detect, _depend, _early_init, _late_init,			\
+	   _finish ? IOMMU_FINISH_IF_DETECTED : 0}
+/*
+ * The simplest IOMMU definition. Provide the detection routine
+ * and it will be run after the SWIOTLB and the other IOMMUs
+ * that utilize this macro. If the IOMMU is detected (ie, the
+ * detect routine returns a positive value), the other IOMMUs
+ * are also checked. You can use IOMMU_INIT_FINISH if you prefer
+ * to stop detecting the other IOMMUs after yours has been detected.
+ */
+#define IOMMU_INIT_POST(_detect)					\
+	__IOMMU_INIT(_detect, pci_swiotlb_detect,  0, 0, 0)
+
+#define IOMMU_INIT_POST_FINISH(detect)					\
+	__IOMMU_INIT(_detect, pci_swiotlb_detect,  0, 0, 1)
+
+/*
+ * A more sophisticated version of IOMMU_INIT. This variant requires:
+ *  a). A detection routine function.
+ *  b). The name of the detection routine we depend on to get called
+ *      before us.
+ *  c). The init routine which gets called if the detection routine
+ *      returns a positive value from the pci_iommu_alloc. This means
+ *      no presence of a memory allocator.
+ *  d). Similar to the 'init', except that this gets called from pci_iommu_init
+ *      where we do have a memory allocator.
+ *
+ * The _CONT vs the _EXIT differs in that the _CONT variant will
+ * continue detecting other IOMMUs in the call list after the
+ * the detection routine returns a positive number. The _EXIT will
+ * stop the execution chain. Both will still call the 'init' and
+ * 'late_init' functions if they are set.
+ */
+#define IOMMU_INIT_FINISH(_detect, _depend, _init, _late_init)		\
+	__IOMMU_INIT(_detect, _depend, _init, _late_init, 1)
+
+#define IOMMU_INIT(_detect, _depend, _init, _late_init)			\
+	__IOMMU_INIT(_detect, _depend, _init, _late_init, 0)
+
+#endif /* _ASM_X86_IOMMU_TABLE_H */
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index d0bb522..b92e040 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -260,6 +260,13 @@ SECTIONS
 		*(.altinstr_replacement)
 	}
 
+	.iommu_table : AT(ADDR(.iommu_table) - LOAD_OFFSET) {
+		__iommu_table = .;
+		*(.iommu_table)
+		. = ALIGN(8);
+		__iommu_table_end = .;
+	}
+
 	/*
 	 * .exit.text is discard at runtime, not link time, to deal with
 	 *  references from .altinstructions and .eh_frame
-- 
1.7.0.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 02/10] x86/iommu: Make all IOMMU's detection routines return a value.
  2010-08-26 17:57 [RFC PATCH v2] Modularize IOMMUs detection/init for X86 Konrad Rzeszutek Wilk
  2010-08-26 17:57 ` [PATCH 01/10] x86/iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure Konrad Rzeszutek Wilk
@ 2010-08-26 17:57 ` Konrad Rzeszutek Wilk
  2010-08-26 23:28   ` [tip:x86/iommu] x86, iommu: " tip-bot for Konrad Rzeszutek Wilk
  2010-08-26 17:57 ` [PATCH 03/10] x86/iommu: Add proper dependency sort routine (and sanity check) Konrad Rzeszutek Wilk
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 31+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-08-26 17:57 UTC (permalink / raw)
  To: hpa, fujita.tomonori, linux-kernel
  Cc: Konrad Rzeszutek Wilk, Muli Ben-Yehuda, Jon D. Mason,
	Darrick J. Wong, Jesse Barnes, David Woodhouse, Chris Wright,
	Yinghai Lu, Joerg Roedel

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 detect_calgary(void);
 #else
-static inline void detect_calgary(void) { return; }
+static inline int detect_calgary(void) { return -ENODEV; }
 #endif
 
 #endif /* _ASM_X86_CALGARY_H */
diff --git a/arch/x86/include/asm/gart.h b/arch/x86/include/asm/gart.h
index 4ac5b0f..d7d1d4c 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;
 extern void early_gart_iommu_check(void);
 extern int gart_iommu_init(void);
 extern void __init gart_parse_options(char *);
-extern void gart_iommu_hole_init(void);
+extern int gart_iommu_hole_init(void);
 
 #else
 #define gart_iommu_aperture            0
@@ -50,8 +50,9 @@ static inline void early_gart_iommu_check(void)
 static inline void gart_parse_options(char *options)
 {
 }
-static inline void gart_iommu_hole_init(void)
+static inline int gart_iommu_hole_init(void)
 {
+	return -ENODEV;
 }
 #endif
 
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index 3cc63e2..0b9e2dc 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -1382,13 +1382,13 @@ static int __init early_amd_iommu_detect(struct acpi_table_header *table)
 	return 0;
 }
 
-void __init amd_iommu_detect(void)
+int __init amd_iommu_detect(void)
 {
 	if (no_iommu || (iommu_detected && !gart_iommu_aperture))
-		return;
+		return -ENODEV;
 
 	if (amd_iommu_disabled)
-		return;
+		return -ENODEV;
 
 	if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) {
 		iommu_detected = 1;
@@ -1397,7 +1397,9 @@ void __init amd_iommu_detect(void)
 
 		/* Make sure ACS will be enabled */
 		pci_request_acs();
+		return 1;
 	}
+	return -ENODEV;
 }
 
 /****************************************************************************
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index a2e0caf..afa0dab 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)
 
 static int __initdata printed_gart_size_msg;
 
-void __init gart_iommu_hole_init(void)
+int __init gart_iommu_hole_init(void)
 {
 	u32 agp_aper_base = 0, agp_aper_order = 0;
 	u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0;
@@ -381,7 +381,7 @@ void __init gart_iommu_hole_init(void)
 
 	if (gart_iommu_aperture_disabled || !fix_aperture ||
 	    !early_pci_allowed())
-		return;
+		return -ENODEV;
 
 	printk(KERN_INFO  "Checking aperture...\n");
 
@@ -463,8 +463,9 @@ out:
 			unsigned long n = (32 * 1024 * 1024) << last_aper_order;
 
 			insert_aperture_resource((u32)last_aper_base, n);
+			return 1;
 		}
-		return;
+		return 0;
 	}
 
 	if (!fallback_aper_force) {
@@ -500,7 +501,7 @@ out:
 			panic("Not enough memory for aperture");
 		}
 	} else {
-		return;
+		return 0;
 	}
 
 	/* Fix up the north bridges */
@@ -524,4 +525,6 @@ out:
 	}
 
 	set_up_gart_resume(aper_order, aper_alloc);
+
+	return 1;
 }
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 078d4ec..28c6b38 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -1364,7 +1364,7 @@ static int __init calgary_iommu_init(void)
 	return 0;
 }
 
-void __init detect_calgary(void)
+int __init detect_calgary(void)
 {
 	int bus;
 	void *tbl;
@@ -1378,13 +1378,13 @@ void __init detect_calgary(void)
 	 * another HW IOMMU already, bail out.
 	 */
 	if (no_iommu || iommu_detected)
-		return;
+		return -ENODEV;
 
 	if (!use_calgary)
-		return;
+		return -ENODEV;
 
 	if (!early_pci_allowed())
-		return;
+		return -ENODEV;
 
 	printk(KERN_DEBUG "Calgary: detecting Calgary via BIOS EBDA area\n");
 
@@ -1410,13 +1410,13 @@ void __init detect_calgary(void)
 	if (!rio_table_hdr) {
 		printk(KERN_DEBUG "Calgary: Unable to locate Rio Grande table "
 		       "in EBDA - bailing!\n");
-		return;
+		return -ENODEV;
 	}
 
 	ret = build_detail_arrays();
 	if (ret) {
 		printk(KERN_DEBUG "Calgary: build_detail_arrays ret %d\n", ret);
-		return;
+		return -ENOMEM;
 	}
 
 	specified_table_size = determine_tce_table_size((is_kdump_kernel() ?
@@ -1464,7 +1464,7 @@ void __init detect_calgary(void)
 
 		x86_init.iommu.iommu_init = calgary_iommu_init;
 	}
-	return;
+	return calgary_found;
 
 cleanup:
 	for (--bus; bus >= 0; --bus) {
@@ -1473,6 +1473,7 @@ cleanup:
 		if (info->tce_space)
 			free_tce_table(info->tce_space);
 	}
+	return -ENOMEM;
 }
 
 static int __init calgary_parse_options(char *p)
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 0a19708..5fa64ea 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -687,7 +687,7 @@ failed:
 	return 0;
 }
 
-void __init detect_intel_iommu(void)
+int __init detect_intel_iommu(void)
 {
 	int ret;
 
@@ -723,6 +723,8 @@ void __init detect_intel_iommu(void)
 	}
 	early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size);
 	dmar_tbl = NULL;
+
+	return (ret ? 1 : -ENODEV);
 }
 
 
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index d7cecc9..a206020 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -57,15 +57,15 @@ extern int dmar_table_init(void);
 extern int dmar_dev_scope_init(void);
 
 /* Intel IOMMU detection */
-extern void detect_intel_iommu(void);
+extern int detect_intel_iommu(void);
 extern int enable_drhd_fault_handling(void);
 
 extern int parse_ioapics_under_ir(void);
 extern int alloc_iommu(struct dmar_drhd_unit *);
 #else
-static inline void detect_intel_iommu(void)
+static inline int detect_intel_iommu(void)
 {
-	return;
+	return -ENODEV;
 }
 
 static inline int dmar_table_init(void)
-- 
1.7.0.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 03/10] x86/iommu: Add proper dependency sort routine (and sanity check).
  2010-08-26 17:57 [RFC PATCH v2] Modularize IOMMUs detection/init for X86 Konrad Rzeszutek Wilk
  2010-08-26 17:57 ` [PATCH 01/10] x86/iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure Konrad Rzeszutek Wilk
  2010-08-26 17:57 ` [PATCH 02/10] x86/iommu: Make all IOMMU's detection routines return a value Konrad Rzeszutek Wilk
@ 2010-08-26 17:57 ` Konrad Rzeszutek Wilk
  2010-08-26 23:28   ` [tip:x86/iommu] x86, iommu: " tip-bot for Konrad Rzeszutek Wilk
  2010-08-26 17:57 ` [PATCH 04/10] x86/swiotlb: Simplify SWIOTLB pci_swiotlb_detect routine Konrad Rzeszutek Wilk
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 31+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-08-26 17:57 UTC (permalink / raw)
  To: hpa, fujita.tomonori, linux-kernel; +Cc: Konrad Rzeszutek Wilk

We are using a very simple sort routine which sorts the .iommu_table
array in the order of dependencies. Specifically each structure
of iommu_table_entry has a field 'depend' which contains the function
pointer to the IOMMU that MUST be run before us. We sort the array
of structures so that the struct iommu_table_entry with no
'depend' field are first, and then the subsequent ones are the
ones for which the 'depend' function has been already invoked
(in other words, precede us).

Using the kernel's version 'sort', which is a mergeheap is
feasible, but would require making the comparison operator
scan recursivly the array to satisfy the "heapify" process: setting the
levels properly. The end result would much more complex than it should
be an it is just much simpler to utilize this simple sort routine.

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>
---
 arch/x86/include/asm/iommu_table.h |    6 ++
 arch/x86/kernel/Makefile           |    1 +
 arch/x86/kernel/pci-iommu_table.c  |   90 ++++++++++++++++++++++++++++++++++++
 3 files changed, 97 insertions(+), 0 deletions(-)
 create mode 100644 arch/x86/kernel/pci-iommu_table.c

diff --git a/arch/x86/include/asm/iommu_table.h b/arch/x86/include/asm/iommu_table.h
index 435176f..2124e3e 100644
--- a/arch/x86/include/asm/iommu_table.h
+++ b/arch/x86/include/asm/iommu_table.h
@@ -92,4 +92,10 @@ struct iommu_table_entry {
 #define IOMMU_INIT(_detect, _depend, _init, _late_init)			\
 	__IOMMU_INIT(_detect, _depend, _init, _late_init, 0)
 
+void sort_iommu_table(struct iommu_table_entry *start,
+		      struct iommu_table_entry *finish);
+
+void check_iommu_entries(struct iommu_table_entry *start,
+			 struct iommu_table_entry *finish);
+
 #endif /* _ASM_X86_IOMMU_TABLE_H */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 0925676..6817546 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -42,6 +42,7 @@ obj-y			+= bootflag.o e820.o
 obj-y			+= pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
 obj-y			+= alternative.o i8253.o pci-nommu.o hw_breakpoint.o
 obj-y			+= tsc.o io_delay.o rtc.o
+obj-y			+= pci-iommu_table.o
 
 obj-$(CONFIG_X86_TRAMPOLINE)	+= trampoline.o
 obj-y				+= process.o
diff --git a/arch/x86/kernel/pci-iommu_table.c b/arch/x86/kernel/pci-iommu_table.c
new file mode 100644
index 0000000..d63451d
--- /dev/null
+++ b/arch/x86/kernel/pci-iommu_table.c
@@ -0,0 +1,90 @@
+#include <linux/dma-mapping.h>
+#include <asm/iommu_table.h>
+#include <linux/string.h>
+#include <linux/kallsyms.h>
+
+
+#define DEBUG 1
+
+static struct iommu_table_entry * __init
+find_dependents_of(struct iommu_table_entry *start,
+		   struct iommu_table_entry *finish,
+		   struct iommu_table_entry *q)
+{
+	struct iommu_table_entry *p;
+
+	if (!q)
+		return NULL;
+
+	for (p = start; p < finish; p++)
+		if (p->detect == q->depend)
+			return p;
+
+	return NULL;
+}
+
+
+void __init sort_iommu_table(struct iommu_table_entry *start,
+			     struct iommu_table_entry *finish) {
+
+	struct iommu_table_entry *p, *q, tmp;
+
+	for (p = start; p < finish; p++) {
+again:
+		q = find_dependents_of(start, finish, p);
+		/* We are bit sneaky here. We use the memory address to figure
+		 * out if the node we depend on is past our point, if so, swap.
+		 */
+		if (q > p) {
+			tmp = *p;
+			memmove(p, q, sizeof(*p));
+			*q = tmp;
+			goto again;
+		}
+	}
+
+}
+
+#ifdef DEBUG
+void __init check_iommu_entries(struct iommu_table_entry *start,
+				struct iommu_table_entry *finish)
+{
+	struct iommu_table_entry *p, *q, *x;
+	char sym_p[KSYM_SYMBOL_LEN];
+	char sym_q[KSYM_SYMBOL_LEN];
+
+	/* Simple cyclic dependency checker. */
+	for (p = start; p < finish; p++) {
+		q = find_dependents_of(start, finish, p);
+		x = find_dependents_of(start, finish, q);
+		if (p == x) {
+			sprint_symbol(sym_p, (unsigned long)p->detect);
+			sprint_symbol(sym_q, (unsigned long)q->detect);
+
+			printk(KERN_ERR "CYCLIC DEPENDENCY FOUND! %s depends" \
+					" on %s and vice-versa. BREAKING IT.\n",
+					sym_p, sym_q);
+			/* Heavy handed way..*/
+			x->depend = 0;
+		}
+	}
+
+	for (p = start; p < finish; p++) {
+		q = find_dependents_of(p, finish, p);
+		if (q && q > p) {
+			sprint_symbol(sym_p, (unsigned long)p->detect);
+			sprint_symbol(sym_q, (unsigned long)q->detect);
+
+			printk(KERN_ERR "EXECUTION ORDER INVALID! %s "\
+					"should be called before %s!\n",
+					sym_p, sym_q);
+		}
+	}
+}
+#else
+inline void check_iommu_entries(struct iommu_table_entry *start,
+				       struct iommu_table_entry *finish)
+{
+}
+#endif
+
-- 
1.7.0.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 04/10] x86/swiotlb: Simplify SWIOTLB pci_swiotlb_detect routine.
  2010-08-26 17:57 [RFC PATCH v2] Modularize IOMMUs detection/init for X86 Konrad Rzeszutek Wilk
                   ` (2 preceding siblings ...)
  2010-08-26 17:57 ` [PATCH 03/10] x86/iommu: Add proper dependency sort routine (and sanity check) Konrad Rzeszutek Wilk
@ 2010-08-26 17:57 ` Konrad Rzeszutek Wilk
  2010-08-26 23:28   ` [tip:x86/iommu] x86, swiotlb: " tip-bot for Konrad Rzeszutek Wilk
  2010-08-26 17:58 ` [PATCH 05/10] x86/swiotlb: Make SWIOTLB use IOMMU_INIT_* macros Konrad Rzeszutek Wilk
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 31+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-08-26 17:57 UTC (permalink / raw)
  To: hpa, fujita.tomonori, linux-kernel; +Cc: Konrad Rzeszutek Wilk, x86

In 'pci_swiotlb_detect' we used to do two different things:
 a). If user provided 'iommu=soft' or 'swiotlb=force' we
     would set swiotlb=1 and return 1 (and forcing pci-dma.c
     to call pci_swiotlb_init() immediately).
 b). If 4GB or more would be detected and if user did not specify
     iommu=off, we would set 'swiotlb=1' and return whatever 'a)'
     figured out.

We simplify this by splitting a) and b) in two different routines.

CC: H. Peter Anvin <hpa@zytor.com>
CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp>
CC: x86@kernel.org
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
 arch/x86/include/asm/iommu_table.h |    4 ++--
 arch/x86/include/asm/swiotlb.h     |   13 +++++++++++--
 arch/x86/kernel/pci-dma.c          |    4 +++-
 arch/x86/kernel/pci-swiotlb.c      |   33 +++++++++++++++++++++++++++------
 4 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/arch/x86/include/asm/iommu_table.h b/arch/x86/include/asm/iommu_table.h
index 2124e3e..df55a78 100644
--- a/arch/x86/include/asm/iommu_table.h
+++ b/arch/x86/include/asm/iommu_table.h
@@ -64,10 +64,10 @@ struct iommu_table_entry {
  * to stop detecting the other IOMMUs after yours has been detected.
  */
 #define IOMMU_INIT_POST(_detect)					\
-	__IOMMU_INIT(_detect, pci_swiotlb_detect,  0, 0, 0)
+	__IOMMU_INIT(_detect, pci_swiotlb_detect_4gb,  0, 0, 0)
 
 #define IOMMU_INIT_POST_FINISH(detect)					\
-	__IOMMU_INIT(_detect, pci_swiotlb_detect,  0, 0, 1)
+	__IOMMU_INIT(_detect, pci_swiotlb_detect_4gb,  0, 0, 1)
 
 /*
  * A more sophisticated version of IOMMU_INIT. This variant requires:
diff --git a/arch/x86/include/asm/swiotlb.h b/arch/x86/include/asm/swiotlb.h
index 8085277..977f176 100644
--- a/arch/x86/include/asm/swiotlb.h
+++ b/arch/x86/include/asm/swiotlb.h
@@ -5,17 +5,26 @@
 
 #ifdef CONFIG_SWIOTLB
 extern int swiotlb;
-extern int __init pci_swiotlb_detect(void);
+extern int __init pci_swiotlb_detect_override(void);
+extern int __init pci_swiotlb_detect_4gb(void);
 extern void __init pci_swiotlb_init(void);
+extern void __init pci_swiotlb_late_init(void);
 #else
 #define swiotlb 0
-static inline int pci_swiotlb_detect(void)
+static inline int pci_swiotlb_detect_override(void)
+{
+	return 0;
+}
+static inline int pci_swiotlb_detect_4gb(void)
 {
 	return 0;
 }
 static inline void pci_swiotlb_init(void)
 {
 }
+static inline void pci_swiotlb_late_init(void)
+{
+}
 #endif
 
 static inline void dma_mark_clean(void *addr, size_t size) {}
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 9f07cfc..1b3beb5 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -133,9 +133,11 @@ void __init pci_iommu_alloc(void)
 	/* free the range so iommu could get some range less than 4G */
 	dma32_free_bootmem();
 
-	if (pci_xen_swiotlb_detect() || pci_swiotlb_detect())
+	if (pci_xen_swiotlb_detect() || pci_swiotlb_detect_override())
 		goto out;
 
+	pci_swiotlb_detect_4gb();
+
 	gart_iommu_hole_init();
 
 	detect_calgary();
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
index a5bc528..c7a72fa 100644
--- a/arch/x86/kernel/pci-swiotlb.c
+++ b/arch/x86/kernel/pci-swiotlb.c
@@ -41,24 +41,33 @@ static struct dma_map_ops swiotlb_dma_ops = {
 };
 
 /*
- * pci_swiotlb_detect - set swiotlb to 1 if necessary
+ * pci_swiotlb_detect_override - set swiotlb to 1 if necessary
  *
  * This returns non-zero if we are forced to use swiotlb (by the boot
  * option).
  */
-int __init pci_swiotlb_detect(void)
+int __init pci_swiotlb_detect_override(void)
 {
 	int use_swiotlb = swiotlb | swiotlb_force;
 
+	if (swiotlb_force)
+		swiotlb = 1;
+
+	return use_swiotlb;
+}
+
+/*
+ * if 4GB or more detected (and iommu=off not set) return 1
+ * and set swiotlb to 1.
+ */
+int __init pci_swiotlb_detect_4gb(void)
+{
 	/* don't initialize swiotlb if iommu=off (no_iommu=1) */
 #ifdef CONFIG_X86_64
 	if (!no_iommu && max_pfn > MAX_DMA32_PFN)
 		swiotlb = 1;
 #endif
-	if (swiotlb_force)
-		swiotlb = 1;
-
-	return use_swiotlb;
+	return swiotlb;
 }
 
 void __init pci_swiotlb_init(void)
@@ -68,3 +77,15 @@ void __init pci_swiotlb_init(void)
 		dma_ops = &swiotlb_dma_ops;
 	}
 }
+
+void __init pci_swiotlb_late_init(void)
+{
+	/* An IOMMU turned us off. */
+	if (!swiotlb)
+		swiotlb_free();
+	else {
+		printk(KERN_INFO "PCI-DMA: "
+		       "Using software bounce buffering for IO (SWIOTLB)\n");
+		swiotlb_print_info();
+	}
+}
-- 
1.7.0.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 05/10] x86/swiotlb: Make SWIOTLB use IOMMU_INIT_* macros.
  2010-08-26 17:57 [RFC PATCH v2] Modularize IOMMUs detection/init for X86 Konrad Rzeszutek Wilk
                   ` (3 preceding siblings ...)
  2010-08-26 17:57 ` [PATCH 04/10] x86/swiotlb: Simplify SWIOTLB pci_swiotlb_detect routine Konrad Rzeszutek Wilk
@ 2010-08-26 17:58 ` Konrad Rzeszutek Wilk
  2010-08-26 23:29   ` [tip:x86/iommu] x86, swiotlb: " tip-bot for Konrad Rzeszutek Wilk
  2010-08-26 17:58 ` [PATCH 06/10] x86/xen-swiotlb: Make Xen-SWIOTLB " Konrad Rzeszutek Wilk
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 31+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-08-26 17:58 UTC (permalink / raw)
  To: hpa, fujita.tomonori, linux-kernel; +Cc: Konrad Rzeszutek Wilk, x86

We utilize the IOMMU_INIT macros to create this dependency:

       [pci_xen_swiotlb_detect]
                 |
       [pci_swiotlb_detect_override]
                 |
       [pci_swiotlb_detect_4gb]

And set the SWIOTLB IOMMU_INIT to utilize 'pci_swiotlb_init'
for .init and 'pci_swiotlb_late_init' for .late_init.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
CC: x86@kernel.org
CC: H. Peter Anvin <hpa@zytor.com>
CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp>
---
 arch/x86/kernel/pci-swiotlb.c |   12 +++++++++++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
index c7a72fa..a5ad584 100644
--- a/arch/x86/kernel/pci-swiotlb.c
+++ b/arch/x86/kernel/pci-swiotlb.c
@@ -10,7 +10,8 @@
 #include <asm/iommu.h>
 #include <asm/swiotlb.h>
 #include <asm/dma.h>
-
+#include <asm/xen/swiotlb-xen.h>
+#include <asm/iommu_table.h>
 int swiotlb __read_mostly;
 
 static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
@@ -55,6 +56,10 @@ int __init pci_swiotlb_detect_override(void)
 
 	return use_swiotlb;
 }
+IOMMU_INIT_FINISH(pci_swiotlb_detect_override,
+		  pci_xen_swiotlb_detect,
+		  pci_swiotlb_init,
+		  pci_swiotlb_late_init);
 
 /*
  * if 4GB or more detected (and iommu=off not set) return 1
@@ -69,6 +74,10 @@ int __init pci_swiotlb_detect_4gb(void)
 #endif
 	return swiotlb;
 }
+IOMMU_INIT(pci_swiotlb_detect_4gb,
+	   pci_swiotlb_detect_override,
+	   pci_swiotlb_init,
+	   pci_swiotlb_late_init);
 
 void __init pci_swiotlb_init(void)
 {
@@ -89,3 +98,4 @@ void __init pci_swiotlb_late_init(void)
 		swiotlb_print_info();
 	}
 }
+
-- 
1.7.0.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 06/10] x86/xen-swiotlb: Make Xen-SWIOTLB use IOMMU_INIT_* macros.
  2010-08-26 17:57 [RFC PATCH v2] Modularize IOMMUs detection/init for X86 Konrad Rzeszutek Wilk
                   ` (4 preceding siblings ...)
  2010-08-26 17:58 ` [PATCH 05/10] x86/swiotlb: Make SWIOTLB use IOMMU_INIT_* macros Konrad Rzeszutek Wilk
@ 2010-08-26 17:58 ` Konrad Rzeszutek Wilk
  2010-08-26 23:29   ` [tip:x86/iommu] x86, xen-swiotlb: " tip-bot for Konrad Rzeszutek Wilk
  2010-08-26 17:58 ` [PATCH 07/10] x86/calgary: Make Calgary IOMMU " Konrad Rzeszutek Wilk
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 31+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-08-26 17:58 UTC (permalink / raw)
  To: hpa, fujita.tomonori, linux-kernel; +Cc: Konrad Rzeszutek Wilk

We utilize the IOMMU_INIT macros to create this dependency:

               [null]
                 |
       [pci_xen_swiotlb_detect]
                 |
       [pci_swiotlb_detect_override]
                 |
       [pci_swiotlb_detect_4gb]

In other words, we set 'pci_xen_swiotlb_detect' to be
the first detection to be run during start.

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/xen/pci-swiotlb-xen.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c
index a013ec9..2247100 100644
--- a/arch/x86/xen/pci-swiotlb-xen.c
+++ b/arch/x86/xen/pci-swiotlb-xen.c
@@ -5,6 +5,7 @@
 
 #include <asm/xen/hypervisor.h>
 #include <xen/xen.h>
+#include <asm/iommu_table.h>
 
 int xen_swiotlb __read_mostly;
 
@@ -56,3 +57,7 @@ void __init pci_xen_swiotlb_init(void)
 		dma_ops = &xen_swiotlb_dma_ops;
 	}
 }
+IOMMU_INIT_FINISH(pci_xen_swiotlb_detect,
+		  0,
+		  pci_xen_swiotlb_init,
+		  0);
-- 
1.7.0.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 07/10] x86/calgary: Make Calgary IOMMU use IOMMU_INIT_* macros.
  2010-08-26 17:57 [RFC PATCH v2] Modularize IOMMUs detection/init for X86 Konrad Rzeszutek Wilk
                   ` (5 preceding siblings ...)
  2010-08-26 17:58 ` [PATCH 06/10] x86/xen-swiotlb: Make Xen-SWIOTLB " Konrad Rzeszutek Wilk
@ 2010-08-26 17:58 ` Konrad Rzeszutek Wilk
  2010-08-26 23:30   ` [tip:x86/iommu] x86, calgary: " tip-bot for Konrad Rzeszutek Wilk
  2010-08-26 17:58 ` [PATCH 08/10] x86/GART/AMD-VI: Make AMD GART and " Konrad Rzeszutek Wilk
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 31+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-08-26 17:58 UTC (permalink / raw)
  To: hpa, fujita.tomonori, linux-kernel
  Cc: Konrad Rzeszutek Wilk, Muli Ben-Yehuda, Jon D. Mason, Darrick J. Wong

We utilize the IOMMU_INIT macros to create this dependency:

     [pci_xen_swiotlb_detect]
         |
     [pci_swiotlb_detect_override]
         |
     [pci_swiotlb_detect_4gb]
         |
      [detect_calgary]

Meaning that 'detect_calgary' is going to be called after
'pci_swiotlb_detect'.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
CC: Muli Ben-Yehuda <muli@il.ibm.com>
CC: "Jon D. Mason" <jdmason@kudzu.us>
CC: "Darrick J. Wong" <djwong@us.ibm.com>
CC: H. Peter Anvin <hpa@zytor.com>
CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp>
---
 arch/x86/kernel/pci-calgary_64.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 28c6b38..f56a117 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -47,6 +47,7 @@
 #include <asm/rio.h>
 #include <asm/bios_ebda.h>
 #include <asm/x86_init.h>
+#include <asm/iommu_table.h>
 
 #ifdef CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT
 int use_calgary __read_mostly = 1;
@@ -1595,3 +1596,5 @@ static int __init calgary_fixup_tce_spaces(void)
  * and before device_initcall.
  */
 rootfs_initcall(calgary_fixup_tce_spaces);
+
+IOMMU_INIT_POST(detect_calgary);
-- 
1.7.0.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 08/10] x86/GART/AMD-VI: Make AMD GART and IOMMU use IOMMU_INIT_* macros.
  2010-08-26 17:57 [RFC PATCH v2] Modularize IOMMUs detection/init for X86 Konrad Rzeszutek Wilk
                   ` (6 preceding siblings ...)
  2010-08-26 17:58 ` [PATCH 07/10] x86/calgary: Make Calgary IOMMU " Konrad Rzeszutek Wilk
@ 2010-08-26 17:58 ` Konrad Rzeszutek Wilk
  2010-08-26 23:30   ` [tip:x86/iommu] x86, GART/AMD-VI: " tip-bot for Konrad Rzeszutek Wilk
  2010-08-26 17:58 ` [PATCH 09/10] x86/VT-d: Make Intel VT-d " Konrad Rzeszutek Wilk
  2010-08-26 17:58 ` [PATCH 10/10] x86/iommu: Utilize the IOMMU_INIT macros functionality Konrad Rzeszutek Wilk
  9 siblings, 1 reply; 31+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-08-26 17:58 UTC (permalink / raw)
  To: hpa, fujita.tomonori, linux-kernel
  Cc: Konrad Rzeszutek Wilk, Joerg Roedel, Thomas Gleixner, Ingo Molnar

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 bytes */
@@ -896,3 +897,4 @@ void __init gart_parse_options(char *p)
 		}
 	}
 }
+IOMMU_INIT_POST(gart_iommu_hole_init);
-- 
1.7.0.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 09/10] x86/VT-d: Make Intel VT-d IOMMU use IOMMU_INIT_* macros.
  2010-08-26 17:57 [RFC PATCH v2] Modularize IOMMUs detection/init for X86 Konrad Rzeszutek Wilk
                   ` (7 preceding siblings ...)
  2010-08-26 17:58 ` [PATCH 08/10] x86/GART/AMD-VI: Make AMD GART and " Konrad Rzeszutek Wilk
@ 2010-08-26 17:58 ` Konrad Rzeszutek Wilk
  2010-08-26 23:30   ` [tip:x86/iommu] x86, VT-d: " tip-bot for Konrad Rzeszutek Wilk
  2010-09-07 18:10   ` [PATCH 09/10] x86/VT-d: " Tony Luck
  2010-08-26 17:58 ` [PATCH 10/10] x86/iommu: Utilize the IOMMU_INIT macros functionality Konrad Rzeszutek Wilk
  9 siblings, 2 replies; 31+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-08-26 17:58 UTC (permalink / raw)
  To: hpa, fujita.tomonori, linux-kernel
  Cc: Konrad Rzeszutek Wilk, Jesse Barnes, David Woodhouse, Len Brown,
	Chris Wright, Yinghai Lu

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


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 10/10] x86/iommu: Utilize the IOMMU_INIT macros functionality.
  2010-08-26 17:57 [RFC PATCH v2] Modularize IOMMUs detection/init for X86 Konrad Rzeszutek Wilk
                   ` (8 preceding siblings ...)
  2010-08-26 17:58 ` [PATCH 09/10] x86/VT-d: Make Intel VT-d " Konrad Rzeszutek Wilk
@ 2010-08-26 17:58 ` Konrad Rzeszutek Wilk
  2010-08-26 23:31   ` [tip:x86/iommu] x86, iommu: " tip-bot for Konrad Rzeszutek Wilk
  9 siblings, 1 reply; 31+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-08-26 17:58 UTC (permalink / raw)
  To: hpa, fujita.tomonori, linux-kernel
  Cc: Konrad Rzeszutek Wilk, Thomas Gleixner, Ingo Molnar, x86

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 out;
-
-	pci_swiotlb_detect_4gb();
-
-	gart_iommu_hole_init();
-
-	detect_calgary();
-
-	detect_intel_iommu();
+	sort_iommu_table(__iommu_table, __iommu_table_end);
+	check_iommu_entries(__iommu_table, __iommu_table_end);
 
-	/* needs to be called after gart_iommu_hole_init */
-	amd_iommu_detect();
-out:
-	pci_xen_swiotlb_init();
-
-	pci_swiotlb_init();
+	for (p = __iommu_table; p < __iommu_table_end; p++) {
+		if (p && p->detect && p->detect() > 0) {
+			p->flags |= IOMMU_DETECTED;
+			if (p->early_init)
+				p->early_init();
+			if (p->flags & IOMMU_FINISH_IF_DETECTED)
+				break;
+		}
+	}
 }
-
 void *dma_generic_alloc_coherent(struct device *dev, size_t size,
 				 dma_addr_t *dma_addr, gfp_t flag)
 {
@@ -294,6 +291,7 @@ EXPORT_SYMBOL(dma_supported);
 
 static int __init pci_iommu_init(void)
 {
+	struct iommu_table_entry *p;
 	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
 
 #ifdef CONFIG_PCI
@@ -301,12 +299,10 @@ static int __init pci_iommu_init(void)
 #endif
 	x86_init.iommu.iommu_init();
 
-	if (swiotlb || xen_swiotlb) {
-		printk(KERN_INFO "PCI-DMA: "
-		       "Using software bounce buffering for IO (SWIOTLB)\n");
-		swiotlb_print_info();
-	} else
-		swiotlb_free();
+	for (p = __iommu_table; p < __iommu_table_end; p++) {
+		if (p && (p->flags & IOMMU_DETECTED) && p->late_init)
+			p->late_init();
+	}
 
 	return 0;
 }
-- 
1.7.0.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 01/10] x86/iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure.
  2010-08-26 17:57 ` [PATCH 01/10] x86/iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure Konrad Rzeszutek Wilk
@ 2010-08-26 18:19   ` Sam Ravnborg
  2010-08-26 19:48     ` H. Peter Anvin
                       ` (2 more replies)
  2010-08-26 23:27   ` [tip:x86/iommu] x86, iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure tip-bot for Konrad Rzeszutek Wilk
  1 sibling, 3 replies; 31+ messages in thread
From: Sam Ravnborg @ 2010-08-26 18:19 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk
  Cc: hpa, fujita.tomonori, linux-kernel, x86, Thomas Gleixner, Ingo Molnar

> diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
> index d0bb522..b92e040 100644
> --- a/arch/x86/kernel/vmlinux.lds.S
> +++ b/arch/x86/kernel/vmlinux.lds.S
> @@ -260,6 +260,13 @@ SECTIONS
>  		*(.altinstr_replacement)
>  	}
>  
> +	.iommu_table : AT(ADDR(.iommu_table) - LOAD_OFFSET) {
> +		__iommu_table = .;
> +		*(.iommu_table)
> +		. = ALIGN(8);
> +		__iommu_table_end = .;
> +	}
> +

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

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 01/10] x86/iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure.
  2010-08-26 18:19   ` Sam Ravnborg
@ 2010-08-26 19:48     ` H. Peter Anvin
  2010-08-26 23:47     ` H. Peter Anvin
  2010-08-27 14:38     ` Konrad Rzeszutek Wilk
  2 siblings, 0 replies; 31+ messages in thread
From: H. Peter Anvin @ 2010-08-26 19:48 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Konrad Rzeszutek Wilk, fujita.tomonori, linux-kernel, x86,
	Thomas Gleixner, Ingo Molnar

On 08/26/2010 11:19 AM, Sam Ravnborg wrote:
> 
> 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.
> 

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

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [tip:x86/iommu] x86, iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure
  2010-08-26 17:57 ` [PATCH 01/10] x86/iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure Konrad Rzeszutek Wilk
  2010-08-26 18:19   ` Sam Ravnborg
@ 2010-08-26 23:27   ` tip-bot for Konrad Rzeszutek Wilk
  1 sibling, 0 replies; 31+ messages in thread
From: tip-bot for Konrad Rzeszutek Wilk @ 2010-08-26 23:27 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, konrad.wilk, fujita.tomonori, tglx, hpa

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 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.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
LKML-Reference: <1282845485-8991-2-git-send-email-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>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
---
 arch/x86/include/asm/iommu_table.h |   95 ++++++++++++++++++++++++++++++++++++
 arch/x86/kernel/vmlinux.lds.S      |    7 +++
 2 files changed, 102 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/iommu_table.h b/arch/x86/include/asm/iommu_table.h
new file mode 100644
index 0000000..435176f
--- /dev/null
+++ b/arch/x86/include/asm/iommu_table.h
@@ -0,0 +1,95 @@
+
+#ifndef _ASM_X86_IOMMU_TABLE_H
+#define _ASM_X86_IOMMU_TABLE_H
+
+#include <asm/swiotlb.h>
+
+/*
+ * History lesson:
+ * The execution chain of IOMMUs in 2.6.36 looks as so:
+ *
+ *            [xen-swiotlb]
+ *                 |
+ *         +----[swiotlb *]--+
+ *        /         |         \
+ *       /          |          \
+ *    [GART]     [Calgary]  [Intel VT-d]
+ *     /
+ *    /
+ * [AMD-Vi]
+ *
+ * *: if SWIOTLB detected 'iommu=soft'/'swiotlb=force' it would skip
+ * over the rest of IOMMUs and unconditionally initialize the SWIOTLB.
+ * Also it would surreptitiously initialize set the swiotlb=1 if there were
+ * more than 4GB and if the user did not pass in 'iommu=off'. The swiotlb
+ * flag would be turned off by all IOMMUs except the Calgary one.
+ *
+ * The IOMMU_INIT* macros allow a similar tree (or more complex if desired)
+ * to be built by defining who we depend on.
+ *
+ * And all that needs to be done is to use one of the macros in the IOMMU
+ * and the pci-dma.c will take care of the rest.
+ */
+
+struct iommu_table_entry {
+	initcall_t	detect;
+	initcall_t	depend;
+	void		(*early_init)(void); /* No memory allocate available. */
+	void		(*late_init)(void); /* Yes, can allocate memory. */
+#define IOMMU_FINISH_IF_DETECTED (1<<0)
+#define IOMMU_DETECTED		 (1<<1)
+	int		flags;
+};
+/*
+ * Macro fills out an entry in the .iommu_table that is equivalent
+ * to the fields that 'struct iommu_table_entry' has. The entries
+ * that are put in the .iommu_table section are not put in any order
+ * hence during boot-time we will have to resort them based on
+ * dependency. */
+
+
+#define __IOMMU_INIT(_detect, _depend, _early_init, _late_init, _finish)\
+	static const struct iommu_table_entry const			\
+		__iommu_entry_##_detect __used				\
+	__attribute__ ((unused, __section__(".iommu_table"),		\
+			aligned((sizeof(void *)))))	\
+	= {_detect, _depend, _early_init, _late_init,			\
+	   _finish ? IOMMU_FINISH_IF_DETECTED : 0}
+/*
+ * The simplest IOMMU definition. Provide the detection routine
+ * and it will be run after the SWIOTLB and the other IOMMUs
+ * that utilize this macro. If the IOMMU is detected (ie, the
+ * detect routine returns a positive value), the other IOMMUs
+ * are also checked. You can use IOMMU_INIT_FINISH if you prefer
+ * to stop detecting the other IOMMUs after yours has been detected.
+ */
+#define IOMMU_INIT_POST(_detect)					\
+	__IOMMU_INIT(_detect, pci_swiotlb_detect,  0, 0, 0)
+
+#define IOMMU_INIT_POST_FINISH(detect)					\
+	__IOMMU_INIT(_detect, pci_swiotlb_detect,  0, 0, 1)
+
+/*
+ * A more sophisticated version of IOMMU_INIT. This variant requires:
+ *  a). A detection routine function.
+ *  b). The name of the detection routine we depend on to get called
+ *      before us.
+ *  c). The init routine which gets called if the detection routine
+ *      returns a positive value from the pci_iommu_alloc. This means
+ *      no presence of a memory allocator.
+ *  d). Similar to the 'init', except that this gets called from pci_iommu_init
+ *      where we do have a memory allocator.
+ *
+ * The _CONT vs the _EXIT differs in that the _CONT variant will
+ * continue detecting other IOMMUs in the call list after the
+ * the detection routine returns a positive number. The _EXIT will
+ * stop the execution chain. Both will still call the 'init' and
+ * 'late_init' functions if they are set.
+ */
+#define IOMMU_INIT_FINISH(_detect, _depend, _init, _late_init)		\
+	__IOMMU_INIT(_detect, _depend, _init, _late_init, 1)
+
+#define IOMMU_INIT(_detect, _depend, _init, _late_init)			\
+	__IOMMU_INIT(_detect, _depend, _init, _late_init, 0)
+
+#endif /* _ASM_X86_IOMMU_TABLE_H */
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index d0bb522..b92e040 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -260,6 +260,13 @@ SECTIONS
 		*(.altinstr_replacement)
 	}
 
+	.iommu_table : AT(ADDR(.iommu_table) - LOAD_OFFSET) {
+		__iommu_table = .;
+		*(.iommu_table)
+		. = ALIGN(8);
+		__iommu_table_end = .;
+	}
+
 	/*
 	 * .exit.text is discard at runtime, not link time, to deal with
 	 *  references from .altinstructions and .eh_frame

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [tip:x86/iommu] x86, iommu: Make all IOMMU's detection routines return a value.
  2010-08-26 17:57 ` [PATCH 02/10] x86/iommu: Make all IOMMU's detection routines return a value Konrad Rzeszutek Wilk
@ 2010-08-26 23:28   ` tip-bot for Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 31+ messages in thread
From: tip-bot for Konrad Rzeszutek Wilk @ 2010-08-26 23:28 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, yinghai, konrad.wilk, joerg.roedel,
	fujita.tomonori, djwong, muli, jdmason, jbarnes, chrisw, tglx,
	hpa, David.Woodhouse

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 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 detect_calgary(void);
 #else
-static inline void detect_calgary(void) { return; }
+static inline int detect_calgary(void) { return -ENODEV; }
 #endif
 
 #endif /* _ASM_X86_CALGARY_H */
diff --git a/arch/x86/include/asm/gart.h b/arch/x86/include/asm/gart.h
index 4ac5b0f..d7d1d4c 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;
 extern void early_gart_iommu_check(void);
 extern int gart_iommu_init(void);
 extern void __init gart_parse_options(char *);
-extern void gart_iommu_hole_init(void);
+extern int gart_iommu_hole_init(void);
 
 #else
 #define gart_iommu_aperture            0
@@ -50,8 +50,9 @@ static inline void early_gart_iommu_check(void)
 static inline void gart_parse_options(char *options)
 {
 }
-static inline void gart_iommu_hole_init(void)
+static inline int gart_iommu_hole_init(void)
 {
+	return -ENODEV;
 }
 #endif
 
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index 3cc63e2..0b9e2dc 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -1382,13 +1382,13 @@ static int __init early_amd_iommu_detect(struct acpi_table_header *table)
 	return 0;
 }
 
-void __init amd_iommu_detect(void)
+int __init amd_iommu_detect(void)
 {
 	if (no_iommu || (iommu_detected && !gart_iommu_aperture))
-		return;
+		return -ENODEV;
 
 	if (amd_iommu_disabled)
-		return;
+		return -ENODEV;
 
 	if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) {
 		iommu_detected = 1;
@@ -1397,7 +1397,9 @@ void __init amd_iommu_detect(void)
 
 		/* Make sure ACS will be enabled */
 		pci_request_acs();
+		return 1;
 	}
+	return -ENODEV;
 }
 
 /****************************************************************************
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index a2e0caf..afa0dab 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)
 
 static int __initdata printed_gart_size_msg;
 
-void __init gart_iommu_hole_init(void)
+int __init gart_iommu_hole_init(void)
 {
 	u32 agp_aper_base = 0, agp_aper_order = 0;
 	u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0;
@@ -381,7 +381,7 @@ void __init gart_iommu_hole_init(void)
 
 	if (gart_iommu_aperture_disabled || !fix_aperture ||
 	    !early_pci_allowed())
-		return;
+		return -ENODEV;
 
 	printk(KERN_INFO  "Checking aperture...\n");
 
@@ -463,8 +463,9 @@ out:
 			unsigned long n = (32 * 1024 * 1024) << last_aper_order;
 
 			insert_aperture_resource((u32)last_aper_base, n);
+			return 1;
 		}
-		return;
+		return 0;
 	}
 
 	if (!fallback_aper_force) {
@@ -500,7 +501,7 @@ out:
 			panic("Not enough memory for aperture");
 		}
 	} else {
-		return;
+		return 0;
 	}
 
 	/* Fix up the north bridges */
@@ -524,4 +525,6 @@ out:
 	}
 
 	set_up_gart_resume(aper_order, aper_alloc);
+
+	return 1;
 }
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 078d4ec..28c6b38 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -1364,7 +1364,7 @@ static int __init calgary_iommu_init(void)
 	return 0;
 }
 
-void __init detect_calgary(void)
+int __init detect_calgary(void)
 {
 	int bus;
 	void *tbl;
@@ -1378,13 +1378,13 @@ void __init detect_calgary(void)
 	 * another HW IOMMU already, bail out.
 	 */
 	if (no_iommu || iommu_detected)
-		return;
+		return -ENODEV;
 
 	if (!use_calgary)
-		return;
+		return -ENODEV;
 
 	if (!early_pci_allowed())
-		return;
+		return -ENODEV;
 
 	printk(KERN_DEBUG "Calgary: detecting Calgary via BIOS EBDA area\n");
 
@@ -1410,13 +1410,13 @@ void __init detect_calgary(void)
 	if (!rio_table_hdr) {
 		printk(KERN_DEBUG "Calgary: Unable to locate Rio Grande table "
 		       "in EBDA - bailing!\n");
-		return;
+		return -ENODEV;
 	}
 
 	ret = build_detail_arrays();
 	if (ret) {
 		printk(KERN_DEBUG "Calgary: build_detail_arrays ret %d\n", ret);
-		return;
+		return -ENOMEM;
 	}
 
 	specified_table_size = determine_tce_table_size((is_kdump_kernel() ?
@@ -1464,7 +1464,7 @@ void __init detect_calgary(void)
 
 		x86_init.iommu.iommu_init = calgary_iommu_init;
 	}
-	return;
+	return calgary_found;
 
 cleanup:
 	for (--bus; bus >= 0; --bus) {
@@ -1473,6 +1473,7 @@ cleanup:
 		if (info->tce_space)
 			free_tce_table(info->tce_space);
 	}
+	return -ENOMEM;
 }
 
 static int __init calgary_parse_options(char *p)
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 0a19708..5fa64ea 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -687,7 +687,7 @@ failed:
 	return 0;
 }
 
-void __init detect_intel_iommu(void)
+int __init detect_intel_iommu(void)
 {
 	int ret;
 
@@ -723,6 +723,8 @@ void __init detect_intel_iommu(void)
 	}
 	early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size);
 	dmar_tbl = NULL;
+
+	return (ret ? 1 : -ENODEV);
 }
 
 
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index d7cecc9..a206020 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -57,15 +57,15 @@ extern int dmar_table_init(void);
 extern int dmar_dev_scope_init(void);
 
 /* Intel IOMMU detection */
-extern void detect_intel_iommu(void);
+extern int detect_intel_iommu(void);
 extern int enable_drhd_fault_handling(void);
 
 extern int parse_ioapics_under_ir(void);
 extern int alloc_iommu(struct dmar_drhd_unit *);
 #else
-static inline void detect_intel_iommu(void)
+static inline int detect_intel_iommu(void)
 {
-	return;
+	return -ENODEV;
 }
 
 static inline int dmar_table_init(void)

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [tip:x86/iommu] x86, iommu: Add proper dependency sort routine (and sanity check).
  2010-08-26 17:57 ` [PATCH 03/10] x86/iommu: Add proper dependency sort routine (and sanity check) Konrad Rzeszutek Wilk
@ 2010-08-26 23:28   ` tip-bot for Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 31+ messages in thread
From: tip-bot for Konrad Rzeszutek Wilk @ 2010-08-26 23:28 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, konrad.wilk, fujita.tomonori, tglx, hpa

Commit-ID:  5bef80a4b826b9cee1c6aec7ecc371ec395260cc
Gitweb:     http://git.kernel.org/tip/5bef80a4b826b9cee1c6aec7ecc371ec395260cc
Author:     Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
AuthorDate: Thu, 26 Aug 2010 13:57:58 -0400
Committer:  H. Peter Anvin <hpa@linux.intel.com>
CommitDate: Thu, 26 Aug 2010 15:13:19 -0700

x86, iommu: Add proper dependency sort routine (and sanity check).

We are using a very simple sort routine which sorts the .iommu_table
array in the order of dependencies. Specifically each structure
of iommu_table_entry has a field 'depend' which contains the function
pointer to the IOMMU that MUST be run before us. We sort the array
of structures so that the struct iommu_table_entry with no
'depend' field are first, and then the subsequent ones are the
ones for which the 'depend' function has been already invoked
(in other words, precede us).

Using the kernel's version 'sort', which is a mergeheap is
feasible, but would require making the comparison operator
scan recursivly the array to satisfy the "heapify" process: setting the
levels properly. The end result would much more complex than it should
be an it is just much simpler to utilize this simple sort routine.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
LKML-Reference: <1282845485-8991-4-git-send-email-konrad.wilk@oracle.com>
CC: H. Peter Anvin <hpa@zytor.com>
CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
---
 arch/x86/include/asm/iommu_table.h |    6 ++
 arch/x86/kernel/Makefile           |    1 +
 arch/x86/kernel/pci-iommu_table.c  |   89 ++++++++++++++++++++++++++++++++++++
 3 files changed, 96 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/iommu_table.h b/arch/x86/include/asm/iommu_table.h
index 435176f..2124e3e 100644
--- a/arch/x86/include/asm/iommu_table.h
+++ b/arch/x86/include/asm/iommu_table.h
@@ -92,4 +92,10 @@ struct iommu_table_entry {
 #define IOMMU_INIT(_detect, _depend, _init, _late_init)			\
 	__IOMMU_INIT(_detect, _depend, _init, _late_init, 0)
 
+void sort_iommu_table(struct iommu_table_entry *start,
+		      struct iommu_table_entry *finish);
+
+void check_iommu_entries(struct iommu_table_entry *start,
+			 struct iommu_table_entry *finish);
+
 #endif /* _ASM_X86_IOMMU_TABLE_H */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 0925676..6817546 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -42,6 +42,7 @@ obj-y			+= bootflag.o e820.o
 obj-y			+= pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
 obj-y			+= alternative.o i8253.o pci-nommu.o hw_breakpoint.o
 obj-y			+= tsc.o io_delay.o rtc.o
+obj-y			+= pci-iommu_table.o
 
 obj-$(CONFIG_X86_TRAMPOLINE)	+= trampoline.o
 obj-y				+= process.o
diff --git a/arch/x86/kernel/pci-iommu_table.c b/arch/x86/kernel/pci-iommu_table.c
new file mode 100644
index 0000000..55d745e
--- /dev/null
+++ b/arch/x86/kernel/pci-iommu_table.c
@@ -0,0 +1,89 @@
+#include <linux/dma-mapping.h>
+#include <asm/iommu_table.h>
+#include <linux/string.h>
+#include <linux/kallsyms.h>
+
+
+#define DEBUG 1
+
+static struct iommu_table_entry * __init
+find_dependents_of(struct iommu_table_entry *start,
+		   struct iommu_table_entry *finish,
+		   struct iommu_table_entry *q)
+{
+	struct iommu_table_entry *p;
+
+	if (!q)
+		return NULL;
+
+	for (p = start; p < finish; p++)
+		if (p->detect == q->depend)
+			return p;
+
+	return NULL;
+}
+
+
+void __init sort_iommu_table(struct iommu_table_entry *start,
+			     struct iommu_table_entry *finish) {
+
+	struct iommu_table_entry *p, *q, tmp;
+
+	for (p = start; p < finish; p++) {
+again:
+		q = find_dependents_of(start, finish, p);
+		/* We are bit sneaky here. We use the memory address to figure
+		 * out if the node we depend on is past our point, if so, swap.
+		 */
+		if (q > p) {
+			tmp = *p;
+			memmove(p, q, sizeof(*p));
+			*q = tmp;
+			goto again;
+		}
+	}
+
+}
+
+#ifdef DEBUG
+void __init check_iommu_entries(struct iommu_table_entry *start,
+				struct iommu_table_entry *finish)
+{
+	struct iommu_table_entry *p, *q, *x;
+	char sym_p[KSYM_SYMBOL_LEN];
+	char sym_q[KSYM_SYMBOL_LEN];
+
+	/* Simple cyclic dependency checker. */
+	for (p = start; p < finish; p++) {
+		q = find_dependents_of(start, finish, p);
+		x = find_dependents_of(start, finish, q);
+		if (p == x) {
+			sprint_symbol(sym_p, (unsigned long)p->detect);
+			sprint_symbol(sym_q, (unsigned long)q->detect);
+
+			printk(KERN_ERR "CYCLIC DEPENDENCY FOUND! %s depends" \
+					" on %s and vice-versa. BREAKING IT.\n",
+					sym_p, sym_q);
+			/* Heavy handed way..*/
+			x->depend = 0;
+		}
+	}
+
+	for (p = start; p < finish; p++) {
+		q = find_dependents_of(p, finish, p);
+		if (q && q > p) {
+			sprint_symbol(sym_p, (unsigned long)p->detect);
+			sprint_symbol(sym_q, (unsigned long)q->detect);
+
+			printk(KERN_ERR "EXECUTION ORDER INVALID! %s "\
+					"should be called before %s!\n",
+					sym_p, sym_q);
+		}
+	}
+}
+#else
+inline void check_iommu_entries(struct iommu_table_entry *start,
+				       struct iommu_table_entry *finish)
+{
+}
+#endif

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [tip:x86/iommu] x86, swiotlb: Simplify SWIOTLB pci_swiotlb_detect routine.
  2010-08-26 17:57 ` [PATCH 04/10] x86/swiotlb: Simplify SWIOTLB pci_swiotlb_detect routine Konrad Rzeszutek Wilk
@ 2010-08-26 23:28   ` tip-bot for Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 31+ messages in thread
From: tip-bot for Konrad Rzeszutek Wilk @ 2010-08-26 23:28 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, konrad.wilk, fujita.tomonori, tglx, hpa

Commit-ID:  efa631c26d3bb1162b8f95008801db602217f52b
Gitweb:     http://git.kernel.org/tip/efa631c26d3bb1162b8f95008801db602217f52b
Author:     Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
AuthorDate: Thu, 26 Aug 2010 13:57:59 -0400
Committer:  H. Peter Anvin <hpa@linux.intel.com>
CommitDate: Thu, 26 Aug 2010 15:13:29 -0700

x86, swiotlb: Simplify SWIOTLB pci_swiotlb_detect routine.

In 'pci_swiotlb_detect' we used to do two different things:
 a). If user provided 'iommu=soft' or 'swiotlb=force' we
     would set swiotlb=1 and return 1 (and forcing pci-dma.c
     to call pci_swiotlb_init() immediately).
 b). If 4GB or more would be detected and if user did not specify
     iommu=off, we would set 'swiotlb=1' and return whatever 'a)'
     figured out.

We simplify this by splitting a) and b) in two different routines.

CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
LKML-Reference: <1282845485-8991-5-git-send-email-konrad.wilk@oracle.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
---
 arch/x86/include/asm/iommu_table.h |    4 ++--
 arch/x86/include/asm/swiotlb.h     |   13 +++++++++++--
 arch/x86/kernel/pci-dma.c          |    4 +++-
 arch/x86/kernel/pci-swiotlb.c      |   33 +++++++++++++++++++++++++++------
 4 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/arch/x86/include/asm/iommu_table.h b/arch/x86/include/asm/iommu_table.h
index 2124e3e..df55a78 100644
--- a/arch/x86/include/asm/iommu_table.h
+++ b/arch/x86/include/asm/iommu_table.h
@@ -64,10 +64,10 @@ struct iommu_table_entry {
  * to stop detecting the other IOMMUs after yours has been detected.
  */
 #define IOMMU_INIT_POST(_detect)					\
-	__IOMMU_INIT(_detect, pci_swiotlb_detect,  0, 0, 0)
+	__IOMMU_INIT(_detect, pci_swiotlb_detect_4gb,  0, 0, 0)
 
 #define IOMMU_INIT_POST_FINISH(detect)					\
-	__IOMMU_INIT(_detect, pci_swiotlb_detect,  0, 0, 1)
+	__IOMMU_INIT(_detect, pci_swiotlb_detect_4gb,  0, 0, 1)
 
 /*
  * A more sophisticated version of IOMMU_INIT. This variant requires:
diff --git a/arch/x86/include/asm/swiotlb.h b/arch/x86/include/asm/swiotlb.h
index 8085277..977f176 100644
--- a/arch/x86/include/asm/swiotlb.h
+++ b/arch/x86/include/asm/swiotlb.h
@@ -5,17 +5,26 @@
 
 #ifdef CONFIG_SWIOTLB
 extern int swiotlb;
-extern int __init pci_swiotlb_detect(void);
+extern int __init pci_swiotlb_detect_override(void);
+extern int __init pci_swiotlb_detect_4gb(void);
 extern void __init pci_swiotlb_init(void);
+extern void __init pci_swiotlb_late_init(void);
 #else
 #define swiotlb 0
-static inline int pci_swiotlb_detect(void)
+static inline int pci_swiotlb_detect_override(void)
+{
+	return 0;
+}
+static inline int pci_swiotlb_detect_4gb(void)
 {
 	return 0;
 }
 static inline void pci_swiotlb_init(void)
 {
 }
+static inline void pci_swiotlb_late_init(void)
+{
+}
 #endif
 
 static inline void dma_mark_clean(void *addr, size_t size) {}
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 9f07cfc..1b3beb5 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -133,9 +133,11 @@ void __init pci_iommu_alloc(void)
 	/* free the range so iommu could get some range less than 4G */
 	dma32_free_bootmem();
 
-	if (pci_xen_swiotlb_detect() || pci_swiotlb_detect())
+	if (pci_xen_swiotlb_detect() || pci_swiotlb_detect_override())
 		goto out;
 
+	pci_swiotlb_detect_4gb();
+
 	gart_iommu_hole_init();
 
 	detect_calgary();
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
index a5bc528..c7a72fa 100644
--- a/arch/x86/kernel/pci-swiotlb.c
+++ b/arch/x86/kernel/pci-swiotlb.c
@@ -41,24 +41,33 @@ static struct dma_map_ops swiotlb_dma_ops = {
 };
 
 /*
- * pci_swiotlb_detect - set swiotlb to 1 if necessary
+ * pci_swiotlb_detect_override - set swiotlb to 1 if necessary
  *
  * This returns non-zero if we are forced to use swiotlb (by the boot
  * option).
  */
-int __init pci_swiotlb_detect(void)
+int __init pci_swiotlb_detect_override(void)
 {
 	int use_swiotlb = swiotlb | swiotlb_force;
 
+	if (swiotlb_force)
+		swiotlb = 1;
+
+	return use_swiotlb;
+}
+
+/*
+ * if 4GB or more detected (and iommu=off not set) return 1
+ * and set swiotlb to 1.
+ */
+int __init pci_swiotlb_detect_4gb(void)
+{
 	/* don't initialize swiotlb if iommu=off (no_iommu=1) */
 #ifdef CONFIG_X86_64
 	if (!no_iommu && max_pfn > MAX_DMA32_PFN)
 		swiotlb = 1;
 #endif
-	if (swiotlb_force)
-		swiotlb = 1;
-
-	return use_swiotlb;
+	return swiotlb;
 }
 
 void __init pci_swiotlb_init(void)
@@ -68,3 +77,15 @@ void __init pci_swiotlb_init(void)
 		dma_ops = &swiotlb_dma_ops;
 	}
 }
+
+void __init pci_swiotlb_late_init(void)
+{
+	/* An IOMMU turned us off. */
+	if (!swiotlb)
+		swiotlb_free();
+	else {
+		printk(KERN_INFO "PCI-DMA: "
+		       "Using software bounce buffering for IO (SWIOTLB)\n");
+		swiotlb_print_info();
+	}
+}

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [tip:x86/iommu] x86, swiotlb: Make SWIOTLB use IOMMU_INIT_* macros.
  2010-08-26 17:58 ` [PATCH 05/10] x86/swiotlb: Make SWIOTLB use IOMMU_INIT_* macros Konrad Rzeszutek Wilk
@ 2010-08-26 23:29   ` tip-bot for Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 31+ messages in thread
From: tip-bot for Konrad Rzeszutek Wilk @ 2010-08-26 23:29 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, konrad.wilk, fujita.tomonori, tglx, hpa

Commit-ID:  c116c5457c46edb767df6f4e36d4905e3514ad37
Gitweb:     http://git.kernel.org/tip/c116c5457c46edb767df6f4e36d4905e3514ad37
Author:     Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
AuthorDate: Thu, 26 Aug 2010 13:58:00 -0400
Committer:  H. Peter Anvin <hpa@linux.intel.com>
CommitDate: Thu, 26 Aug 2010 15:13:37 -0700

x86, swiotlb: Make SWIOTLB use IOMMU_INIT_* macros.

We utilize the IOMMU_INIT macros to create this dependency:

       [pci_xen_swiotlb_detect]
                 |
       [pci_swiotlb_detect_override]
                 |
       [pci_swiotlb_detect_4gb]

And set the SWIOTLB IOMMU_INIT to utilize 'pci_swiotlb_init'
for .init and 'pci_swiotlb_late_init' for .late_init.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
LKML-Reference: <1282845485-8991-6-git-send-email-konrad.wilk@oracle.com>
CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
---
 arch/x86/kernel/pci-swiotlb.c |   11 ++++++++++-
 1 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
index c7a72fa..8f972cb 100644
--- a/arch/x86/kernel/pci-swiotlb.c
+++ b/arch/x86/kernel/pci-swiotlb.c
@@ -10,7 +10,8 @@
 #include <asm/iommu.h>
 #include <asm/swiotlb.h>
 #include <asm/dma.h>
-
+#include <asm/xen/swiotlb-xen.h>
+#include <asm/iommu_table.h>
 int swiotlb __read_mostly;
 
 static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
@@ -55,6 +56,10 @@ int __init pci_swiotlb_detect_override(void)
 
 	return use_swiotlb;
 }
+IOMMU_INIT_FINISH(pci_swiotlb_detect_override,
+		  pci_xen_swiotlb_detect,
+		  pci_swiotlb_init,
+		  pci_swiotlb_late_init);
 
 /*
  * if 4GB or more detected (and iommu=off not set) return 1
@@ -69,6 +74,10 @@ int __init pci_swiotlb_detect_4gb(void)
 #endif
 	return swiotlb;
 }
+IOMMU_INIT(pci_swiotlb_detect_4gb,
+	   pci_swiotlb_detect_override,
+	   pci_swiotlb_init,
+	   pci_swiotlb_late_init);
 
 void __init pci_swiotlb_init(void)
 {

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [tip:x86/iommu] x86, xen-swiotlb: Make Xen-SWIOTLB use IOMMU_INIT_* macros.
  2010-08-26 17:58 ` [PATCH 06/10] x86/xen-swiotlb: Make Xen-SWIOTLB " Konrad Rzeszutek Wilk
@ 2010-08-26 23:29   ` tip-bot for Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 31+ messages in thread
From: tip-bot for Konrad Rzeszutek Wilk @ 2010-08-26 23:29 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, jeremy, hpa, mingo, konrad.wilk, fujita.tomonori,
	tglx, hpa

Commit-ID:  5cb3a267939a223eb84692d229569d2ef493d7ca
Gitweb:     http://git.kernel.org/tip/5cb3a267939a223eb84692d229569d2ef493d7ca
Author:     Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
AuthorDate: Thu, 26 Aug 2010 13:58:01 -0400
Committer:  H. Peter Anvin <hpa@linux.intel.com>
CommitDate: Thu, 26 Aug 2010 15:14:06 -0700

x86, xen-swiotlb: Make Xen-SWIOTLB 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]

In other words, we set 'pci_xen_swiotlb_detect' to be
the first detection to be run during start.

CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
LKML-Reference: <1282845485-8991-7-git-send-email-konrad.wilk@oracle.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
---
 arch/x86/xen/pci-swiotlb-xen.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c
index a013ec9..2247100 100644
--- a/arch/x86/xen/pci-swiotlb-xen.c
+++ b/arch/x86/xen/pci-swiotlb-xen.c
@@ -5,6 +5,7 @@
 
 #include <asm/xen/hypervisor.h>
 #include <xen/xen.h>
+#include <asm/iommu_table.h>
 
 int xen_swiotlb __read_mostly;
 
@@ -56,3 +57,7 @@ void __init pci_xen_swiotlb_init(void)
 		dma_ops = &xen_swiotlb_dma_ops;
 	}
 }
+IOMMU_INIT_FINISH(pci_xen_swiotlb_detect,
+		  0,
+		  pci_xen_swiotlb_init,
+		  0);

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [tip:x86/iommu] x86, calgary: Make Calgary IOMMU use IOMMU_INIT_* macros.
  2010-08-26 17:58 ` [PATCH 07/10] x86/calgary: Make Calgary IOMMU " Konrad Rzeszutek Wilk
@ 2010-08-26 23:30   ` tip-bot for Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 31+ messages in thread
From: tip-bot for Konrad Rzeszutek Wilk @ 2010-08-26 23:30 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, konrad.wilk, fujita.tomonori, djwong,
	muli, jdmason, tglx, hpa

Commit-ID:  d2aa232f3d0b5a3e22f91b736fe68eddcf0d5ea3
Gitweb:     http://git.kernel.org/tip/d2aa232f3d0b5a3e22f91b736fe68eddcf0d5ea3
Author:     Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
AuthorDate: Thu, 26 Aug 2010 13:58:02 -0400
Committer:  H. Peter Anvin <hpa@linux.intel.com>
CommitDate: Thu, 26 Aug 2010 15:14:15 -0700

x86, calgary: Make Calgary IOMMU use IOMMU_INIT_* macros.

We utilize the IOMMU_INIT macros to create this dependency:

     [pci_xen_swiotlb_detect]
         |
     [pci_swiotlb_detect_override]
         |
     [pci_swiotlb_detect_4gb]
         |
      [detect_calgary]

Meaning that 'detect_calgary' is going to be called after
'pci_swiotlb_detect'.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
LKML-Reference: <1282845485-8991-8-git-send-email-konrad.wilk@oracle.com>
CC: Muli Ben-Yehuda <muli@il.ibm.com>
CC: "Jon D. Mason" <jdmason@kudzu.us>
CC: "Darrick J. Wong" <djwong@us.ibm.com>
CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
---
 arch/x86/kernel/pci-calgary_64.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 28c6b38..f56a117 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -47,6 +47,7 @@
 #include <asm/rio.h>
 #include <asm/bios_ebda.h>
 #include <asm/x86_init.h>
+#include <asm/iommu_table.h>
 
 #ifdef CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT
 int use_calgary __read_mostly = 1;
@@ -1595,3 +1596,5 @@ static int __init calgary_fixup_tce_spaces(void)
  * and before device_initcall.
  */
 rootfs_initcall(calgary_fixup_tce_spaces);
+
+IOMMU_INIT_POST(detect_calgary);

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [tip:x86/iommu] x86, GART/AMD-VI: Make AMD GART and IOMMU use IOMMU_INIT_* macros.
  2010-08-26 17:58 ` [PATCH 08/10] x86/GART/AMD-VI: Make AMD GART and " Konrad Rzeszutek Wilk
@ 2010-08-26 23:30   ` tip-bot for Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 31+ messages in thread
From: tip-bot for Konrad Rzeszutek Wilk @ 2010-08-26 23:30 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, konrad.wilk, joerg.roedel,
	fujita.tomonori, tglx, hpa

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=", 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 bytes */
@@ -896,3 +897,4 @@ void __init gart_parse_options(char *p)
 		}
 	}
 }
+IOMMU_INIT_POST(gart_iommu_hole_init);

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [tip:x86/iommu] x86, VT-d: Make Intel VT-d IOMMU use IOMMU_INIT_* macros.
  2010-08-26 17:58 ` [PATCH 09/10] x86/VT-d: Make Intel VT-d " Konrad Rzeszutek Wilk
@ 2010-08-26 23:30   ` tip-bot for Konrad Rzeszutek Wilk
  2010-09-07 18:10   ` [PATCH 09/10] x86/VT-d: " Tony Luck
  1 sibling, 0 replies; 31+ messages in thread
From: tip-bot for Konrad Rzeszutek Wilk @ 2010-08-26 23:30 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, yinghai, konrad.wilk, fujita.tomonori,
	chrisw, jbarnes, tglx, hpa, David.Woodhouse, len.brown

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 dmar->flags & 0x1;
 }
+IOMMU_INIT_POST(detect_intel_iommu);

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [tip:x86/iommu] x86, iommu: Utilize the IOMMU_INIT macros functionality.
  2010-08-26 17:58 ` [PATCH 10/10] x86/iommu: Utilize the IOMMU_INIT macros functionality Konrad Rzeszutek Wilk
@ 2010-08-26 23:31   ` tip-bot for Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 31+ messages in thread
From: tip-bot for Konrad Rzeszutek Wilk @ 2010-08-26 23:31 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, konrad.wilk, fujita.tomonori, tglx, hpa

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[], __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 out;
-
-	pci_swiotlb_detect_4gb();
-
-	gart_iommu_hole_init();
-
-	detect_calgary();
-
-	detect_intel_iommu();
+	sort_iommu_table(__iommu_table, __iommu_table_end);
+	check_iommu_entries(__iommu_table, __iommu_table_end);
 
-	/* needs to be called after gart_iommu_hole_init */
-	amd_iommu_detect();
-out:
-	pci_xen_swiotlb_init();
-
-	pci_swiotlb_init();
+	for (p = __iommu_table; p < __iommu_table_end; p++) {
+		if (p && p->detect && p->detect() > 0) {
+			p->flags |= IOMMU_DETECTED;
+			if (p->early_init)
+				p->early_init();
+			if (p->flags & IOMMU_FINISH_IF_DETECTED)
+				break;
+		}
+	}
 }
-
 void *dma_generic_alloc_coherent(struct device *dev, size_t size,
 				 dma_addr_t *dma_addr, gfp_t flag)
 {
@@ -294,6 +291,7 @@ EXPORT_SYMBOL(dma_supported);
 
 static int __init pci_iommu_init(void)
 {
+	struct iommu_table_entry *p;
 	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
 
 #ifdef CONFIG_PCI
@@ -301,12 +299,10 @@ static int __init pci_iommu_init(void)
 #endif
 	x86_init.iommu.iommu_init();
 
-	if (swiotlb || xen_swiotlb) {
-		printk(KERN_INFO "PCI-DMA: "
-		       "Using software bounce buffering for IO (SWIOTLB)\n");
-		swiotlb_print_info();
-	} else
-		swiotlb_free();
+	for (p = __iommu_table; p < __iommu_table_end; p++) {
+		if (p && (p->flags & IOMMU_DETECTED) && p->late_init)
+			p->late_init();
+	}
 
 	return 0;
 }

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 01/10] x86/iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure.
  2010-08-26 18:19   ` Sam Ravnborg
  2010-08-26 19:48     ` H. Peter Anvin
@ 2010-08-26 23:47     ` H. Peter Anvin
  2010-08-27 14:38     ` Konrad Rzeszutek Wilk
  2 siblings, 0 replies; 31+ messages in thread
From: H. Peter Anvin @ 2010-08-26 23:47 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Konrad Rzeszutek Wilk, fujita.tomonori, linux-kernel, x86,
	Thomas Gleixner, Ingo Molnar

On 08/26/2010 11:19 AM, Sam Ravnborg wrote:
> 
> 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.
> 

I added this series to tip:x86/iommu, but please do provide an
incremental patch with a comment.

Thanks,

	-hpa


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 01/10] x86/iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure.
  2010-08-26 18:19   ` Sam Ravnborg
  2010-08-26 19:48     ` H. Peter Anvin
  2010-08-26 23:47     ` H. Peter Anvin
@ 2010-08-27 14:38     ` Konrad Rzeszutek Wilk
  2010-08-27 14:40       ` Sam Ravnborg
  2 siblings, 1 reply; 31+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-08-27 14:38 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: hpa, fujita.tomonori, linux-kernel, x86, Thomas Gleixner, Ingo Molnar

On Thu, Aug 26, 2010 at 08:19:13PM +0200, Sam Ravnborg wrote:
> > diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
> > index d0bb522..b92e040 100644
> > --- a/arch/x86/kernel/vmlinux.lds.S
> > +++ b/arch/x86/kernel/vmlinux.lds.S
> > @@ -260,6 +260,13 @@ SECTIONS
> >  		*(.altinstr_replacement)
> >  	}
> >  
> > +	.iommu_table : AT(ADDR(.iommu_table) - LOAD_OFFSET) {
> > +		__iommu_table = .;
> > +		*(.iommu_table)
> > +		. = ALIGN(8);
> > +		__iommu_table_end = .;
> > +	}
> > +
> 
> 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.

Sure. Will provide one and also explain the other sections that I am
familiar with.

Thanks for your feedback!

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 01/10] x86/iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure.
  2010-08-27 14:38     ` Konrad Rzeszutek Wilk
@ 2010-08-27 14:40       ` Sam Ravnborg
  2010-08-27 18:19         ` [PATCH] x86: Adding comments about .iommu_table and its neighbors Konrad Rzeszutek Wilk
  0 siblings, 1 reply; 31+ messages in thread
From: Sam Ravnborg @ 2010-08-27 14:40 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk
  Cc: hpa, fujita.tomonori, linux-kernel, x86, Thomas Gleixner, Ingo Molnar

On Fri, Aug 27, 2010 at 10:38:44AM -0400, Konrad Rzeszutek Wilk wrote:
> On Thu, Aug 26, 2010 at 08:19:13PM +0200, Sam Ravnborg wrote:
> > > diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
> > > index d0bb522..b92e040 100644
> > > --- a/arch/x86/kernel/vmlinux.lds.S
> > > +++ b/arch/x86/kernel/vmlinux.lds.S
> > > @@ -260,6 +260,13 @@ SECTIONS
> > >  		*(.altinstr_replacement)
> > >  	}
> > >  
> > > +	.iommu_table : AT(ADDR(.iommu_table) - LOAD_OFFSET) {
> > > +		__iommu_table = .;
> > > +		*(.iommu_table)
> > > +		. = ALIGN(8);
> > > +		__iommu_table_end = .;
> > > +	}
> > > +
> > 
> > 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.
> 
> Sure. Will provide one and also explain the other sections that I am
> familiar with.

Appreciated - thanks!

	Sam

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH] x86: Adding comments about .iommu_table and its neighbors.
  2010-08-27 14:40       ` Sam Ravnborg
@ 2010-08-27 18:19         ` Konrad Rzeszutek Wilk
  2010-08-28  1:54           ` [tip:x86/iommu] x86, doc: " tip-bot for Konrad Rzeszutek Wilk
  0 siblings, 1 reply; 31+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-08-27 18:19 UTC (permalink / raw)
  To: linux-kernel
  Cc: Konrad Rzeszutek Wilk, Sam Ravnborg, H. Peter Anvin,
	Fujita Tomonori, Thomas Gleixner, Ingo Molnar

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 order. After rootfs_initcall is complete
+	 * this section can be safely removed.
+	 */
 	.iommu_table : AT(ADDR(.iommu_table) - LOAD_OFFSET) {
 		__iommu_table = .;
 		*(.iommu_table)
-- 
1.7.0.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [tip:x86/iommu] x86, doc: Adding comments about .iommu_table and its neighbors.
  2010-08-27 18:19         ` [PATCH] x86: Adding comments about .iommu_table and its neighbors Konrad Rzeszutek Wilk
@ 2010-08-28  1:54           ` tip-bot for Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 31+ messages in thread
From: tip-bot for Konrad Rzeszutek Wilk @ 2010-08-28  1:54 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, konrad.wilk, sam, fujita.tomonori, tglx

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 = .;
 	}
 
+	/*
+	 * 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 order. After rootfs_initcall is complete
+	 * this section can be safely removed.
+	 */
 	.iommu_table : AT(ADDR(.iommu_table) - LOAD_OFFSET) {
 		__iommu_table = .;
 		*(.iommu_table)

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 09/10] x86/VT-d: Make Intel VT-d IOMMU use IOMMU_INIT_* macros.
  2010-08-26 17:58 ` [PATCH 09/10] x86/VT-d: Make Intel VT-d " Konrad Rzeszutek Wilk
  2010-08-26 23:30   ` [tip:x86/iommu] x86, VT-d: " tip-bot for Konrad Rzeszutek Wilk
@ 2010-09-07 18:10   ` Tony Luck
  2010-09-07 19:07     ` Konrad Rzeszutek Wilk
  1 sibling, 1 reply; 31+ messages in thread
From: Tony Luck @ 2010-09-07 18:10 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk
  Cc: hpa, fujita.tomonori, linux-kernel, Jesse Barnes,
	David Woodhouse, Len Brown, Chris Wright, Yinghai Lu

On Thu, Aug 26, 2010 at 10:58 AM, Konrad Rzeszutek Wilk
<konrad.wilk@oracle.com> wrote:
> We utilize the IOMMU_INIT macros to create this dependency:
...
>  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>

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

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 09/10] x86/VT-d: Make Intel VT-d IOMMU use IOMMU_INIT_* macros.
  2010-09-07 18:10   ` [PATCH 09/10] x86/VT-d: " Tony Luck
@ 2010-09-07 19:07     ` Konrad Rzeszutek Wilk
  2010-09-07 19:12       ` Luck, Tony
  0 siblings, 1 reply; 31+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-09-07 19:07 UTC (permalink / raw)
  To: Tony Luck
  Cc: hpa, fujita.tomonori, linux-kernel, Jesse Barnes,
	David Woodhouse, Len Brown, Chris Wright, Yinghai Lu

On Tue, Sep 07, 2010 at 11:10:30AM -0700, Tony Luck wrote:
> On Thu, Aug 26, 2010 at 10:58 AM, Konrad Rzeszutek Wilk
> <konrad.wilk@oracle.com> wrote:
> > We utilize the IOMMU_INIT macros to create this dependency:
> ...
> >  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>
> 
> This breaks ia64 - since you didn't make an asm/iommu_table.h for it :-(

Oh no! Well, perhaps moving it to a wider audience is the right thing..
But for right now let me be a bit conservative.
> 
> 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.

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


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* RE: [PATCH 09/10] x86/VT-d: Make Intel VT-d IOMMU use IOMMU_INIT_* macros.
  2010-09-07 19:07     ` Konrad Rzeszutek Wilk
@ 2010-09-07 19:12       ` Luck, Tony
  0 siblings, 0 replies; 31+ messages in thread
From: Luck, Tony @ 2010-09-07 19:12 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk
  Cc: hpa, fujita.tomonori, linux-kernel, Jesse Barnes, Woodhouse,
	David, Brown, Len, Chris Wright, Yinghai Lu

> If you do this patch it should compile fine, let me think a bit about
> how to make the iommu_* pieces platform-agnostic.


Yes. That fixes the compliation problem.

-Tony

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2010-09-07 19:12 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-26 17:57 [RFC PATCH v2] Modularize IOMMUs detection/init for X86 Konrad Rzeszutek Wilk
2010-08-26 17:57 ` [PATCH 01/10] x86/iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure Konrad Rzeszutek Wilk
2010-08-26 18:19   ` Sam Ravnborg
2010-08-26 19:48     ` H. Peter Anvin
2010-08-26 23:47     ` H. Peter Anvin
2010-08-27 14:38     ` Konrad Rzeszutek Wilk
2010-08-27 14:40       ` Sam Ravnborg
2010-08-27 18:19         ` [PATCH] x86: Adding comments about .iommu_table and its neighbors Konrad Rzeszutek Wilk
2010-08-28  1:54           ` [tip:x86/iommu] x86, doc: " tip-bot for Konrad Rzeszutek Wilk
2010-08-26 23:27   ` [tip:x86/iommu] x86, iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure tip-bot for Konrad Rzeszutek Wilk
2010-08-26 17:57 ` [PATCH 02/10] x86/iommu: Make all IOMMU's detection routines return a value Konrad Rzeszutek Wilk
2010-08-26 23:28   ` [tip:x86/iommu] x86, iommu: " tip-bot for Konrad Rzeszutek Wilk
2010-08-26 17:57 ` [PATCH 03/10] x86/iommu: Add proper dependency sort routine (and sanity check) Konrad Rzeszutek Wilk
2010-08-26 23:28   ` [tip:x86/iommu] x86, iommu: " tip-bot for Konrad Rzeszutek Wilk
2010-08-26 17:57 ` [PATCH 04/10] x86/swiotlb: Simplify SWIOTLB pci_swiotlb_detect routine Konrad Rzeszutek Wilk
2010-08-26 23:28   ` [tip:x86/iommu] x86, swiotlb: " tip-bot for Konrad Rzeszutek Wilk
2010-08-26 17:58 ` [PATCH 05/10] x86/swiotlb: Make SWIOTLB use IOMMU_INIT_* macros Konrad Rzeszutek Wilk
2010-08-26 23:29   ` [tip:x86/iommu] x86, swiotlb: " tip-bot for Konrad Rzeszutek Wilk
2010-08-26 17:58 ` [PATCH 06/10] x86/xen-swiotlb: Make Xen-SWIOTLB " Konrad Rzeszutek Wilk
2010-08-26 23:29   ` [tip:x86/iommu] x86, xen-swiotlb: " tip-bot for Konrad Rzeszutek Wilk
2010-08-26 17:58 ` [PATCH 07/10] x86/calgary: Make Calgary IOMMU " Konrad Rzeszutek Wilk
2010-08-26 23:30   ` [tip:x86/iommu] x86, calgary: " tip-bot for Konrad Rzeszutek Wilk
2010-08-26 17:58 ` [PATCH 08/10] x86/GART/AMD-VI: Make AMD GART and " Konrad Rzeszutek Wilk
2010-08-26 23:30   ` [tip:x86/iommu] x86, GART/AMD-VI: " tip-bot for Konrad Rzeszutek Wilk
2010-08-26 17:58 ` [PATCH 09/10] x86/VT-d: Make Intel VT-d " Konrad Rzeszutek Wilk
2010-08-26 23:30   ` [tip:x86/iommu] x86, VT-d: " tip-bot for Konrad Rzeszutek Wilk
2010-09-07 18:10   ` [PATCH 09/10] x86/VT-d: " Tony Luck
2010-09-07 19:07     ` Konrad Rzeszutek Wilk
2010-09-07 19:12       ` Luck, Tony
2010-08-26 17:58 ` [PATCH 10/10] x86/iommu: Utilize the IOMMU_INIT macros functionality Konrad Rzeszutek Wilk
2010-08-26 23:31   ` [tip:x86/iommu] x86, iommu: " tip-bot for Konrad Rzeszutek Wilk

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.