lkml.org 
[lkml]   [2022]   [May]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v5 2/3] x86/mce: Check for writes ignored in MCA_STATUS register
Date
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@amd.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
\
 
 \ /
  Last update: 2022-05-03 05:29    [W:0.066 / U:1.232 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site