From 65daa8c14696dea0d6ca2c0772d0022923435f57 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Fri, 22 Aug 2025 15:04:34 -0400 Subject: [PATCH] kernel/x86: Clean up AMD C1E feature detection. * If the CPUID bit is present, don't bother checking the models. (This will happen on hypervisors.) * Set the CPUID bit if we determine it's present. * Only do this on CPU 0. --- src/system/kernel/arch/x86/arch_cpu.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index 06e552af82..043f3d226a 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -1605,12 +1605,21 @@ detect_amdc1e_noarat() if (cpu->arch.vendor != VENDOR_AMD) return false; - // Family 0x12 and higher processors support ARAT - // Family lower than 0xf processors doesn't support C1E - // Family 0xf with model <= 0x40 procssors doesn't support C1E + if (cpu->arch.feature[FEATURE_6_EAX] & IA32_FEATURE_ARAT) + return false; + uint32 family = cpu->arch.family + cpu->arch.extended_family; uint32 model = (cpu->arch.extended_model << 4) | cpu->arch.model; - return (family < 0x12 && family > 0xf) || (family == 0xf && model > 0x40); + if (family >= 0x12) { + // Family 0x12 and higher processors support ARAT correctly, + // but they don't declare it in the CPUID until 0x17 (Zen). + cpu->arch.feature[FEATURE_6_EAX] |= IA32_FEATURE_ARAT; + return false; + } + + // Family lower than 0xf processors doesn't support C1E + // Family 0xf with model <= 0x40 processors doesn't support C1E + return (family > 0xf) || (family == 0xf && model > 0x40); } @@ -1732,10 +1741,9 @@ arch_cpu_init_percpu(kernel_args* args, int cpu) load_microcode(cpu); detect_cpu(cpu); - if (cpu == 0) + if (cpu == 0) { init_tsc(args); - if (!gCpuIdleFunc) { if (detect_amdc1e_noarat()) gCpuIdleFunc = amdc1e_noarat_idle; else