2023-06-07 10:49:50

by Tony W Wang-oc

[permalink] [raw]
Subject: [PATCH 1/3] x86/mce: Move Zhaoxin MCE functions to the separate file

Right now the functions of Zhaoxin MCE are in the MCE core.c file.
Create a separate zhaoxin.c to make MCE core.c more clearly.
Functions not change.

Signed-off-by: Tony W Wang-oc <[email protected]>
---
arch/x86/Kconfig | 8 +++++
arch/x86/include/asm/mce.h | 8 +++++
arch/x86/kernel/cpu/mce/Makefile | 1 +
arch/x86/kernel/cpu/mce/core.c | 49 ++++++++++++-------------------
arch/x86/kernel/cpu/mce/zhaoxin.c | 15 ++++++++++
5 files changed, 50 insertions(+), 31 deletions(-)
create mode 100644 arch/x86/kernel/cpu/mce/zhaoxin.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index a98c5f82be48..79db47afd752 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1182,6 +1182,14 @@ config X86_MCE_INJECT
If you don't know what a machine check is and you don't do kernel
QA it is safe to say n.

+config X86_MCE_ZHAOXIN
+ def_bool y
+ prompt "Zhaoxin MCE features"
+ depends on X86_MCE && X86_LOCAL_APIC && X86_MCE_INTEL
+ help
+ Additional support for Zhaoxin specific MCE features such as
+ the DRAM error threshold.
+
source "arch/x86/events/Kconfig"

config X86_LEGACY_VM86
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index 180b1cbfcc4e..c4776421518e 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -353,4 +353,12 @@ static inline void mce_hygon_feature_init(struct cpuinfo_x86 *c) { return mce_am

unsigned long copy_mc_fragile_handle_tail(char *to, char *from, unsigned len);

+#ifdef CONFIG_X86_MCE_ZHAOXIN
+void mce_zhaoxin_feature_init(void);
+void mce_zhaoxin_feature_clear(void);
+#else
+static inline void mce_zhaoxin_feature_init(void) { }
+static inline void mce_zhaoxin_feature_clear(void) { }
+#endif
+
#endif /* _ASM_X86_MCE_H */
diff --git a/arch/x86/kernel/cpu/mce/Makefile b/arch/x86/kernel/cpu/mce/Makefile
index 015856abdbb1..ff0b67f643d4 100644
--- a/arch/x86/kernel/cpu/mce/Makefile
+++ b/arch/x86/kernel/cpu/mce/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_X86_ANCIENT_MCE) += winchip.o p5.o
obj-$(CONFIG_X86_MCE_INTEL) += intel.o
obj-$(CONFIG_X86_MCE_AMD) += amd.o
obj-$(CONFIG_X86_MCE_THRESHOLD) += threshold.o
+obj-$(CONFIG_X86_MCE_ZHAOXIN) += zhaoxin.o

mce-inject-y := inject.o
obj-$(CONFIG_X86_MCE_INJECT) += mce-inject.o
diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
index 22dfcb2adcd7..6ae68749383c 100644
--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -1884,6 +1884,21 @@ static int __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
}

