Re: [PATCH] x86/cpu/centaur: Disable X86_FEATURE_FSGSBASE on Zhaoxin C4600
From: David Laight
Date: Thu Mar 05 2026 - 09:12:14 EST
On Thu, 5 Mar 2026 17:03:07 +0800
Tony W Wang-oc <TonyWWang-oc@xxxxxxxxxxx> wrote:
> Thank you for submitting the patch to fix the Zhaoxin CPU issue.
>
> After internal clarification, we have confirmed that this is an
> issue with the ZX-C CPU ucode:
> When modifying CR4.FSGSBASE bit 16, the ucode propagates its
> value to another MSR register. During execution of FSGSBASE-related
> instructions, the hardware actually checks whether this MSR
> register's bit is set to determine whether to generate a #UD
> exception.
> When the CPU enters SMM mode and then returns via RSM, the CR4
> register is restored but the value of CR4.FSGSBASE is not
> re-propagated to the MSR register.
> As a result, after enabling CR4.FSGSBASE, once the CPU goes
> through SMM mode, executing FSGSBASE-related instructions will
> trigger a #UD exception.
>
> This issue exists only on ZX-C CPUs, which have two different
> CPU vendor IDs and distinct FMS values. The following patch can
> be used to identify ZX-C CPUs and properly handle this issue:
>
> --- a/arch/x86/kernel/cpu/centaur.c
> +++ b/arch/x86/kernel/cpu/centaur.c
> @@ -201,6 +201,11 @@ 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) {
The '>= 14' looks odd to me.
It implies it all worked, got broken, and will never be fixed.
I'd also add a 1-line comment, something like:
/* CR4.FSGSBASE not copied to MSR on return from SMM mode. */
David
> + 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..6a2d6df307ee 100644
> --- 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);
> + }
> +
> init_ia32_feat_ctl(c);
> }
>
> Sincerely
> TonyWWang-oc
>