[PATCH v7 047/120] x86/cpu/amd: Refactor CPUID(0x1) level calculation

"Ahmed S. Darwish" <[email protected]> Thu, 28 May 2026 17:38:09 +0200
Newsgroups dev.linux.lists.x86-cpuid,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
AMD K8 init code has the cryptic CPUID(0x1).EAX level check:

    (level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58

Given that:

    EAX[0:3] is the CPU stepping
    EAX[4:7] is the CPU base model
    EAX[8:11] is the base family ID, with 0xf as the largest
    EAX[16:19] is the CPU extended model

then "level >= 0x0f58" translates to:

    model > 5 || (model == 5 && stepping >= 8)

and "level >= 0x0f48 && level < 0x0f50" translates to:

    model == 4 && stepping >= 8

The two expressions can then be combined as:

    model > 5 || ((model == 0x4 || model == 0x5) && stepping >= 0x8)

and further combined as:

    model > 5 || (model >= 4 && stepping >= 8)

where "model" in all translations above is the decoded CPUID model:

    base_model | (ext_model << 4)

Using all the information above, convert that CPUID(0x1).EAX level check
into a more readable form.

Avoid a direct CPUID query by using the already cached CPU model and
stepping values at struct cpuinfo_x86.

Signed-off-by: Ahmed S. Darwish <[email protected]>
---
 arch/x86/kernel/cpu/amd.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 50bbf9f33501..0e077a4f2646 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -691,12 +691,10 @@ static void early_init_amd(struct cpuinfo_x86 *c)
 
 static void init_amd_k8(struct cpuinfo_x86 *c)
 {
-	u32 level;
 	u64 value;
 
 	/* On C+ stepping K8 rep microcode works well for copy/memset */
-	level = cpuid_eax(1);
-	if ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)
+	if (c->x86_model > 5 || (c->x86_model >= 4 && c->x86_stepping >= 8))
 		set_cpu_cap(c, X86_FEATURE_REP_GOOD);
 
 	/*
-- 
2.54.0