From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A055FC2BB41 for ; Tue, 16 Aug 2022 07:10:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231644AbiHPHKw (ORCPT ); Tue, 16 Aug 2022 03:10:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36342 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231628AbiHPHJr (ORCPT ); Tue, 16 Aug 2022 03:09:47 -0400 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E296F389CB9 for ; Mon, 15 Aug 2022 21:39:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660624798; x=1692160798; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=KR/HBP1wOvQFpjD2YET+iCx+bjZqywBPEsVL8qmACU8=; b=L52aPJT5NusZ0LKiWoqOJC6RdTH/UYHTRhduEdd1PX75NHrUIjiLv9Sy l2JdnnvNkhbv4noSPx+6PZqBuQ0yL0urSSdyWSfT5FZRMVjoA7TeRjqEH XId068B3BOHvPqA+oqaGiYoySNFSLllWmVghtIzkwQAutImwi57/CPA0N XXtOPRdskKIZcP9sZ0hmXWLPJcKDG/HkfFYX/6pKf0xJja7OaLgCt48dY CenATiLcSgCSyPkUaEeVNJVshaB/ZoY31Ga/nRF4oDmAxCW7H3Rs2PXcU rbF8OGY0Zy/ur5bZ7LZpvIhlJwKfucP5rXQiVsrZyiASfCF+rvzpZAeZ4 g==; X-IronPort-AV: E=McAfee;i="6400,9594,10440"; a="293395139" X-IronPort-AV: E=Sophos;i="5.93,240,1654585200"; d="scan'208";a="293395139" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Aug 2022 21:38:19 -0700 X-IronPort-AV: E=Sophos;i="5.93,240,1654585200"; d="scan'208";a="675071596" Received: from araj-dh-work.jf.intel.com ([10.165.157.158]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Aug 2022 21:38:19 -0700 From: Ashok Raj To: Borislav Petkov , Thomas Gleixner Cc: "LKML Mailing List" , Andy Lutomirski , Andrew Cooper , "Ashok Raj" , Dave Hansen , Tony Luck Subject: [PATCH v2 3/4] x86/microcode: Avoid any chance of MCE's during microcode update Date: Tue, 16 Aug 2022 04:37:52 +0000 Message-Id: <20220816043754.3258815-4-ashok.raj@intel.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220816043754.3258815-1-ashok.raj@intel.com> References: <20220816043754.3258815-1-ashok.raj@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When a microcode update is in progress, several instructions and MSR's can be patched by the update. During the update in progress, touching any of the resources being patched could result in unpredictable results. If thread0 is doing the update and thread1 happens to get a MCE, the handler might read an MSR that's being patched. In order to have predictable behavior, to avoid this scenario we set the MCIP in all threads. Since MCE's can't be nested, HW will automatically promote to shutdown condition. After the update is completed, MCIP flag is cleared. The system is going to shutdown anyway, since the MCE could be a fatal error, or even recoverable errors in kernel space are treated as unrecoverable. Signed-off-by: Ashok Raj --- arch/x86/include/asm/mce.h | 4 ++++ arch/x86/kernel/cpu/mce/core.c | 9 +++++++++ arch/x86/kernel/cpu/microcode/core.c | 11 +++++++++++ 3 files changed, 24 insertions(+) diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index cc73061e7255..2aef6120e23f 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -207,12 +207,16 @@ void mcheck_cpu_init(struct cpuinfo_x86 *c); void mcheck_cpu_clear(struct cpuinfo_x86 *c); int apei_smca_report_x86_error(struct cper_ia_proc_ctx *ctx_info, u64 lapic_id); +extern void mce_set_mcip(void); +extern void mce_clear_mcip(void); #else static inline int mcheck_init(void) { return 0; } static inline void mcheck_cpu_init(struct cpuinfo_x86 *c) {} static inline void mcheck_cpu_clear(struct cpuinfo_x86 *c) {} static inline int apei_smca_report_x86_error(struct cper_ia_proc_ctx *ctx_info, u64 lapic_id) { return -EINVAL; } +static inline void mce_set_mcip(void) {} +static inline void mce_clear_mcip(void) {} #endif void mce_setup(struct mce *m); diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c index 2c8ec5c71712..72b49d95bb3b 100644 --- a/arch/x86/kernel/cpu/mce/core.c +++ b/arch/x86/kernel/cpu/mce/core.c @@ -402,6 +402,15 @@ static noinstr void mce_wrmsrl(u32 msr, u64 v) : : "c" (msr), "a"(low), "d" (high) : "memory"); } +void mce_set_mcip(void) +{ + mce_wrmsrl(MSR_IA32_MCG_STATUS, 0x1); +} + +void mce_clear_mcip(void) +{ + mce_wrmsrl(MSR_IA32_MCG_STATUS, 0x0); +} /* * Collect all global (w.r.t. this processor) status about this machine * check into our "mce" struct so that we can use it later to assess diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index ad57e0e4d674..d24e1c754c27 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -39,6 +39,7 @@ #include #include #include +#include #define DRIVER_VERSION "2.2" @@ -450,6 +451,14 @@ static int __reload_late(void *info) if (__wait_for_cpus(&late_cpus_in, NSEC_PER_SEC)) return -1; + /* + * Its dangerous to let MCE while microcode update is in progress. + * Its extremely rare and even if happens they are fatal errors. + * But reading patched areas before the update is complete can be + * leading to unpredictable results. Setting MCIP will guarantee + * the platform is taken to reset predictively. + */ + mce_set_mcip(); /* * On an SMT system, it suffices to load the microcode on one sibling of * the core because the microcode engine is shared between the threads. @@ -457,6 +466,7 @@ static int __reload_late(void *info) * loading attempts happen on multiple threads of an SMT core. See * below. */ + if (cpumask_first(topology_sibling_cpumask(cpu)) == cpu) apply_microcode_local(&err); else @@ -473,6 +483,7 @@ static int __reload_late(void *info) if (__wait_for_cpus(&late_cpus_out, NSEC_PER_SEC)) panic("Timeout during microcode update!\n"); + mce_clear_mcip(); /* * At least one thread has completed update on each core. * For others, simply call the update to make sure the -- 2.32.0