From patchwork Fri Mar 20 23:17:52 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Luis R. Rodriguez" X-Patchwork-Id: 6061521 Return-Path: X-Original-To: patchwork-linux-fbdev@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 215BABF90F for ; Fri, 20 Mar 2015 23:25:30 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5F083204B0 for ; Fri, 20 Mar 2015 23:25:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E1B9520519 for ; Fri, 20 Mar 2015 23:25:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751612AbbCTXZV (ORCPT ); Fri, 20 Mar 2015 19:25:21 -0400 Received: from mail-pa0-f54.google.com ([209.85.220.54]:36088 "EHLO mail-pa0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751164AbbCTXZU (ORCPT ); Fri, 20 Mar 2015 19:25:20 -0400 Received: by padcy3 with SMTP id cy3so122859750pad.3; Fri, 20 Mar 2015 16:25:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=/uWIpXF1qjg4O2nRlpwPdKQyISJc4RToDepdyQbIxdE=; b=yj5dJvXnyfA9XDSIhZaX9fjAm142KDlWI8suBuDJ/s9YrOxi8WMITxIiL7BH72h+F3 exbf6uXz3gfITm4zMminFtrhOXyGGWNQuz/ZN/KMCqV4/b7+WaDtx9nWNSFhjzamtXOL 6L09NhezHT1J7hOtbOqBO2S7da2osJoEkZG3je37VHPRTwB3Ws4+W/gfVRHJuBlL/h4d 7ZnxC8/IGEpVKQwcpaDi36s6Yc3m+n+sx2bdZm2TVKF6HSP0VXDAd2thLUTeN7ci3gjW azd/Q/jvJ7zkmvZOU8HXvy2J52EVyEOQjwqZba4Hwy637CnqYZspl088YVS8wkcCaiGN UPLA== X-Received: by 10.68.76.98 with SMTP id j2mr616332pbw.75.1426893919633; Fri, 20 Mar 2015 16:25:19 -0700 (PDT) Received: from mcgrof@gmail.com (c-98-234-145-61.hsd1.ca.comcast.net. [98.234.145.61]) by mx.google.com with ESMTPSA id qh6sm9810385pab.34.2015.03.20.16.25.15 (version=TLSv1 cipher=RC4-SHA bits=128/128); Fri, 20 Mar 2015 16:25:18 -0700 (PDT) Received: by mcgrof@gmail.com (sSMTP sendmail emulation); Fri, 20 Mar 2015 16:23:07 -0700 From: "Luis R. Rodriguez" To: luto@amacapital.net, mingo@redhat.com, tglx@linutronix.de, hpa@zytor.com, jgross@suse.com, JBeulich@suse.com, bp@suse.de, suresh.b.siddha@intel.com, venkatesh.pallipadi@intel.com, airlied@redhat.com Cc: linux-kernel@vger.kernel.org, linux-fbdev@vger.kernel.org, x86@kernel.org, xen-devel@lists.xenproject.org, "Luis R. Rodriguez" , Ingo Molnar , Daniel Vetter , Antonino Daplas , Jean-Christophe Plagniol-Villard , Tomi Valkeinen , Dave Hansen , Stefan Bader , konrad.wilk@oracle.com, ville.syrjala@linux.intel.com, david.vrabel@citrix.com, jbeulich@suse.com, toshi.kani@hp.com, bhelgaas@google.com, =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , xen-devel@lists.xensource.com Subject: [PATCH v1 02/47] x86: mtrr: generalize run time disabling of MTRR Date: Fri, 20 Mar 2015 16:17:52 -0700 Message-Id: <1426893517-2511-3-git-send-email-mcgrof@do-not-panic.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1426893517-2511-1-git-send-email-mcgrof@do-not-panic.com> References: <1426893517-2511-1-git-send-email-mcgrof@do-not-panic.com> MIME-Version: 1.0 Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: "Luis R. Rodriguez" It is possible to enable CONFIG_MTRR and up with it disabled at run time and yet CONFIG_X86_PAT continues to kick through fully functionally. This can happen for instance on Xen where MTRR is not supported but PAT is, this can happen now on Linux as of commit 47591df50 by Juergen introduced as of v3.19. Technically we should assume the proper CPU bits would be set to disable MTRR but we can't always rely on this. At least on the Xen Hypervisor for instance only X86_FEATURE_MTRR was disabled as of Xen 4.4 through Xen commit 586ab6a [0], but not X86_FEATURE_K6_MTRR, X86_FEATURE_CENTAUR_MCR, or X86_FEATURE_CYRIX_ARR for instance. x86 mtrr code relies on quite a bit of checks for mtrr_if being set to check to see if MTRR did get set up, instead of using that lets provide a generic setter which when set we know MTRR is enabled. This also adds a few checks where they were not before which could potentially safeguard ourselves against incorrect usage of MTRR where this was not desirable. Where possible match error codes as if MTRR was disabled on arch/x86/include/asm/mtrr.h. Lastly, since disabling MTRR can happen at run time and we could end up with PAT enabled best record now on our logs when MTRR is disabled. [0] ~/devel/xen (git::stable-4.5)$ git describe --contains 586ab6a 4.4.0-rc1~18 Cc: Andy Lutomirski Cc: Suresh Siddha Cc: Venkatesh Pallipadi Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Juergen Gross Cc: Daniel Vetter Cc: Dave Airlie Cc: Antonino Daplas Cc: Jean-Christophe Plagniol-Villard Cc: Tomi Valkeinen Cc: Dave Hansen Cc: venkatesh.pallipadi@intel.com Cc: Stefan Bader Cc: konrad.wilk@oracle.com Cc: ville.syrjala@linux.intel.com Cc: david.vrabel@citrix.com Cc: jbeulich@suse.com Cc: toshi.kani@hp.com Cc: bhelgaas@google.com Cc: Roger Pau Monné Cc: linux-fbdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: xen-devel@lists.xensource.com Signed-off-by: Luis R. Rodriguez --- arch/x86/include/asm/mtrr.h | 2 ++ arch/x86/kernel/cpu/mtrr/cleanup.c | 2 +- arch/x86/kernel/cpu/mtrr/generic.c | 5 +++-- arch/x86/kernel/cpu/mtrr/if.c | 3 +++ arch/x86/kernel/cpu/mtrr/main.c | 31 ++++++++++++++++++++++--------- 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h index f768f62..cade917 100644 --- a/arch/x86/include/asm/mtrr.h +++ b/arch/x86/include/asm/mtrr.h @@ -31,6 +31,7 @@ * arch_phys_wc_add and arch_phys_wc_del. */ # ifdef CONFIG_MTRR +extern int mtrr_enabled; extern u8 mtrr_type_lookup(u64 addr, u64 end); extern void mtrr_save_fixed_ranges(void *); extern void mtrr_save_state(void); @@ -50,6 +51,7 @@ extern int mtrr_trim_uncached_memory(unsigned long end_pfn); extern int amd_special_default_mtrr(void); extern int phys_wc_to_mtrr_index(int handle); # else +static const int mtrr_enabled; static inline u8 mtrr_type_lookup(u64 addr, u64 end) { /* diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c index 5f90b85..784dc55 100644 --- a/arch/x86/kernel/cpu/mtrr/cleanup.c +++ b/arch/x86/kernel/cpu/mtrr/cleanup.c @@ -880,7 +880,7 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn) * Make sure we only trim uncachable memory on machines that * support the Intel MTRR architecture: */ - if (!is_cpu(INTEL) || disable_mtrr_trim) + if (!is_cpu(INTEL) || disable_mtrr_trim || !mtrr_enabled) return 0; rdmsr(MSR_MTRRdefType, def, dummy); diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 09c82de..df321b2 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -116,7 +116,8 @@ static u8 __mtrr_type_lookup(u64 start, u64 end, u64 *partial_end, int *repeat) u8 prev_match, curr_match; *repeat = 0; - if (!mtrr_state_set) + /* generic_mtrr_ops is only set for generic_mtrr_ops */ + if (!mtrr_state_set || !mtrr_enabled) return 0xFF; if (!mtrr_state.enabled) @@ -290,7 +291,7 @@ static void get_fixed_ranges(mtrr_type *frs) void mtrr_save_fixed_ranges(void *info) { - if (cpu_has_mtrr) + if (mtrr_enabled && cpu_has_mtrr) get_fixed_ranges(mtrr_state.fixed_ranges); } diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c index d76f13d..e9e001a 100644 --- a/arch/x86/kernel/cpu/mtrr/if.c +++ b/arch/x86/kernel/cpu/mtrr/if.c @@ -436,6 +436,9 @@ static int __init mtrr_if_init(void) { struct cpuinfo_x86 *c = &boot_cpu_data; + if (!mtrr_enabled) + return 0; + if ((!cpu_has(c, X86_FEATURE_MTRR)) && (!cpu_has(c, X86_FEATURE_K6_MTRR)) && (!cpu_has(c, X86_FEATURE_CYRIX_ARR)) && diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index ea5f363..7db9c47 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c @@ -59,6 +59,7 @@ #define MTRR_TO_PHYS_WC_OFFSET 1000 u32 num_var_ranges; +int mtrr_enabled; unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES]; static DEFINE_MUTEX(mtrr_mutex); @@ -84,6 +85,9 @@ static int have_wrcomb(void) { struct pci_dev *dev; + if (!mtrr_enabled) + return 0; + dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL); if (dev != NULL) { /* @@ -286,7 +290,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, int i, replace, error; mtrr_type ltype; - if (!mtrr_if) + if (!mtrr_enabled) return -ENXIO; error = mtrr_if->validate_add_page(base, size, type); @@ -388,6 +392,8 @@ int mtrr_add_page(unsigned long base, unsigned long size, static int mtrr_check(unsigned long base, unsigned long size) { + if (!mtrr_enabled) + return -ENODEV; if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) { pr_warning("mtrr: size and base must be multiples of 4 kiB\n"); pr_debug("mtrr: size: 0x%lx base: 0x%lx\n", size, base); @@ -463,8 +469,8 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) unsigned long lbase, lsize; int error = -EINVAL; - if (!mtrr_if) - return -ENXIO; + if (!mtrr_enabled) + return -ENODEV; max = num_var_ranges; /* No CPU hotplug when we change MTRR entries */ @@ -523,6 +529,8 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) */ int mtrr_del(int reg, unsigned long base, unsigned long size) { + if (!mtrr_enabled) + return -ENODEV; if (mtrr_check(base, size)) return -EINVAL; return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT); @@ -545,7 +553,7 @@ int arch_phys_wc_add(unsigned long base, unsigned long size) { int ret; - if (pat_enabled) + if (pat_enabled || !mtrr_enabled) return 0; /* Success! (We don't need to do anything.) */ ret = mtrr_add(base, size, MTRR_TYPE_WRCOMB, true); @@ -734,6 +742,7 @@ void __init mtrr_bp_init(void) } if (mtrr_if) { + mtrr_enabled = true; set_num_var_ranges(); init_table(); if (use_intel()) { @@ -744,12 +753,13 @@ void __init mtrr_bp_init(void) mtrr_if->set_all(); } } - } + } else + pr_info("mtrr: system does not support MTRR\n"); } void mtrr_ap_init(void) { - if (!use_intel() || mtrr_aps_delayed_init) + if (!use_intel() || mtrr_aps_delayed_init || !mtrr_enabled) return; /* * Ideally we should hold mtrr_mutex here to avoid mtrr entries @@ -774,6 +784,9 @@ void mtrr_save_state(void) { int first_cpu; + if (!mtrr_enabled) + return; + get_online_cpus(); first_cpu = cpumask_first(cpu_online_mask); smp_call_function_single(first_cpu, mtrr_save_fixed_ranges, NULL, 1); @@ -782,7 +795,7 @@ void mtrr_save_state(void) void set_mtrr_aps_delayed_init(void) { - if (!use_intel()) + if (!use_intel() || !mtrr_enabled) return; mtrr_aps_delayed_init = true; @@ -810,7 +823,7 @@ void mtrr_aps_init(void) void mtrr_bp_restore(void) { - if (!use_intel()) + if (!use_intel() || !mtrr_enabled) return; mtrr_if->set_all(); @@ -818,7 +831,7 @@ void mtrr_bp_restore(void) static int __init mtrr_init_finialize(void) { - if (!mtrr_if) + if (!mtrr_enabled) return 0; if (use_intel()) {