if (c->x86_vendor == X86_VENDOR_ZHAOXIN) {
+ /*
+ * These CPUs have MCA bank 8 which reports only one error type called
+ * SVAD (System View Address Decoder). The reporting of that error is
+ * controlled by IA32_MC8.CTL.0.
+ *
+ * If enabled, prefetching on these CPUs will cause SVAD MCE when
+ * virtual machines start and result in a system panic. Always disable
+ * bank 8 SVAD error by default.
+ */
+ if ((c->x86 == 7 && c->x86_model == 0x1b) ||
+ (c->x86_model == 0x19 || c->x86_model == 0x1f)) {
+ if (this_cpu_read(mce_num_banks) > 8)
+ mce_banks[8].ctl = 0;
+ }
+
/*
* All newer Zhaoxin CPUs support MCE broadcasting. Enable
* synchronization with a one second timeout.
@@ -1951,35 +1966,6 @@ static void mce_centaur_feature_init(struct cpuinfo_x86 *c)
}
}

-static void mce_zhaoxin_feature_init(struct cpuinfo_x86 *c)
-{
- struct mce_bank *mce_banks = this_cpu_ptr(mce_banks_array);
-
- /*
- * These CPUs have MCA bank 8 which reports only one error type called
- * SVAD (System View Address Decoder). The reporting of that error is
- * controlled by IA32_MC8.CTL.0.
- *
- * If enabled, prefetching on these CPUs will cause SVAD MCE when
- * virtual machines start and result in a system panic. Always disable
- * bank 8 SVAD error by default.
- */
- if ((c->x86 == 7 && c->x86_model == 0x1b) ||
- (c->x86_model == 0x19 || c->x86_model == 0x1f)) {
- if (this_cpu_read(mce_num_banks) > 8)
- mce_banks[8].ctl = 0;
- }
-
- intel_init_cmci();
- intel_init_lmce();
- mce_adjust_timer = cmci_intel_adjust_timer;
-}
-
-static void mce_zhaoxin_feature_clear(struct cpuinfo_x86 *c)
-{
- intel_clear_lmce();
-}
-
static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c)
{
switch (c->x86_vendor) {
@@ -2002,7 +1988,8 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c)
break;

case X86_VENDOR_ZHAOXIN:
- mce_zhaoxin_feature_init(c);
+ mce_zhaoxin_feature_init();
+ mce_adjust_timer = cmci_intel_adjust_timer;
break;

default:
@@ -2018,7 +2005,7 @@ static void __mcheck_cpu_clear_vendor(struct cpuinfo_x86 *c)
break;

case X86_VENDOR_ZHAOXIN:
- mce_zhaoxin_feature_clear(c);
+ mce_zhaoxin_feature_clear();
break;

default:
diff --git a/arch/x86/kernel/cpu/mce/zhaoxin.c b/arch/x86/kernel/cpu/mce/zhaoxin.c
new file mode 100644
index 000000000000..f4e90ec99267
--- /dev/null
+++ b/arch/x86/kernel/cpu/mce/zhaoxin.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <asm/mce.h>
+
+#include "internal.h"
+
+void mce_zhaoxin_feature_init(void)
+{
+ intel_init_cmci();
+ intel_init_lmce();
+}
+
+void mce_zhaoxin_feature_clear(void)
+{
+ intel_clear_lmce();
+}
--
2.17.1



2023-06-07 10:49:51

by Tony W Wang-oc

[permalink] [raw]
Subject: [PATCH 2/3] x86/mce: Set Zhaoxin CPUs MCE monarch_timeout correctly

Because __mcheck_cpu_apply_quirks will setting monarch_timeout = 0
before to call the function mce_centaur_feature_init.

So the if case below will not be executed:
if (cfg->monarch_timeout < 0)
cfg->monarch_timeout = USEC_PER_SEC;

Move monarch_timeout setup for these Zhaoxin CPUs to the function
__mcheck_cpu_apply_quirks to solve this problem.

Signed-off-by: Tony W Wang-oc <[email protected]>
---
arch/x86/kernel/cpu/mce/core.c | 31 ++++++++++++-------------------
1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
index 6ae68749383c..f919fa3ab69d 100644
--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -1909,6 +1909,18 @@ static int __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
}
}

+ if (c->x86_vendor == X86_VENDOR_CENTAUR) {
+ /*
+ * All newer Centaur CPUs support MCE broadcasting. Enable
+ * synchronization with a one second timeout.
+ */
+ if ((c->x86 == 6 && c->x86_model == 0xf && c->x86_stepping >= 0xe) ||
+ c->x86 > 6) {
+ if (cfg->monarch_timeout < 0)
+ cfg->monarch_timeout = USEC_PER_SEC;
+ }
+ }
+
if (cfg->monarch_timeout < 0)
cfg->monarch_timeout = 0;
if (cfg->bootlog != 0)
@@ -1951,21 +1963,6 @@ static void __mcheck_cpu_init_early(struct cpuinfo_x86 *c)
}
}

