From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 334F0332916 for ; Thu, 18 Jun 2026 22:45:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781822744; cv=none; b=nvPYWZRQBbUG0VDWjT4zpAMbzmiAPkumWlZbn+LKD4XcjPpC213dQm9YkyaSp6/18cTjDdQ7LrJES1p7ZWfSuozE3NvbC5TZxfFiOqN+lfyg7LOBIFg4hbPzv5wuWGRRTpQqcJ4zrhuqMssuSvCvanTR6nmwJ9mrerNnlxryAT0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781822744; c=relaxed/simple; bh=BjA7c9I6piwWq9wtAxtFoFdK4hfiQGXOkTBLMpji+sc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=b7H0ot1NakEeEcNi24q2WDZdqRR1n15V0PlTEU48xgtrO6VeVUiJju9vs9+DAr6PXx4j8BoQaqaf+57KgZMQutIa88g4jrRWeg+xpNOOR/eBMgdALBmNTPHjwRuon8Ik2qzxIESEtuZ8h5iqrR6wyhFUzc2Has/+e6yNDMeIuLw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=MAyhSVNI; arc=none smtp.client-ip=209.85.215.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="MAyhSVNI" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-c891ed872ddso1011122a12.2 for ; Thu, 18 Jun 2026 15:45:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1781822742; x=1782427542; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=orCsuuUrSE13rotpUYJYYTAbwaY/W6h9VEYHAL58Cls=; b=MAyhSVNIVFasSOYdc+3F/UekXk73T2EwPDcCk94nDn1qATtajJ/RcsDpD9Tm1WlaD4 yt2U+eYZ5a9jQx3qANAFVDCS5Aj7LzVRqkLuk/Xqh3caF6fqgXCoWdJVYfg5upSCBqS1 M7ghMh3WcQTqKYvdMAqRExgd7Tb2wCEKuNsubvNaGzOSxDl+lpAqRWj0j0vtQBOkgO8T 2g+WxmngdDncHTJsjNAgrpXD9QXRwR1JQIkGhUEPkA+rLFwfRX2zLEXKpN+Y7u10UkZq R3ln3GLTKNsH4aYIcZ1yhxRYRGxD8ZBrhHYaPAfkp4jASysxJk3LM3OB9Em7A7xbsK0R PS3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781822742; x=1782427542; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=orCsuuUrSE13rotpUYJYYTAbwaY/W6h9VEYHAL58Cls=; b=Qh1viiMbYfA+KT87zVB78de858VW1zWOocUr1u7/leO/IMLqO9mEEgFM2hpSvnrFX+ F/zBH9vvI9DwHVdM04nJXVjj6WIWEye8xaEw/BMveFjQpWI1yP9vztBgLMgIKerhK6+1 BxzK5KGsOrzSYu5HeY4A9b+Zf/tHyyHAX1MGRjY3wu5UcYQF8VUF97eGhBlwz9Od51Hn JAbSE5faLRwm5TwVW9g6n/YMCbMMHB3t2dalPWnpwc0E/gdjG3cDU595SlAcgNxOMsro x0Uypc01aKiLHJZrhkGVo17DCgRVIl2fjnUIz/5dcbVQMHjNRIXSIPzik2BjrkGhYxaU UaZw== X-Gm-Message-State: AOJu0YzCdyl2lSBgtZdnGxA1kSuXMfL/X+C3DhB7Fv0gk4r4PR+yD9I0 TTecmBJ6TymCSoZl+Zz048P5n9prsex6DUS3eo2tdkZaZuLTQF7lOBnoEaC9YoguhJDLqgkvDTA 8UXHY7vLj/abNkQ== X-Received: from plae3.prod.google.com ([2002:a17:902:e0c3:b0:2b0:5102:ab9e]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:d489:b0:2c0:ccdb:e02c with SMTP id d9443c01a7336-2c718efa7acmr12378295ad.7.1781822742377; Thu, 18 Jun 2026 15:45:42 -0700 (PDT) Date: Thu, 18 Jun 2026 15:45:25 -0700 In-Reply-To: <20260618224527.1506419-1-jmattson@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260618224527.1506419-1-jmattson@google.com> X-Mailer: git-send-email 2.55.0.rc0.799.gd6f94ed593-goog Message-ID: <20260618224527.1506419-3-jmattson@google.com> Subject: [PATCH v3 2/4] x86/mce/inject: Avoid racy updates to MSR_K7_HWCR during MCE injection From: Jim Mattson To: bp@alien8.de, tglx@kernel.org, x86@kernel.org, rafael@kernel.org, viresh.kumar@linaro.org, yosry@kernel.org, andrew.cooper3@citrix.com, ludloff@gmail.com Cc: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, Jim Mattson Content-Type: text/plain; charset="UTF-8" MCE injection performs a read-modify-write of MSR_K7_HWCR as two independent crosscalls (via toggle_hw_mce_inject) wrapping the actual MSR writes (prepare_msrs). Another HWCR update on the target CPU could be lost if it occurred between these crosscalls. Introduce ipi_inject_mce() to perform the entire injection sequence (toggle ON, write MSRs, toggle OFF) in a single IPI callback, ensuring atomicity on the target CPU. For the local CPU initialization path in check_hw_inj_possible(), use amd_update_hwcr() directly to avoid IPI overhead and ensure safe updates. Remove toggle_hw_mce_inject() as it is no longer used. Opportunistically, replace the open-coded BIT(18) with a new MSR_K7_HWCR_MCSTATUSWREN macro. Fixes: 21690934d934 ("EDAC, mce_amd_inj: Enable direct writes to MCE MSRs") Link: https://sashiko.dev/#/patchset/20260612215729.1532175-1-jmattson%40google.com?part=2 Assisted-by: Gemini:gemini-3.5-pro Signed-off-by: Jim Mattson --- arch/x86/include/asm/msr-index.h | 2 ++ arch/x86/kernel/cpu/mce/inject.c | 46 ++++++++++---------------------- 2 files changed, 16 insertions(+), 32 deletions(-) diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 86554de9a3f5..29c4abade594 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -896,6 +896,8 @@ #define MSR_K7_HWCR 0xc0010015 #define MSR_K7_HWCR_SMMLOCK_BIT 0 #define MSR_K7_HWCR_SMMLOCK BIT_ULL(MSR_K7_HWCR_SMMLOCK_BIT) +#define MSR_K7_HWCR_MCSTATUSWREN_BIT 18 +#define MSR_K7_HWCR_MCSTATUSWREN BIT_ULL(MSR_K7_HWCR_MCSTATUSWREN_BIT) #define MSR_K7_HWCR_IRPERF_EN_BIT 30 #define MSR_K7_HWCR_IRPERF_EN BIT_ULL(MSR_K7_HWCR_IRPERF_EN_BIT) #define MSR_K7_HWCR_CPUID_USER_DIS_BIT 35 diff --git a/arch/x86/kernel/cpu/mce/inject.c b/arch/x86/kernel/cpu/mce/inject.c index 6f8a49d8baeb..1e017d8e23e4 100644 --- a/arch/x86/kernel/cpu/mce/inject.c +++ b/arch/x86/kernel/cpu/mce/inject.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "internal.h" @@ -311,30 +312,6 @@ static struct notifier_block inject_nb = { .notifier_call = mce_inject_raise, }; -/* - * Caller needs to be make sure this cpu doesn't disappear - * from under us, i.e.: get_cpu/put_cpu. - */ -static int toggle_hw_mce_inject(unsigned int cpu, bool enable) -{ - struct msr val; - int err; - - err = rdmsrq_on_cpu(cpu, MSR_K7_HWCR, &val.q); - if (err) { - pr_err("%s: error reading HWCR\n", __func__); - return err; - } - - enable ? (val.l |= BIT(18)) : (val.l &= ~BIT(18)); - - err = wrmsrq_on_cpu(cpu, MSR_K7_HWCR, val.q); - if (err) - pr_err("%s: error writing HWCR\n", __func__); - - return err; -} - static int __set_inj(const char *buf) { int i; @@ -500,6 +477,12 @@ static void prepare_msrs(void *info) wrmsrq(MSR_IA32_MCx_MISC(b), m.misc); } } +static void ipi_inject_mce(void *info) +{ + amd_update_hwcr(MSR_K7_HWCR_MCSTATUSWREN_BIT, true); + prepare_msrs(info); + amd_update_hwcr(MSR_K7_HWCR_MCSTATUSWREN_BIT, false); +} static void do_inject(void) { @@ -556,13 +539,13 @@ static void do_inject(void) if (!cpu_online(cpu)) goto err; - toggle_hw_mce_inject(cpu, true); - i_mce.mcgstatus = mcg_status; i_mce.inject_flags = inj_type; - smp_call_function_single(cpu, prepare_msrs, &i_mce, 0); - toggle_hw_mce_inject(cpu, false); + if (smp_call_function_single(cpu, ipi_inject_mce, &i_mce, 1)) { + pr_err("%s: Error injecting MCE on CPU %d\n", __func__, cpu); + goto err; + } switch (inj_type) { case DFR_INT_INJ: @@ -727,7 +710,6 @@ static void __init debugfs_init(void) static void check_hw_inj_possible(void) { - int cpu; u8 bank; /* @@ -737,7 +719,7 @@ static void check_hw_inj_possible(void) if (!cpu_feature_enabled(X86_FEATURE_SMCA)) return; - cpu = get_cpu(); + get_cpu(); for (bank = 0; bank < MAX_NR_BANKS; ++bank) { u64 status = MCI_STATUS_VAL, ipid; @@ -747,7 +729,7 @@ static void check_hw_inj_possible(void) if (!ipid) continue; - toggle_hw_mce_inject(cpu, true); + amd_update_hwcr(MSR_K7_HWCR_MCSTATUSWREN_BIT, true); wrmsrq_safe(mca_msr_reg(bank, MCA_STATUS), status); rdmsrq_safe(mca_msr_reg(bank, MCA_STATUS), &status); @@ -759,7 +741,7 @@ static void check_hw_inj_possible(void) "Try using APEI EINJ instead.\n"); } - toggle_hw_mce_inject(cpu, false); + amd_update_hwcr(MSR_K7_HWCR_MCSTATUSWREN_BIT, false); break; } -- 2.55.0.rc0.799.gd6f94ed593-goog