[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 25 of 38] xen mtrr: Add mtrr_ops support for Xen mtrr



From: Stephen Tweedie <sct@xxxxxxxxxx>

Add a Xen mtrr type, and reorganise mtrr initialisation slightly to allow the
mtrr driver to set up num_var_ranges (Xen needs to do this by querying the
hypervisor itself.)

Only the boot path is handled for now: we set up a xen-specific mtrr_if
and set up the mtrr tables based on hypervisor information, but we don't
yet handle mtrr entry add/delete.

Signed-off-by: Stephen Tweedie <sct@xxxxxxxxxx>
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@xxxxxxxxxx>
---
 arch/x86/kernel/cpu/mtrr/Makefile  |    1
 arch/x86/kernel/cpu/mtrr/amd.c     |    1
 arch/x86/kernel/cpu/mtrr/centaur.c |    1
 arch/x86/kernel/cpu/mtrr/cyrix.c   |    1
 arch/x86/kernel/cpu/mtrr/generic.c |    1
 arch/x86/kernel/cpu/mtrr/main.c    |   11 ++++--
 arch/x86/kernel/cpu/mtrr/mtrr.h    |    5 +++
 arch/x86/kernel/cpu/mtrr/xen.c     |   59 ++++++++++++++++++++++++++++++++++++
 8 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/cpu/mtrr/Makefile 
b/arch/x86/kernel/cpu/mtrr/Makefile
--- a/arch/x86/kernel/cpu/mtrr/Makefile
+++ b/arch/x86/kernel/cpu/mtrr/Makefile
@@ -1,3 +1,4 @@
 obj-y          := main.o if.o generic.o state.o
 obj-$(CONFIG_X86_32) += amd.o cyrix.o centaur.o
+obj-$(CONFIG_XEN_DOM0) += xen.o
 
diff --git a/arch/x86/kernel/cpu/mtrr/amd.c b/arch/x86/kernel/cpu/mtrr/amd.c
--- a/arch/x86/kernel/cpu/mtrr/amd.c
+++ b/arch/x86/kernel/cpu/mtrr/amd.c
@@ -108,6 +108,7 @@
        .get_free_region   = generic_get_free_region,
        .validate_add_page = amd_validate_add_page,
        .have_wrcomb       = positive_have_wrcomb,
+       .num_var_ranges    = common_num_var_ranges,
 };
 
 int __init amd_init_mtrr(void)
diff --git a/arch/x86/kernel/cpu/mtrr/centaur.c 
b/arch/x86/kernel/cpu/mtrr/centaur.c
--- a/arch/x86/kernel/cpu/mtrr/centaur.c
+++ b/arch/x86/kernel/cpu/mtrr/centaur.c
@@ -213,6 +213,7 @@
        .get_free_region   = centaur_get_free_region,
        .validate_add_page = centaur_validate_add_page,
        .have_wrcomb       = positive_have_wrcomb,
+       .num_var_ranges    = common_num_var_ranges,
 };
 
 int __init centaur_init_mtrr(void)
diff --git a/arch/x86/kernel/cpu/mtrr/cyrix.c b/arch/x86/kernel/cpu/mtrr/cyrix.c
--- a/arch/x86/kernel/cpu/mtrr/cyrix.c
+++ b/arch/x86/kernel/cpu/mtrr/cyrix.c
@@ -263,6 +263,7 @@
        .get_free_region   = cyrix_get_free_region,
        .validate_add_page = generic_validate_add_page,
        .have_wrcomb       = positive_have_wrcomb,
+       .num_var_ranges    = common_num_var_ranges,
 };
 
 int __init cyrix_init_mtrr(void)
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c 
b/arch/x86/kernel/cpu/mtrr/generic.c
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -667,4 +667,5 @@
        .set               = generic_set_mtrr,
        .validate_add_page = generic_validate_add_page,
        .have_wrcomb       = generic_have_wrcomb,
+       .num_var_ranges    = common_num_var_ranges,
 };
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -99,7 +99,7 @@
 }
 
 /*  This function returns the number of variable MTRRs  */
