Re: [PATCH] x86/cpu/centaur: Disable X86_FEATURE_FSGSBASE on Zhaoxin C4600
From: Tony W Wang-oc
Date: Wed Mar 11 2026 - 22:15:29 EST
Hi Dave/Andrew/David/Yaozi,
Sorry for the late reply.
First of all, this bug was present in certain early ucode patches for ZX-C/ZX-C+ series CPUs; however, it has since been resolved in subsequent updates to the ZX-C/ZX-C+ ucode patch.
According to available documentation, the VIA Eden platform supports FSGSBASE; however, this CPU is too old, and we haven't been able to locate actual hardware to test whether it was affected by this bug.
It is recommended that, in addition to the existing FMS-based detection, a supplementary check be implemented to identify the specific ucode patch revisions associated with ZX-C/ZX-C+ that are known to exhibit this bug.
Due to differences in ucode matching rules on Zhaoxin platforms, existing kernel function interfaces cannot be used, so the patch code has been placed in a vendor-specific file. The specific patching approach can be as follows:
--- a/arch/x86/kernel/cpu/centaur.c
+++ b/arch/x86/kernel/cpu/centaur.c
@@ -8,6 +8,7 @@
#include <asm/e820/api.h>
#include <asm/mtrr.h>
#include <asm/msr.h>
+#include <asm/microcode.h>
#include "cpu.h"
@@ -110,6 +111,8 @@ static void early_init_centaur(struct cpuinfo_x86 *c)
static void init_centaur(struct cpuinfo_x86 *c)
{
+ u32 chip_pf, dummy;
+
#ifdef CONFIG_X86_32
char *name;
u32 fcr_set = 0;
@@ -201,6 +204,18 @@ static void init_centaur(struct cpuinfo_x86 *c)
set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
#endif
+ if (c->x86 == 6 && c->x86_model == 15 && c->x86_stepping >= 14) {
+ native_rdmsr(0x1232, dummy, chip_pf);
+ chip_pf = (chip_pf >> 15) & 0x7;
+ c->microcode = intel_get_microcode_revision();
+
+ if ((chip_pf == 0 && c->microcode < 0x20e) ||
+ (chip_pf == 1 && c->microcode < 0x208)) {
+ pr_warn_once("CPU has broken FSGSBASE support; clear FSGSBASE feature\n");
+ setup_clear_cpu_cap(X86_FEATURE_FSGSBASE);
+ }
+ }
+
init_ia32_feat_ctl(c);
}
diff --git a/arch/x86/kernel/cpu/zhaoxin.c b/arch/x86/kernel/cpu/zhaoxin.c
index 031379b7d4fa..0a0525320502 100644
--- a/arch/x86/kernel/cpu/zhaoxin.c
+++ b/arch/x86/kernel/cpu/zhaoxin.c
@@ -5,6 +5,7 @@
#include <asm/cpu.h>
#include <asm/cpufeature.h>
#include <asm/msr.h>
+#include <asm/microcode.h>
#include "cpu.h"
@@ -68,6 +69,8 @@ static void early_init_zhaoxin(struct cpuinfo_x86 *c)
static void init_zhaoxin(struct cpuinfo_x86 *c)
{
+ u32 chip_pf, dummy;
+
early_init_zhaoxin(c);
init_intel_cacheinfo(c);
@@ -89,6 +92,18 @@ static void init_zhaoxin(struct cpuinfo_x86 *c)
set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
#endif
+ if (c->x86 == 6 && c->x86_model == 25 && c->x86_stepping <= 3) {
+ native_rdmsr(0x1232, dummy, chip_pf);
+ chip_pf = (chip_pf >> 15) & 0x7;
+ c->microcode = intel_get_microcode_revision();
+
+ if ((chip_pf == 0 && c->microcode < 0x20e) ||
+ (chip_pf == 1 && c->microcode < 0x208)) {
+ pr_warn_once("CPU has broken FSGSBASE support; clear FSGSBASE feature\n");
+ setup_clear_cpu_cap(X86_FEATURE_FSGSBASE);
+ }
+ }
+
init_ia32_feat_ctl(c);
}
Sincerely!
TonyWWang-oc
On 2026/3/6 00:20, Dave Hansen wrote:
[这封邮件来自外部发件人 谨防风险]
On 3/5/26 01:03, Tony W Wang-oc wrote:
--- a/arch/x86/kernel/cpu/zhaoxin.c
+++ b/arch/x86/kernel/cpu/zhaoxin.c
@@ -89,6 +89,11 @@ static void init_zhaoxin(struct cpuinfo_x86 *c)
set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
#endif
+ if (c->x86 == 6 && c->x86_model == 25 && c->x86_stepping <= 3) {
+ pr_warn_once("CPU has broken FSGSBASE support; clear
FSGSBASE feature\n");
+ setup_clear_cpu_cap(X86_FEATURE_FSGSBASE);
+ }
+
Folks, we have vendor-generic infrastructure to handle these today. You
don't need to hack copied and pasted code across vendor-specific files.
You just need some "VFM" defines for the models:
#define Z_MODEL_HERE VFM_MAKE(X86_VENDOR_ZHAOXIN, 6, 26)
#define C_MODEL_HERE VFM_MAKE(X86_VENDOR_ZHAOXIN, ...)
a table:
static const struct x86_cpu_id bum_fsgsbase[] __initconst = {
X86_MATCH_VFM_STEPS(Z_MODEL_HERE, X86_STEP_MIN, 0x3, 1),
X86_MATCH_VFM_STEPS(C_MODEL_HERE, ..., 1),
};
and this code:
if (x86_match_cpu(bum_fsgsbase))
setup_clear_cpu_cap(X86_FEATURE_FSGSBASE);
That code happens _once_. You can even call it from vendor-independent code.
If you get fixed microcode that can also be extended to store a fixed
microcode version (although we're moving away from doing this on Intel).
Just please give the models some semi-sane model name.