lkml.org 
[lkml]   [2008]   [Nov]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH 25 of 38] xen mtrr: Add mtrr_ops support for Xen mtrr
    Date
    From
    From: Stephen Tweedie <sct@redhat.com>

    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@redhat.com>
    Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
    ---
    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;
    +}



    \
     
     \ /
      Last update: 2008-11-13 20:49    [W:3.538 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site