-static void __init set_num_var_ranges(void)
+int __init common_num_var_ranges(void)
 {
        unsigned long config = 0, dummy;
 
@@ -109,7 +109,7 @@
                config = 2;
        else if (is_cpu(CYRIX) || is_cpu(CENTAUR))
                config = 8;
-       num_var_ranges = config & 0xff;
+       return config & 0xff;
 }
 
 static void __init init_table(void)
@@ -1676,12 +1676,17 @@
 void __init mtrr_bp_init(void)
 {
        u32 phys_addr;
+
        init_ifs();
 
        phys_addr = 32;
 
        if (cpu_has_mtrr) {
                mtrr_if = &generic_mtrr_ops;
+#ifdef CONFIG_XEN_DOM0
+               xen_init_mtrr();
+#endif
+
                size_or_mask = 0xff000000;      /* 36 bits */
                size_and_mask = 0x00f00000;
                phys_addr = 36;
@@ -1739,7 +1744,7 @@
        }
 
        if (mtrr_if) {
-               set_num_var_ranges();
+               num_var_ranges = mtrr_if->num_var_ranges();
                init_table();
                if (use_intel()) {
                        get_mtrr_state();
diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtrr.h
--- a/arch/x86/kernel/cpu/mtrr/mtrr.h
+++ b/arch/x86/kernel/cpu/mtrr/mtrr.h
@@ -50,6 +50,8 @@
        int     (*validate_add_page)(unsigned long base, unsigned long size,
                                     unsigned int type);
        int     (*have_wrcomb)(void);
+
+       int     (*num_var_ranges)(void);
 };
 
 extern int generic_get_free_region(unsigned long base, unsigned long size,
@@ -61,6 +63,8 @@
 
 extern int positive_have_wrcomb(void);
 
+extern int __init common_num_var_ranges(void);
+
 /* library functions for processor-specific routines */
 struct set_mtrr_context {
        unsigned long flags;
@@ -104,3 +108,4 @@
 int amd_init_mtrr(void);
 int cyrix_init_mtrr(void);
 int centaur_init_mtrr(void);
+void xen_init_mtrr(void);
diff --git a/arch/x86/kernel/cpu/mtrr/xen.c b/arch/x86/kernel/cpu/mtrr/xen.c
new file mode 100644
--- /dev/null
+++ b/arch/x86/kernel/cpu/mtrr/xen.c
@@ -0,0 +1,59 @@
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <asm/uaccess.h>
+#include <linux/mutex.h>
+
+#include <asm/mtrr.h>
+#include "mtrr.h"
+
+#include <xen/interface/platform.h>
+#include <asm/xen/hypervisor.h>
+#include <asm/xen/hypercall.h>
+
+static int __init xen_num_var_ranges(void);
+
+/* DOM0 TODO: Need to fill in the remaining mtrr methods to have full
+ * working userland mtrr support. */
+static struct mtrr_ops xen_mtrr_ops = {
+       .vendor            = X86_VENDOR_UNKNOWN,
+//     .set               = xen_set_mtrr,
+//     .get               = xen_get_mtrr,
+       .get_free_region   = generic_get_free_region,
+//     .validate_add_page = xen_validate_add_page,
+       .have_wrcomb       = positive_have_wrcomb,
+       .use_intel_if      = 0,
+       .num_var_ranges    = xen_num_var_ranges,
+};
+
+static int __init xen_num_var_ranges(void)
+{
+       int ranges;
+       struct xen_platform_op op;
+
+       for (ranges = 0; ; ranges++) {
+               op.cmd = XENPF_read_memtype;
+               op.u.read_memtype.reg = ranges;
+               if (HYPERVISOR_dom0_op(&op) != 0)
+                       break;
+       }
+       return ranges;
+}
+
+void __init xen_init_mtrr(void)
+{
+       struct cpuinfo_x86 *c = &boot_cpu_data;
+
+       if (!xen_initial_domain())
+               return;
+
+       if ((!cpu_has(c, X86_FEATURE_MTRR)) &&
+           (!cpu_has(c, X86_FEATURE_K6_MTRR)) &&
+           (!cpu_has(c, X86_FEATURE_CYRIX_ARR)) &&
+           (!cpu_has(c, X86_FEATURE_CENTAUR_MCR)))
+               return;
+
+       mtrr_if = &xen_mtrr_ops;
+}



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.