[PATCH] x86/cpu/hygon: Work around XSAVES Erratum 1386

From: Tina Zhang

Date: Wed Oct 28 2026 - 19:57:45 EST


The XSAVES malfunction described in AMD Erratum 1386 also affects
certain Hygon Family 18h processors. Under specific conditions, XSAVES
may fail to save XMM register state, allowing stale register values to
reappear after the state is restored.

None of the affected processors enumerate supervisor XSAVE state
components. XSAVEC is therefore equivalent for their enabled state
components and is not affected by the erratum.

Family 18h models 00h through 06h and model 10h are affected. Other
Family 18h models contain the fix in hardware.

For the following model and stepping combinations, the minimum
microcode revisions containing the fix are:

Model Stepping Microcode
04h 0 0x9040000f
04h 1 0x9041000f
06h 0 0x9060000f
06h 1 0x9061000f
10h 0 0x91000004

These are the only known steppings for those models.

Disable XSAVES on affected processors unless a matching model and
stepping entry identifies a sufficiently recent microcode revision
containing the fix. This allows the x86 FPU code to use XSAVEC
instead.

Signed-off-by: Tina Zhang <zhang_wei@xxxxxxxxxxxxxx>
Tested-by: Qiming Deng <dengqiming@xxxxxxxx>
Reviewed-by: Zhen Yang <yangzhen@xxxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
---
arch/x86/kernel/cpu/hygon.c | 40 +++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)

diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c
index ec51c2b9a257..0967b0f181dc 100644
--- a/arch/x86/kernel/cpu/hygon.c
+++ b/arch/x86/kernel/cpu/hygon.c
@@ -10,6 +10,7 @@

#include <asm/apic.h>
#include <asm/cpu.h>
+#include <asm/cpu_device_id.h>
#include <asm/cpuid/api.h>
#include <asm/smp.h>
#include <asm/numa.h>
@@ -170,11 +171,50 @@ static void early_init_hygon(struct cpuinfo_x86 *c)
set_cpu_cap(c, X86_FEATURE_VMMCALL);
}

+#define X86_MATCH_HYGON_MODEL_STEP_UCODE(model, step, ucode) \
+ X86_MATCH_VFM_STEPS(VFM_MAKE(X86_VENDOR_HYGON, 0x18, model), \
+ step, step, ucode)
+
+static const struct x86_cpu_id erratum_1386_microcode[] = {
+ X86_MATCH_HYGON_MODEL_STEP_UCODE(0x04, 0x00, 0x9040000f),
+ X86_MATCH_HYGON_MODEL_STEP_UCODE(0x04, 0x01, 0x9041000f),
+ X86_MATCH_HYGON_MODEL_STEP_UCODE(0x06, 0x00, 0x9060000f),
+ X86_MATCH_HYGON_MODEL_STEP_UCODE(0x06, 0x01, 0x9061000f),
+ X86_MATCH_HYGON_MODEL_STEP_UCODE(0x10, 0x00, 0x91000004),
+ {}
+};
+
+static void fix_erratum_1386(struct cpuinfo_x86 *c)
+{
+ /*
+ * Affected processors enumerate no supervisor XSAVE state components,
+ * so XSAVEC is equivalent and is not affected by Erratum 1386.
+ * Disable XSAVES unless the microcode is known to contain the fix.
+ */
+ if (c->x86 != 0x18)
+ return;
+
+ /* Models affected by Erratum 1386. */
+ switch (c->x86_model) {
+ case 0x00 ... 0x06:
+ case 0x10:
+ break;
+ default:
+ return;
+ }
+
+ if (x86_match_min_microcode_rev(erratum_1386_microcode))
+ return;
+
+ clear_cpu_cap(c, X86_FEATURE_XSAVES);
+}
+
static void init_hygon(struct cpuinfo_x86 *c)
{
u64 vm_cr;

early_init_hygon(c);
+ fix_erratum_1386(c);

set_cpu_cap(c, X86_FEATURE_REP_GOOD);

--
2.43.7