From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752175AbbJLJYr (ORCPT ); Mon, 12 Oct 2015 05:24:47 -0400 Received: from mail.skyhub.de ([78.46.96.112]:46018 "EHLO mail.skyhub.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751850AbbJLJW5 (ORCPT ); Mon, 12 Oct 2015 05:22:57 -0400 From: Borislav Petkov To: Ingo Molnar Cc: LKML Subject: [PATCH 1/6] x86/mce: Don't clear shared banks on Intel when offlining CPUs Date: Mon, 12 Oct 2015 11:22:37 +0200 Message-Id: <1444641762-9437-2-git-send-email-bp@alien8.de> X-Mailer: git-send-email 2.3.5 In-Reply-To: <1444641762-9437-1-git-send-email-bp@alien8.de> References: <1444641762-9437-1-git-send-email-bp@alien8.de> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ashok Raj It is not safe to clear global MCi_CTL banks during CPU offline or suspend/resume operations. These MSRs are either thread-scoped (meaning private to a thread), or core-scoped (private to threads in that core only), or with a socket scope: visible and controllable from all threads in the socket. When we offline a single CPU, clearing those MCi_CTL bits will stop signaling for all the shared, i.e., socket-wide resources, such as LLC, iMC, etc. In addition, it might be possible to compromise the integrity of an Intel Secure Guard eXtentions (SGX) system if the attacker has control of the host system and is able to inject errors which would be otherwise ignored when MCi_CTL bits are cleared. Hence on SGX enabled systems, if MCi_CTL is cleared, SGX gets disabled. Reviewed-by: Tony Luck Tested-by: Serge Ayoun Signed-off-by: Ashok Raj Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Serge Ayoun Cc: Thomas Gleixner Cc: Tony Luck Cc: linux-edac Cc: x86-ml Link: http://lkml.kernel.org/r/1441391390-16985-1-git-send-email-ashok.raj@intel.com [ Cleanup text. ] Signed-off-by: Borislav Petkov --- arch/x86/kernel/cpu/mcheck/mce.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 9d014b82a124..17b5ec6edcb6 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -2042,7 +2042,7 @@ int __init mcheck_init(void) * Disable machine checks on suspend and shutdown. We can't really handle * them later. */ -static int mce_disable_error_reporting(void) +static void mce_disable_error_reporting(void) { int i; @@ -2052,17 +2052,32 @@ static int mce_disable_error_reporting(void) if (b->init) wrmsrl(MSR_IA32_MCx_CTL(i), 0); } - return 0; + return; +} + +static void vendor_disable_error_reporting(void) +{ + /* + * Don't clear on Intel CPUs. Some of these MSRs are socket-wide. + * Disabling them for just a single offlined CPU is bad, since it will + * inhibit reporting for all shared resources on the socket like the + * last level cache (LLC), the integrated memory controller (iMC), etc. + */ + if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) + return; + + mce_disable_error_reporting(); } static int mce_syscore_suspend(void) { - return mce_disable_error_reporting(); + vendor_disable_error_reporting(); + return 0; } static void mce_syscore_shutdown(void) { - mce_disable_error_reporting(); + vendor_disable_error_reporting(); } /* @@ -2342,19 +2357,14 @@ static void mce_device_remove(unsigned int cpu) static void mce_disable_cpu(void *h) { unsigned long action = *(unsigned long *)h; - int i; if (!mce_available(raw_cpu_ptr(&cpu_info))) return; if (!(action & CPU_TASKS_FROZEN)) cmci_clear(); - for (i = 0; i < mca_cfg.banks; i++) { - struct mce_bank *b = &mce_banks[i]; - if (b->init) - wrmsrl(MSR_IA32_MCx_CTL(i), 0); - } + vendor_disable_error_reporting(); } static void mce_reenable_cpu(void *h) -- 2.3.5