Browse Source

Kernel: Support all Intel-defined extended CPUID feature flags for EAX=7

We're now able to detect all the extended CPUID feature flags from
EBX/ECX/EDX for EAX=7 :^)
Linus Groh 3 năm trước cách đây
mục cha
commit
96e6420d8d
3 tập tin đã thay đổi với 405 bổ sung12 xóa
  1. 97 12
      Kernel/Arch/x86/CPUID.h
  2. 153 0
      Kernel/Arch/x86/common/CPUID.cpp
  3. 155 0
      Kernel/Arch/x86/common/Processor.cpp

+ 97 - 12
Kernel/Arch/x86/CPUID.h

@@ -37,7 +37,7 @@ private:
     u32 m_edx { 0xffffffff };
 };
 
-AK_MAKE_ARBITRARY_SIZED_ENUM(CPUFeature, u128,
+AK_MAKE_ARBITRARY_SIZED_ENUM(CPUFeature, u256,
     /* EAX=1, ECX                                  */ //
     SSE3 = CPUFeature(1u) << 0u,                      // Streaming SIMD Extensions 3
     PCLMULQDQ = CPUFeature(1u) << 1u,                 // PCLMULDQ Instruction
@@ -105,20 +105,105 @@ AK_MAKE_ARBITRARY_SIZED_ENUM(CPUFeature, u128,
     IA64 = CPUFeature(1u) << 62u,                     // IA64 processor emulating x86
     PBE = CPUFeature(1u) << 63u,                      // Pending Break Enable
     /* EAX=7, EBX */                                  //
-    SMEP = CPUFeature(1u) << 64u,                     // Supervisor Mode Execution Protection
-    RDSEED = CPUFeature(1u) << 65u,                   // RDSEED Instruction
-    SMAP = CPUFeature(1u) << 66u,                     // Supervisor Mode Access Prevention
+    FSGSBASE = CPUFeature(1u) << 64u,                 // Access to base of %fs and %gs
+    TSC_ADJUST = CPUFeature(1u) << 65u,               // IA32_TSC_ADJUST MSR
+    SGX = CPUFeature(1u) << 66u,                      // Software Guard Extensions
+    BMI1 = CPUFeature(1u) << 67u,                     // Bit Manipulation Instruction Set 1
+    HLE = CPUFeature(1u) << 68u,                      // TSX Hardware Lock Elision
+    AVX2 = CPUFeature(1u) << 69u,                     // Advanced Vector Extensions 2
+    FDP_EXCPTN_ONLY = CPUFeature(1u) << 70u,          // FDP_EXCPTN_ONLY
+    SMEP = CPUFeature(1u) << 71u,                     // Supervisor Mode Execution Protection
+    BMI2 = CPUFeature(1u) << 72u,                     // Bit Manipulation Instruction Set 2
+    ERMS = CPUFeature(1u) << 73u,                     // Enhanced REP MOVSB/STOSB
+    INVPCID = CPUFeature(1u) << 74u,                  // INVPCID Instruction
+    RTM = CPUFeature(1u) << 75u,                      // TSX Restricted Transactional Memory
+    PQM = CPUFeature(1u) << 76u,                      // Platform Quality of Service Monitoring
+    ZERO_FCS_FDS = CPUFeature(1u) << 77u,             // FPU CS and FPU DS deprecated
+    MPX = CPUFeature(1u) << 78u,                      // Intel MPX (Memory Protection Extensions)
+    PQE = CPUFeature(1u) << 79u,                      // Platform Quality of Service Enforcement
+    AVX512_F = CPUFeature(1u) << 80u,                 // AVX-512 Foundation
+    AVX512_DQ = CPUFeature(1u) << 81u,                // AVX-512 Doubleword and Quadword Instructions
+    RDSEED = CPUFeature(1u) << 82u,                   // RDSEED Instruction
+    ADX = CPUFeature(1u) << 83u,                      // Intel ADX (Multi-Precision Add-Carry Instruction Extensions)
+    SMAP = CPUFeature(1u) << 84u,                     // Supervisor Mode Access Prevention
+    AVX512_IFMA = CPUFeature(1u) << 85u,              // AVX-512 Integer Fused Multiply-Add Instructions
+    PCOMMIT = CPUFeature(1u) << 86u,                  // PCOMMIT Instruction
+    CLFLUSHOPT = CPUFeature(1u) << 87u,               // CLFLUSHOPT Instruction
+    CLWB = CPUFeature(1u) << 88u,                     // CLWB Instruction
+    INTEL_PT = CPUFeature(1u) << 89u,                 // Intel Processor Tracing
+    AVX512_PF = CPUFeature(1u) << 90u,                // AVX-512 Prefetch Instructions
+    AVX512_ER = CPUFeature(1u) << 91u,                // AVX-512 Exponential and Reciprocal Instructions
+    AVX512_CD = CPUFeature(1u) << 92u,                // AVX-512 Conflict Detection Instructions
+    SHA = CPUFeature(1u) << 93u,                      // Intel SHA Extensions
+    AVX512_BW = CPUFeature(1u) << 94u,                // AVX-512 Byte and Word Instructions
+    AVX512_VL = CPUFeature(1u) << 95u,                // AVX-512 Vector Length Extensions
     /* EAX=7, ECX */                                  //
-    UMIP = CPUFeature(1u) << 67u,                     // User-Mode Instruction Prevention
+    PREFETCHWT1 = CPUFeature(1u) << 96u,              // PREFETCHWT1 Instruction
+    AVX512_VBMI = CPUFeature(1u) << 97u,              // AVX-512 Vector Bit Manipulation Instructions
+    UMIP = CPUFeature(1u) << 98u,                     // UMIP
+    PKU = CPUFeature(1u) << 99u,                      // Memory Protection Keys for User-mode pages
+    OSPKU = CPUFeature(1u) << 100u,                   // PKU enabled by OS
+    WAITPKG = CPUFeature(1u) << 101u,                 // Timed pause and user-level monitor/wait
+    AVX512_VBMI2 = CPUFeature(1u) << 102u,            // AVX-512 Vector Bit Manipulation Instructions 2
+    CET_SS = CPUFeature(1u) << 103u,                  // Control Flow Enforcement (CET) Shadow Stack
+    GFNI = CPUFeature(1u) << 104u,                    // Galois Field Instructions
+    VAES = CPUFeature(1u) << 105u,                    // Vector AES instruction set (VEX-256/EVEX)
+    VPCLMULQDQ = CPUFeature(1u) << 106u,              // CLMUL instruction set (VEX-256/EVEX)
+    AVX512_VNNI = CPUFeature(1u) << 107u,             // AVX-512 Vector Neural Network Instructions
+    AVX512_BITALG = CPUFeature(1u) << 108u,           // AVX-512 BITALG Instructions
+    TME_EN = CPUFeature(1u) << 109u,                  // IA32_TME related MSRs are supported
+    AVX512_VPOPCNTDQ = CPUFeature(1u) << 110u,        // AVX-512 Vector Population Count Double and Quad-word
+    /* ECX Bit 15 */                                  // Reserved
+    INTEL_5_LEVEL_PAGING = CPUFeature(1u) << 112u,    // Intel 5-Level Paging
+    RDPID = CPUFeature(1u) << 113u,                   // RDPID Instruction
+    KL = CPUFeature(1u) << 114u,                      // Key Locker
+    /* ECX Bit 24 */                                  // Reserved
+    CLDEMOTE = CPUFeature(1u) << 116u,                // Cache Line Demote
+    /* ECX Bit 26 */                                  // Reserved
+    MOVDIRI = CPUFeature(1u) << 118u,                 // MOVDIRI Instruction
+    MOVDIR64B = CPUFeature(1u) << 119u,               // MOVDIR64B Instruction
+    ENQCMD = CPUFeature(1u) << 120u,                  // ENQCMD Instruction
+    SGX_LC = CPUFeature(1u) << 121u,                  // SGX Launch Configuration
+    PKS = CPUFeature(1u) << 122u,                     // Protection Keys for Supervisor-Mode Pages
+    /* EAX=7, EDX */                                  //
+    /* ECX Bit 0-1 */                                 // Reserved
+    AVX512_4VNNIW = CPUFeature(1u) << 125u,           // AVX-512 4-register Neural Network Instructions
+    AVX512_4FMAPS = CPUFeature(1u) << 126u,           // AVX-512 4-register Multiply Accumulation Single precision
+    FSRM = CPUFeature(1u) << 127u,                    // Fast Short REP MOVSB
+    /* ECX Bit 5-7 */                                 // Reserved
+    AVX512_VP2INTERSECT = CPUFeature(1u) << 131u,     // AVX-512 VP2INTERSECT Doubleword and Quadword Instructions
+    SRBDS_CTRL = CPUFeature(1u) << 132u,              // Special Register Buffer Data Sampling Mitigations
+    MD_CLEAR = CPUFeature(1u) << 133u,                // VERW instruction clears CPU buffers
+    RTM_ALWAYS_ABORT = CPUFeature(1u) << 134u,        // All TSX transactions are aborted
+    /* ECX Bit 12 */                                  // Reserved
+    TSX_FORCE_ABORT = CPUFeature(1u) << 136u,         // TSX_FORCE_ABORT MSR
+    SERIALIZE = CPUFeature(1u) << 137u,               // Serialize instruction execution
+    HYBRID = CPUFeature(1u) << 138u,                  // Mixture of CPU types in processor topology
+    TSXLDTRK = CPUFeature(1u) << 139u,                // TSX suspend load address tracking
+    /* ECX Bit 17 */                                  // Reserved
+    PCONFIG = CPUFeature(1u) << 141u,                 // Platform configuration (Memory Encryption Technologies Instructions)
+    LBR = CPUFeature(1u) << 142u,                     // Architectural Last Branch Records
+    CET_IBT = CPUFeature(1u) << 143u,                 // Control flow enforcement (CET) indirect branch tracking
+    /* ECX Bit 21 */                                  // Reserved
+    AMX_BF16 = CPUFeature(1u) << 145u,                // Tile computation on bfloat16 numbers
+    AVX512_FP16 = CPUFeature(1u) << 146u,             // AVX512-FP16 half-precision floating-point instructions
+    AMX_TILE = CPUFeature(1u) << 147u,                // Tile architecture
+    AMX_INT8 = CPUFeature(1u) << 148u,                // Tile computation on 8-bit integers
+    SPEC_CTRL = CPUFeature(1u) << 149u,               // Speculation Control
+    STIBP = CPUFeature(1u) << 150u,                   // Single Thread Indirect Branch Predictor
+    L1D_FLUSH = CPUFeature(1u) << 151u,               // IA32_FLUSH_CMD MSR
+    IA32_ARCH_CAPABILITIES = CPUFeature(1u) << 152u,  // IA32_ARCH_CAPABILITIES MSR
+    IA32_CORE_CAPABILITIES = CPUFeature(1u) << 153u,  // IA32_CORE_CAPABILITIES MSR
+    SSBD = CPUFeature(1u) << 154u,                    // Speculative Store Bypass Disable
     /* EAX=80000001h, EDX */                          //
-    SYSCALL = CPUFeature(1u) << 68u,                  // SYSCALL/SYSRET Instructions
-    NX = CPUFeature(1u) << 69u,                       // NX bit
-    RDTSCP = CPUFeature(1u) << 70u,                   // RDTSCP Instruction
-    LM = CPUFeature(1u) << 71u,                       // Long Mode
+    SYSCALL = CPUFeature(1u) << 155u,                 // SYSCALL/SYSRET Instructions
+    NX = CPUFeature(1u) << 156u,                      // NX bit
+    RDTSCP = CPUFeature(1u) << 157u,                  // RDTSCP Instruction
+    LM = CPUFeature(1u) << 158u,                      // Long Mode
     /* EAX=80000007h, EDX */                          //
-    CONSTANT_TSC = CPUFeature(1u) << 72u,             // Invariant TSC
-    NONSTOP_TSC = CPUFeature(1u) << 73u,              // Invariant TSC
-    __End = CPUFeature(1u) << 127u);
+    CONSTANT_TSC = CPUFeature(1u) << 159u,            // Invariant TSC
+    NONSTOP_TSC = CPUFeature(1u) << 160u,             // Invariant TSC
+    __End = CPUFeature(1u) << 255u);
 
 StringView cpu_feature_to_string_view(CPUFeature::Type const&);
 

+ 153 - 0
Kernel/Arch/x86/common/CPUID.cpp

@@ -134,14 +134,167 @@ StringView cpu_feature_to_string_view(CPUFeature::Type const& feature)
         return "ia64"sv;
     if (feature == CPUFeature::PBE)
         return "pbe"sv;
+    if (feature == CPUFeature::FSGSBASE)
+        return "fsgsbase"sv;
+    if (feature == CPUFeature::TSC_ADJUST)
+        return "tsc_adjust"sv;
+    if (feature == CPUFeature::SGX)
+        return "sgx"sv;
+    if (feature == CPUFeature::BMI1)
+        return "bmi1"sv;
+    if (feature == CPUFeature::HLE)
+        return "hle"sv;
+    if (feature == CPUFeature::AVX2)
+        return "avx2"sv;
+    if (feature == CPUFeature::FDP_EXCPTN_ONLY)
+        return "fdp_excptn_only"sv;
     if (feature == CPUFeature::SMEP)
         return "smep"sv;
+    if (feature == CPUFeature::BMI2)
+        return "bmi2"sv;
+    if (feature == CPUFeature::ERMS)
+        return "erms"sv;
+    if (feature == CPUFeature::INVPCID)
+        return "invpcid"sv;
+    if (feature == CPUFeature::RTM)
+        return "rtm"sv;
+    if (feature == CPUFeature::PQM)
+        return "pqm"sv;
+    if (feature == CPUFeature::ZERO_FCS_FDS)
+        return "zero_fcs_fds"sv;
+    if (feature == CPUFeature::MPX)
+        return "mpx"sv;
+    if (feature == CPUFeature::PQE)
+        return "pqe"sv;
+    if (feature == CPUFeature::AVX512_F)
+        return "avx512_f"sv;
+    if (feature == CPUFeature::AVX512_DQ)
+        return "avx512_dq"sv;
     if (feature == CPUFeature::RDSEED)
         return "rdseed"sv;
+    if (feature == CPUFeature::ADX)
+        return "adx"sv;
     if (feature == CPUFeature::SMAP)
         return "smap"sv;
+    if (feature == CPUFeature::AVX512_IFMA)
+        return "avx512_ifma"sv;
+    if (feature == CPUFeature::PCOMMIT)
+        return "pcommit"sv;
+    if (feature == CPUFeature::CLFLUSHOPT)
+        return "clflushopt"sv;
+    if (feature == CPUFeature::CLWB)
+        return "clwb"sv;
+    if (feature == CPUFeature::INTEL_PT)
+        return "intel_pt"sv;
+    if (feature == CPUFeature::AVX512_PF)
+        return "avx512_pf"sv;
+    if (feature == CPUFeature::AVX512_ER)
+        return "avx512_er"sv;
+    if (feature == CPUFeature::AVX512_CD)
+        return "avx512_cd"sv;
+    if (feature == CPUFeature::SHA)
+        return "sha"sv;
+    if (feature == CPUFeature::AVX512_BW)
+        return "avx512_bw"sv;
+    if (feature == CPUFeature::AVX512_VL)
+        return "avx512_vl"sv;
+    if (feature == CPUFeature::PREFETCHWT1)
+        return "prefetchwt1"sv;
+    if (feature == CPUFeature::AVX512_VBMI)
+        return "avx512_vbmi"sv;
     if (feature == CPUFeature::UMIP)
         return "umip"sv;
+    if (feature == CPUFeature::PKU)
+        return "pku"sv;
+    if (feature == CPUFeature::OSPKU)
+        return "ospku"sv;
+    if (feature == CPUFeature::WAITPKG)
+        return "waitpkg"sv;
+    if (feature == CPUFeature::AVX512_VBMI2)
+        return "avx512_vbmi2"sv;
+    if (feature == CPUFeature::CET_SS)
+        return "cet_ss"sv;
+    if (feature == CPUFeature::GFNI)
+        return "gfni"sv;
+    if (feature == CPUFeature::VAES)
+        return "vaes"sv;
+    if (feature == CPUFeature::VPCLMULQDQ)
+        return "vpclmulqdq"sv;
+    if (feature == CPUFeature::AVX512_VNNI)
+        return "avx512_vnni"sv;
+    if (feature == CPUFeature::AVX512_BITALG)
+        return "avx512_bitalg"sv;
+    if (feature == CPUFeature::TME_EN)
+        return "tme_en"sv;
+    if (feature == CPUFeature::AVX512_VPOPCNTDQ)
+        return "avx512_vpopcntdq"sv;
+    if (feature == CPUFeature::INTEL_5_LEVEL_PAGING)
+        return "intel_5_level_paging"sv;
+    if (feature == CPUFeature::RDPID)
+        return "rdpid"sv;
+    if (feature == CPUFeature::KL)
+        return "kl"sv;
+    if (feature == CPUFeature::CLDEMOTE)
+        return "cldemote"sv;
+    if (feature == CPUFeature::MOVDIRI)
+        return "movdiri"sv;
+    if (feature == CPUFeature::MOVDIR64B)
+        return "movdir64b"sv;
+    if (feature == CPUFeature::ENQCMD)
+        return "enqcmd"sv;
+    if (feature == CPUFeature::SGX_LC)
+        return "sgx_lc"sv;
+    if (feature == CPUFeature::PKS)
+        return "pks"sv;
+    if (feature == CPUFeature::AVX512_4VNNIW)
+        return "avx512_4vnniw"sv;
+    if (feature == CPUFeature::AVX512_4FMAPS)
+        return "avx512_4fmaps"sv;
+    if (feature == CPUFeature::FSRM)
+        return "fsrm"sv;
+    if (feature == CPUFeature::AVX512_VP2INTERSECT)
+        return "avx512_vp2intersect"sv;
+    if (feature == CPUFeature::SRBDS_CTRL)
+        return "srbds_ctrl"sv;
+    if (feature == CPUFeature::MD_CLEAR)
+        return "md_clear"sv;
+    if (feature == CPUFeature::RTM_ALWAYS_ABORT)
+        return "rtm_always_abort"sv;
+    if (feature == CPUFeature::TSX_FORCE_ABORT)
+        return "tsx_force_abort"sv;
+    if (feature == CPUFeature::SERIALIZE)
+        return "serialize"sv;
+    if (feature == CPUFeature::HYBRID)
+        return "hybrid"sv;
+    if (feature == CPUFeature::TSXLDTRK)
+        return "tsxldtrk"sv;
+    if (feature == CPUFeature::PCONFIG)
+        return "pconfig"sv;
+    if (feature == CPUFeature::LBR)
+        return "lbr"sv;
+    if (feature == CPUFeature::CET_IBT)
+        return "cet_ibt"sv;
+    if (feature == CPUFeature::AMX_BF16)
+        return "amx_bf16"sv;
+    if (feature == CPUFeature::AVX512_FP16)
+        return "avx512_fp16"sv;
+    if (feature == CPUFeature::AMX_TILE)
+        return "amx_tile"sv;
+    if (feature == CPUFeature::AMX_INT8)
+        return "amx_int8"sv;
+    if (feature == CPUFeature::SPEC_CTRL)
+        return "spec_ctrl"sv;
+    if (feature == CPUFeature::STIBP)
+        return "stibp"sv;
+    // NOTE: This is called flush_l1d on Linux, but L1D_FLUSH in the Intel manual.
+    if (feature == CPUFeature::L1D_FLUSH)
+        return "l1d_flush"sv;
+    if (feature == CPUFeature::IA32_ARCH_CAPABILITIES)
+        return "ia32_arch_capabilities"sv;
+    if (feature == CPUFeature::IA32_CORE_CAPABILITIES)
+        return "ia32_code_capabilities"sv;
+    if (feature == CPUFeature::SSBD)
+        return "ssbd"sv;
     if (feature == CPUFeature::SYSCALL)
         return "syscall"sv;
     if (feature == CPUFeature::NX)

+ 155 - 0
Kernel/Arch/x86/common/Processor.cpp

@@ -212,14 +212,169 @@ UNMAP_AFTER_INIT void Processor::cpu_detect()
         m_features |= CPUFeature::PBE;
 
     CPUID extended_features(0x7);
+
+    if (extended_features.ebx() & (1 << 0))
+        m_features |= CPUFeature::FSGSBASE;
+    if (extended_features.ebx() & (1 << 1))
+        m_features |= CPUFeature::TSC_ADJUST;
+    if (extended_features.ebx() & (1 << 2))
+        m_features |= CPUFeature::SGX;
+    if (extended_features.ebx() & (1 << 3))
+        m_features |= CPUFeature::BMI1;
+    if (extended_features.ebx() & (1 << 4))
+        m_features |= CPUFeature::HLE;
+    if (extended_features.ebx() & (1 << 5))
+        m_features |= CPUFeature::AVX2;
+    if (extended_features.ebx() & (1 << 6))
+        m_features |= CPUFeature::FDP_EXCPTN_ONLY;
     if (extended_features.ebx() & (1 << 7))
         m_features |= CPUFeature::SMEP;
+    if (extended_features.ebx() & (1 << 8))
+        m_features |= CPUFeature::BMI2;
+    if (extended_features.ebx() & (1 << 9))
+        m_features |= CPUFeature::ERMS;
+    if (extended_features.ebx() & (1 << 10))
+        m_features |= CPUFeature::INVPCID;
+    if (extended_features.ebx() & (1 << 11))
+        m_features |= CPUFeature::RTM;
+    if (extended_features.ebx() & (1 << 12))
+        m_features |= CPUFeature::PQM;
+    if (extended_features.ebx() & (1 << 13))
+        m_features |= CPUFeature::ZERO_FCS_FDS;
+    if (extended_features.ebx() & (1 << 14))
+        m_features |= CPUFeature::MPX;
+    if (extended_features.ebx() & (1 << 15))
+        m_features |= CPUFeature::PQE;
+    if (extended_features.ebx() & (1 << 16))
+        m_features |= CPUFeature::AVX512_F;
+    if (extended_features.ebx() & (1 << 17))
+        m_features |= CPUFeature::AVX512_DQ;
     if (extended_features.ebx() & (1 << 18))
         m_features |= CPUFeature::RDSEED;
+    if (extended_features.ebx() & (1 << 19))
+        m_features |= CPUFeature::ADX;
     if (extended_features.ebx() & (1 << 20))
         m_features |= CPUFeature::SMAP;
+    if (extended_features.ebx() & (1 << 21))
+        m_features |= CPUFeature::AVX512_IFMA;
+    if (extended_features.ebx() & (1 << 22))
+        m_features |= CPUFeature::PCOMMIT;
+    if (extended_features.ebx() & (1 << 23))
+        m_features |= CPUFeature::CLFLUSHOPT;
+    if (extended_features.ebx() & (1 << 24))
+        m_features |= CPUFeature::CLWB;
+    if (extended_features.ebx() & (1 << 25))
+        m_features |= CPUFeature::INTEL_PT;
+    if (extended_features.ebx() & (1 << 26))
+        m_features |= CPUFeature::AVX512_PF;
+    if (extended_features.ebx() & (1 << 27))
+        m_features |= CPUFeature::AVX512_ER;
+    if (extended_features.ebx() & (1 << 28))
+        m_features |= CPUFeature::AVX512_CD;
+    if (extended_features.ebx() & (1 << 29))
+        m_features |= CPUFeature::SHA;
+    if (extended_features.ebx() & (1 << 30))
+        m_features |= CPUFeature::AVX512_BW;
+    if (extended_features.ebx() & (1 << 31))
+        m_features |= CPUFeature::AVX512_VL;
+
+    if (extended_features.ecx() & (1 << 0))
+        m_features |= CPUFeature::PREFETCHWT1;
+    if (extended_features.ecx() & (1 << 1))
+        m_features |= CPUFeature::AVX512_VBMI;
     if (extended_features.ecx() & (1 << 2))
         m_features |= CPUFeature::UMIP;
+    if (extended_features.ecx() & (1 << 3))
+        m_features |= CPUFeature::PKU;
+    if (extended_features.ecx() & (1 << 4))
+        m_features |= CPUFeature::OSPKU;
+    if (extended_features.ecx() & (1 << 5))
+        m_features |= CPUFeature::WAITPKG;
+    if (extended_features.ecx() & (1 << 6))
+        m_features |= CPUFeature::AVX512_VBMI2;
+    if (extended_features.ecx() & (1 << 7))
+        m_features |= CPUFeature::CET_SS;
+    if (extended_features.ecx() & (1 << 8))
+        m_features |= CPUFeature::GFNI;
+    if (extended_features.ecx() & (1 << 9))
+        m_features |= CPUFeature::VAES;
+    if (extended_features.ecx() & (1 << 10))
+        m_features |= CPUFeature::VPCLMULQDQ;
+    if (extended_features.ecx() & (1 << 11))
+        m_features |= CPUFeature::AVX512_VNNI;
+    if (extended_features.ecx() & (1 << 12))
+        m_features |= CPUFeature::AVX512_BITALG;
+    if (extended_features.ecx() & (1 << 13))
+        m_features |= CPUFeature::TME_EN;
+    if (extended_features.ecx() & (1 << 14))
+        m_features |= CPUFeature::AVX512_VPOPCNTDQ;
+    if (extended_features.ecx() & (1 << 16))
+        m_features |= CPUFeature::INTEL_5_LEVEL_PAGING;
+    if (extended_features.ecx() & (1 << 22))
+        m_features |= CPUFeature::RDPID;
+    if (extended_features.ecx() & (1 << 23))
+        m_features |= CPUFeature::KL;
+    if (extended_features.ecx() & (1 << 25))
+        m_features |= CPUFeature::CLDEMOTE;
+    if (extended_features.ecx() & (1 << 27))
+        m_features |= CPUFeature::MOVDIRI;
+    if (extended_features.ecx() & (1 << 28))
+        m_features |= CPUFeature::MOVDIR64B;
+    if (extended_features.ecx() & (1 << 29))
+        m_features |= CPUFeature::ENQCMD;
+    if (extended_features.ecx() & (1 << 30))
+        m_features |= CPUFeature::SGX_LC;
+    if (extended_features.ecx() & (1 << 31))
+        m_features |= CPUFeature::PKS;
+
+    if (extended_features.edx() & (1 << 2))
+        m_features |= CPUFeature::AVX512_4VNNIW;
+    if (extended_features.edx() & (1 << 3))
+        m_features |= CPUFeature::AVX512_4FMAPS;
+    if (extended_features.edx() & (1 << 4))
+        m_features |= CPUFeature::FSRM;
+    if (extended_features.edx() & (1 << 8))
+        m_features |= CPUFeature::AVX512_VP2INTERSECT;
+    if (extended_features.edx() & (1 << 9))
+        m_features |= CPUFeature::SRBDS_CTRL;
+    if (extended_features.edx() & (1 << 10))
+        m_features |= CPUFeature::MD_CLEAR;
+    if (extended_features.edx() & (1 << 11))
+        m_features |= CPUFeature::RTM_ALWAYS_ABORT;
+    if (extended_features.edx() & (1 << 13))
+        m_features |= CPUFeature::TSX_FORCE_ABORT;
+    if (extended_features.edx() & (1 << 14))
+        m_features |= CPUFeature::SERIALIZE;
+    if (extended_features.edx() & (1 << 15))
+        m_features |= CPUFeature::HYBRID;
+    if (extended_features.edx() & (1 << 16))
+        m_features |= CPUFeature::TSXLDTRK;
+    if (extended_features.edx() & (1 << 18))
+        m_features |= CPUFeature::PCONFIG;
+    if (extended_features.edx() & (1 << 19))
+        m_features |= CPUFeature::LBR;
+    if (extended_features.edx() & (1 << 20))
+        m_features |= CPUFeature::CET_IBT;
+    if (extended_features.edx() & (1 << 22))
+        m_features |= CPUFeature::AMX_BF16;
+    if (extended_features.edx() & (1 << 23))
+        m_features |= CPUFeature::AVX512_FP16;
+    if (extended_features.edx() & (1 << 24))
+        m_features |= CPUFeature::AMX_TILE;
+    if (extended_features.edx() & (1 << 25))
+        m_features |= CPUFeature::AMX_INT8;
+    if (extended_features.edx() & (1 << 26))
+        m_features |= CPUFeature::SPEC_CTRL;
+    if (extended_features.edx() & (1 << 27))
+        m_features |= CPUFeature::STIBP;
+    if (extended_features.edx() & (1 << 28))
+        m_features |= CPUFeature::L1D_FLUSH;
+    if (extended_features.edx() & (1 << 29))
+        m_features |= CPUFeature::IA32_ARCH_CAPABILITIES;
+    if (extended_features.edx() & (1 << 30))
+        m_features |= CPUFeature::IA32_CORE_CAPABILITIES;
+    if (extended_features.edx() & (1 << 31))
+        m_features |= CPUFeature::SSBD;
 
     u32 max_extended_leaf = CPUID(0x80000000).eax();