-static void mce_centaur_feature_init(struct cpuinfo_x86 *c)
-{
- struct mca_config *cfg = &mca_cfg;
-
- /*
- * All newer Centaur CPUs support MCE broadcasting. Enable
- * synchronization with a one second timeout.
- */
- if ((c->x86 == 6 && c->x86_model == 0xf && c->x86_stepping >= 0xe) ||
- c->x86 > 6) {
- if (cfg->monarch_timeout < 0)
- cfg->monarch_timeout = USEC_PER_SEC;
- }
-}
-
static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c)
{
switch (c->x86_vendor) {
@@ -1983,10 +1980,6 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c)
mce_hygon_feature_init(c);
break;

- case X86_VENDOR_CENTAUR:
- mce_centaur_feature_init(c);
- break;
-
case X86_VENDOR_ZHAOXIN:
mce_zhaoxin_feature_init();
mce_adjust_timer = cmci_intel_adjust_timer;
--
2.17.1


2023-06-07 10:49:53

by Tony W Wang-oc

[permalink] [raw]
Subject: [PATCH 3/3] x86/mce: add Zhaoxin another CPU Vendor ID support

Add Zhaoxin CPUs with Vendor ID "CentaurHauls" support for CMCI/LMCE.

Signed-off-by: Tony W Wang-oc <[email protected]>
---
arch/x86/kernel/cpu/mce/core.c | 15 +++++++++++----
arch/x86/kernel/cpu/mce/intel.c | 3 ++-
2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
index f919fa3ab69d..38228021fe99 100644
--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -466,7 +466,8 @@ int mce_usable_address(struct mce *m)

/* Checks after this one are Intel/Zhaoxin-specific: */
if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL &&
- boot_cpu_data.x86_vendor != X86_VENDOR_ZHAOXIN)
+ boot_cpu_data.x86_vendor != X86_VENDOR_ZHAOXIN &&
+ boot_cpu_data.x86_vendor != X86_VENDOR_CENTAUR)
return 1;

if (!(m->status & MCI_STATUS_MISCV))
@@ -491,6 +492,7 @@ bool mce_is_memory_error(struct mce *m)

case X86_VENDOR_INTEL:
case X86_VENDOR_ZHAOXIN:
+ case X86_VENDOR_CENTAUR:
/*
* Intel SDM Volume 3B - 15.9.2 Compound Error Codes
*
@@ -1192,7 +1194,8 @@ static noinstr bool mce_check_crashing_cpu(void)

mcgstatus = __rdmsr(MSR_IA32_MCG_STATUS);

- if (boot_cpu_data.x86_vendor == X86_VENDOR_ZHAOXIN) {
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_ZHAOXIN ||
+ boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR) {
if (mcgstatus & MCG_STATUS_LMCES)
return false;
}
@@ -1466,7 +1469,8 @@ noinstr void do_machine_check(struct pt_regs *regs)
* on Intel, Zhaoxin only.
*/
if (m.cpuvendor == X86_VENDOR_INTEL ||
- m.cpuvendor == X86_VENDOR_ZHAOXIN)
+ m.cpuvendor == X86_VENDOR_ZHAOXIN ||
+ m.cpuvendor == X86_VENDOR_CENTAUR)
lmce = m.mcgstatus & MCG_STATUS_LMCES;

/*
@@ -1981,6 +1985,7 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c)
break;

case X86_VENDOR_ZHAOXIN:
+ case X86_VENDOR_CENTAUR:
mce_zhaoxin_feature_init();
mce_adjust_timer = cmci_intel_adjust_timer;
break;
@@ -1998,6 +2003,7 @@ static void __mcheck_cpu_clear_vendor(struct cpuinfo_x86 *c)
break;

case X86_VENDOR_ZHAOXIN:
+ case X86_VENDOR_CENTAUR:
mce_zhaoxin_feature_clear();
break;

@@ -2282,7 +2288,8 @@ static void vendor_disable_error_reporting(void)
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ||
boot_cpu_data.x86_vendor == X86_VENDOR_HYGON ||
boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
- boot_cpu_data.x86_vendor == X86_VENDOR_ZHAOXIN)
+ boot_cpu_data.x86_vendor == X86_VENDOR_ZHAOXIN ||
+ boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR)
return;

mce_disable_error_reporting();
diff --git a/arch/x86/kernel/cpu/mce/intel.c b/arch/x86/kernel/cpu/mce/intel.c
index 95275a5e57e0..92f7104c86ad 100644
--- a/arch/x86/kernel/cpu/mce/intel.c
+++ b/arch/x86/kernel/cpu/mce/intel.c
@@ -86,7 +86,8 @@ static int cmci_supported(int *banks)
* makes sure none of the backdoors are entered otherwise.
*/
if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL &&
- boot_cpu_data.x86_vendor != X86_VENDOR_ZHAOXIN)
+ boot_cpu_data.x86_vendor != X86_VENDOR_ZHAOXIN &&
+ boot_cpu_data.x86_vendor != X86_VENDOR_CENTAUR)
return 0;

if (!boot_cpu_has(X86_FEATURE_APIC) || lapic_get_maxlvt() < 6)
--
2.17.1