From c74c3473533fd53a4b5aeffb74e51aa5e1b3c37d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sat, 9 May 2020 00:46:43 +0200 Subject: [PATCH] kernel/x86: detect xsave subfeatures Change-Id: Ida635441faaea4fb060e9f77ca3f4f167dc4bfe4 Reviewed-on: https://review.haiku-os.org/c/haiku/+/2617 Reviewed-by: Adrien Destugues --- headers/private/kernel/arch/x86/arch_cpu.h | 8 ++++++++ src/system/kernel/arch/x86/arch_cpu.cpp | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/headers/private/kernel/arch/x86/arch_cpu.h b/headers/private/kernel/arch/x86/arch_cpu.h index c2826550b3..fa5215eead 100644 --- a/headers/private/kernel/arch/x86/arch_cpu.h +++ b/headers/private/kernel/arch/x86/arch_cpu.h @@ -294,6 +294,13 @@ #define IA32_FEATURE_ARCH_CAPABILITIES (1 << 29) // IA32_ARCH_CAPABILITIES MSR #define IA32_FEATURE_SSBD (1 << 31) // Speculative Store Bypass Disable +// x86 features from cpuid eax 0xd, ecx 1, eax register +// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 3-8) +#define IA32_FEATURE_XSAVEOPT (1 << 0) // XSAVEOPT Instruction +#define IA32_FEATURE_XSAVEC (1 << 1) // XSAVEC and compacted XRSTOR +#define IA32_FEATURE_XGETBV1 (1 << 2) // XGETBV with ECX=1 Instruction +#define IA32_FEATURE_XSAVES (1 << 3) // XSAVES and XRSTORS Instruction + // x86 defined features from cpuid eax 0x80000007, edx register #define IA32_FEATURE_INVARIANT_TSC (1 << 8) @@ -402,6 +409,7 @@ enum x86_feature_type { FEATURE_7_EDX, // cpuid eax=7, edx registers FEATURE_EXT_7_EDX, // cpuid eax=0x80000007, edx register FEATURE_EXT_8_EBX, // cpuid eax=0x80000008, ebx register + FEATURE_D_1_EAX, // cpuid eax=0xd, ecx=1, eax register FEATURE_NUM }; diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index eb2f738dcb..d6fbd74c10 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -560,6 +560,14 @@ dump_feature_string(int currentCPU, cpu_ent* cpu) strlcat(features, "msr_arch ", sizeof(features)); if (cpu->arch.feature[FEATURE_7_EDX] & IA32_FEATURE_SSBD) strlcat(features, "ssbd ", sizeof(features)); + if (cpu->arch.feature[FEATURE_D_1_EAX] & IA32_FEATURE_XSAVEOPT) + strlcat(features, "xsaveopt ", sizeof(features)); + if (cpu->arch.feature[FEATURE_D_1_EAX] & IA32_FEATURE_XSAVEC) + strlcat(features, "xsavec ", sizeof(features)); + if (cpu->arch.feature[FEATURE_D_1_EAX] & IA32_FEATURE_XGETBV1) + strlcat(features, "xgetbv1 ", sizeof(features)); + if (cpu->arch.feature[FEATURE_D_1_EAX] & IA32_FEATURE_XSAVES) + strlcat(features, "xsaves ", sizeof(features)); if (cpu->arch.feature[FEATURE_EXT_8_EBX] & IA32_FEATURE_CLZERO) strlcat(features, "clzero ", sizeof(features)); if (cpu->arch.feature[FEATURE_EXT_8_EBX] & IA32_FEATURE_IBPB) @@ -1069,6 +1077,7 @@ detect_cpu(int currentCPU) cpu->arch.feature[FEATURE_7_EBX] = 0; cpu->arch.feature[FEATURE_7_ECX] = 0; cpu->arch.feature[FEATURE_7_EDX] = 0; + cpu->arch.feature[FEATURE_D_1_EAX] = 0; cpu->arch.model_name[0] = 0; // print some fun data @@ -1185,6 +1194,11 @@ detect_cpu(int currentCPU) cpu->arch.feature[FEATURE_7_EDX] = cpuid.regs.edx; } + if (maxBasicLeaf >= 0xd) { + get_current_cpuid(&cpuid, 0xd, 1); + cpu->arch.feature[FEATURE_D_1_EAX] = cpuid.regs.eax; + } + if (maxExtendedLeaf >= 0x80000007) { get_current_cpuid(&cpuid, 0x80000007, 0); cpu->arch.feature[FEATURE_EXT_7_EDX] = cpuid.regs.edx;