[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20220503032820.61667-3-Smita.KoralahalliChannabasappa@amd.com>
Date: Mon, 2 May 2022 22:28:18 -0500
From: Smita Koralahalli <Smita.KoralahalliChannabasappa@....com>
To: <linux-edac@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
<x86@...nel.org>
CC: Tony Luck <tony.luck@...el.com>,
Smita Koralahalli <Smita.KoralahalliChannabasappa@....com>,
<hpa@...or.com>, Yazen Ghannam <yazen.ghannam@....com>,
Dave Hansen <dave.hansen@...ux.intel.com>
Subject: [PATCH v5 2/3] x86/mce: Check for writes ignored in MCA_STATUS register
According to Section 2.1.16.3 under HWCR[McStatusWrEn] in "PPR for AMD
Family 19h, Model 01h, Revision B1 Processors - 55898 Rev 0.35 - Feb 5,
2021", the status register may sometimes enforce write ignored behavior
independent of the value of HWCR[McStatusWrEn] depending on the platform
settings.
Hence, evaluate for writes ignored for MCA_STATUS before doing hw error
injection. If true, return the appropriate error code to userspace.
Introduce "hw_injection_possible" flag to return early on subsequent
hw error injections.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=206537
Signed-off-by: Smita Koralahalli <Smita.KoralahalliChannabasappa@....com>
---
Link:
https://lkml.kernel.org/r/20220214233640.70510-2-Smita.KoralahalliChannabasappa@amd.com
v2:
msr_ops -> mca_msr_reg().
simulation -> injection.
pr_info() -> pr_err().
Aligned on ",".
v3:
Removed "x86/mce: Use mca_msr_reg() in prepare_msrs()" patch.
and made changes on the existing MCx_{STATUS, ADDR, MISC} macros.
v4:
Simplified the code by just checking for writes ignored behavior in
MCA_STATUS register.
Introduced prepare_mca_status() and performed writes ignored checks
inside the function.
Rephrased error message.
v5:
Replaced i_mce with inject_desc.
Introduction of hw_injection_possible flag to return early if HW
error injections are not possible.
---
arch/x86/kernel/cpu/mce/inject.c | 25 +++++++++++++++++++++++++
arch/x86/kernel/cpu/mce/internal.h | 2 +-
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/cpu/mce/inject.c b/arch/x86/kernel/cpu/mce/inject.c
index 05581b718529..cce068a4478c 100644
--- a/arch/x86/kernel/cpu/mce/inject.c
+++ b/arch/x86/kernel/cpu/mce/inject.c
@@ -33,6 +33,8 @@
#include "internal.h"
+static bool hw_injection_possible = true;
+
/* Collect all the MCi_XXX settings */
static struct inject_desc {
struct mce m;
@@ -474,11 +476,29 @@ static void toggle_nb_mca_mst_cpu(u16 nid)
__func__, PCI_FUNC(F3->devfn), NBCFG);
}
+static bool prepare_mca_status(void)
+{
+ u32 status_reg = mca_msr_reg(inj_desc.m.bank, MCA_STATUS);
+ u64 status_val = inj_desc.m.status;
+
+ wrmsrl(status_reg, status_val);
+ rdmsrl(status_reg, status_val);
+
+ return status_val == inj_desc.m.status;
+}
+
static void prepare_msrs(void *unused)
{
struct mce *m = &inj_desc.m;
u8 b = inj_desc.m.bank;
+ if (!prepare_mca_status()) {
+ pr_err("Platform does not allow error injection, try using APEI EINJ instead.\n");
+ inj_desc.err = -EINVAL;
+ hw_injection_possible = false;
+ return;
+ }
+
wrmsrl(MSR_IA32_MCG_STATUS, m->mcgstatus);
if (boot_cpu_has(X86_FEATURE_SMCA)) {
@@ -521,6 +541,11 @@ static int do_inject(void)
return 0;
}
+ if (!hw_injection_possible) {
+ pr_err("SW-only injection possible on this platform");
+ return -EINVAL;
+ }
+
/* prep MCE global settings for the injection */
mcg_status = MCG_STATUS_MCIP | MCG_STATUS_EIPV;
diff --git a/arch/x86/kernel/cpu/mce/internal.h b/arch/x86/kernel/cpu/mce/internal.h
index 4ae0e603f7fa..7e03f5b7f6bd 100644
--- a/arch/x86/kernel/cpu/mce/internal.h
+++ b/arch/x86/kernel/cpu/mce/internal.h
@@ -211,7 +211,7 @@ noinstr u64 mce_rdmsrl(u32 msr);
static __always_inline u32 mca_msr_reg(int bank, enum mca_msr reg)
{
- if (mce_flags.smca) {
+ if (cpu_feature_enabled(X86_FEATURE_SMCA)) {
switch (reg) {
case MCA_CTL: return MSR_AMD64_SMCA_MCx_CTL(bank);
case MCA_ADDR: return MSR_AMD64_SMCA_MCx_ADDR(bank);
--
2.17.1
Powered by blists - more mailing lists