From b5bb71e4224f44ad1059ad95f7e4eb651869684c Mon Sep 17 00:00:00 2001 From: Stephen Tweedie Date: Mon, 10 Dec 2007 11:32:15 +0000 Subject: [PATCH] xen mtrr: Add mtrr_ops support for Xen mtrr 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 --- arch/x86/kernel/cpu/mtrr/Makefile | 1 + arch/x86/kernel/cpu/mtrr/main.c | 30 ++++++++++++++++--- arch/x86/kernel/cpu/mtrr/xen.c | 57 +++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 arch/x86/kernel/cpu/mtrr/xen.c diff --git a/arch/x86/kernel/cpu/mtrr/Makefile b/arch/x86/kernel/cpu/mtrr/Makefile index 191fc05..81db513 100644 --- 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) += xen.o diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index 3b20613..4fa6ecd 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c @@ -572,6 +572,7 @@ EXPORT_SYMBOL(mtrr_del); extern void amd_init_mtrr(void); extern void cyrix_init_mtrr(void); extern void centaur_init_mtrr(void); +extern void xen_init_mtrr(void); static void __init init_ifs(void) { @@ -580,6 +581,9 @@ static void __init init_ifs(void) cyrix_init_mtrr(); centaur_init_mtrr(); #endif +#ifdef CONFIG_XEN + xen_init_mtrr(); +#endif } /* The suspend/resume methods are only for CPU without MTRR. CPU using generic @@ -635,16 +639,14 @@ static struct sysdev_driver mtrr_sysdev_driver = { /** - * mtrr_bp_init - initialize mtrrs on the boot CPU + * mtrr_bp_detect - detect mtrr hardware on the boot CPU * * This needs to be called early; before any of the other CPUs are * initialized (i.e. before smp_init()). * */ -void __init mtrr_bp_init(void) +static void __init mtrr_bp_detect(void) { - init_ifs(); - if (cpu_has_mtrr) { mtrr_if = &generic_mtrr_ops; size_or_mask = 0xff000000; /* 36 bits */ @@ -701,9 +703,27 @@ void __init mtrr_bp_init(void) break; } } +} + +/** + * mtrr_bp_init - initialize mtrrs on the boot CPU + * + * This needs to be called early; before any of the other CPUs are + * initialized (i.e. before smp_init()). + * + */ +void __init mtrr_bp_init(void) +{ + init_ifs(); + + if (!mtrr_if) + mtrr_bp_detect(); if (mtrr_if) { - set_num_var_ranges(); + /* Xen pv_ops will set the mtrr CPU to unknown, but will + * also initialise the num_var_ranges for us */ + if (!is_cpu(UNKNOWN)) + set_num_var_ranges(); init_table(); if (use_intel()) get_mtrr_state(); diff --git a/arch/x86/kernel/cpu/mtrr/xen.c b/arch/x86/kernel/cpu/mtrr/xen.c new file mode 100644 index 0000000..7011195 --- /dev/null +++ b/arch/x86/kernel/cpu/mtrr/xen.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include "mtrr.h" + +#include +#include +#include + +/* 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 +}; + +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 (!is_initial_xendomain()) + 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; + num_var_ranges = xen_num_var_ranges(); +} -- 1.5.3.4