Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757368AbYKMTpq (ORCPT ); Thu, 13 Nov 2008 14:45:46 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754570AbYKMTeh (ORCPT ); Thu, 13 Nov 2008 14:34:37 -0500 Received: from gw.goop.org ([64.81.55.164]:34425 "EHLO mail.goop.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753960AbYKMTeO (ORCPT ); Thu, 13 Nov 2008 14:34:14 -0500 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [PATCH 25 of 38] xen mtrr: Add mtrr_ops support for Xen mtrr X-Mercurial-Node: 61b4b844fb80206fbda124e44795bcb371598bb4 Message-Id: <61b4b844fb80206fbda1.1226603423@abulafia.goop.org> In-Reply-To: Date: Thu, 13 Nov 2008 11:10:23 -0800 From: Jeremy Fitzhardinge To: Ingo Molnar Cc: linux-kernel@vger.kernel.org, Xen-devel , the arch/x86 maintainers , Ian Campbell Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6557 Lines: 218 From: Stephen Tweedie 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 Signed-off-by: Jeremy Fitzhardinge --- 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 +#include +#include +#include +#include +#include +#include + +#include +#include "mtrr.h" + +#include +#include +#include + +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; +} -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/