Define and pass AMX CPUIDs (0x1E.0x1) through to userspace. Intel Diamond Rapids adds new AMX instructions to support new formats and memory operations [*], and introduces the CPUID subleaf 0x1E.0x1 to centralize the discrete AMX feature bits within EAX. Since these AMX features have no actual kernel usages, define them as KVM-only features in reverse_cpuid.h. In addition to the new features, CPUID 0x1E.0x1.EAX[bits 0-3] are mirrored positions of existing AMX feature bits distributed across the 0x7 leaves. To avoid duplicate feature names, name these mirror bits with a *_MIRROR suffix, and define them in reverse_cpuid.h as KVM-only features as well. Advertise new CPUID subleaf 0x1E.0x1 with its AMX CPUID feature bits to userspace for guest use. It's safe since no additional enabling work is needed in the host kernel. [*]: Intel Architecture Instruction Set Extensions and Future Features (rev.059). Tested-by: Xudong Hao Signed-off-by: Zhao Liu --- Reference link: https://cdrdv2.intel.com/v1/dl/getContent/865891 --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/cpuid.c | 25 +++++++++++++++++++++++++ arch/x86/kvm/reverse_cpuid.h | 11 +++++++++++ 3 files changed, 37 insertions(+) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 48598d017d6f..db7bf364f4fc 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -776,6 +776,7 @@ enum kvm_only_cpuid_leafs { CPUID_24_0_EBX, CPUID_8000_0021_ECX, CPUID_7_1_ECX, + CPUID_1E_1_EAX, NR_KVM_CPU_CAPS, NKVMCAPINTS = NR_KVM_CPU_CAPS - NCAPINTS, diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 372d82bae272..0795c9ecfd4b 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -1057,6 +1057,17 @@ void kvm_set_cpu_caps(void) SCATTERED_F(SGX_EDECCSSA), ); + kvm_cpu_cap_init(CPUID_1E_1_EAX, + F(AMX_INT8_MIRROR), + F(AMX_BF16_MIRROR), + F(AMX_COMPLEX_MIRROR), + F(AMX_FP16_MIRROR), + F(AMX_FP8), + F(AMX_TF32), + F(AMX_AVX512), + F(AMX_MOVRS), + ); + kvm_cpu_cap_init(CPUID_24_0_EBX, F(AVX10_128), F(AVX10_256), @@ -1616,6 +1627,20 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) entry->eax = entry->ebx = entry->ecx = entry->edx = 0; break; } + + max_idx = entry->eax = min(entry->eax, 1u); + + /* KVM only supports up to 0x1e.0x1, capped above via min(). */ + if (max_idx >= 1) { + entry = do_host_cpuid(array, function, 1); + if (!entry) + goto out; + + cpuid_entry_override(entry, CPUID_1E_1_EAX); + entry->ebx = 0; + entry->ecx = 0; + entry->edx = 0; + } break; case 0x24: { u8 avx10_version; diff --git a/arch/x86/kvm/reverse_cpuid.h b/arch/x86/kvm/reverse_cpuid.h index 743ab25ba787..99ec9e656655 100644 --- a/arch/x86/kvm/reverse_cpuid.h +++ b/arch/x86/kvm/reverse_cpuid.h @@ -44,6 +44,16 @@ #define KVM_X86_FEATURE_BHI_CTRL KVM_X86_FEATURE(CPUID_7_2_EDX, 4) #define X86_FEATURE_MCDT_NO KVM_X86_FEATURE(CPUID_7_2_EDX, 5) +/* Intel-defined sub-features, CPUID level 0x0000001E:1 (EAX) */ +#define X86_FEATURE_AMX_INT8_MIRROR KVM_X86_FEATURE(CPUID_1E_1_EAX, 0) /* Mirror of X86_FEATURE_AMX_INT8 */ +#define X86_FEATURE_AMX_BF16_MIRROR KVM_X86_FEATURE(CPUID_1E_1_EAX, 1) /* Mirror of X86_FEATURE_AMX_BF16 */ +#define X86_FEATURE_AMX_COMPLEX_MIRROR KVM_X86_FEATURE(CPUID_1E_1_EAX, 2) /* Mirror of X86_FEATURE_AMX_COMPLEX */ +#define X86_FEATURE_AMX_FP16_MIRROR KVM_X86_FEATURE(CPUID_1E_1_EAX, 3) /* Mirror of X86_FEATURE_AMX_FP16 */ +#define X86_FEATURE_AMX_FP8 KVM_X86_FEATURE(CPUID_1E_1_EAX, 4) +#define X86_FEATURE_AMX_TF32 KVM_X86_FEATURE(CPUID_1E_1_EAX, 6) +#define X86_FEATURE_AMX_AVX512 KVM_X86_FEATURE(CPUID_1E_1_EAX, 7) +#define X86_FEATURE_AMX_MOVRS KVM_X86_FEATURE(CPUID_1E_1_EAX, 8) + /* Intel-defined sub-features, CPUID level 0x00000024:0 (EBX) */ #define X86_FEATURE_AVX10_128 KVM_X86_FEATURE(CPUID_24_0_EBX, 16) #define X86_FEATURE_AVX10_256 KVM_X86_FEATURE(CPUID_24_0_EBX, 17) @@ -91,6 +101,7 @@ static const struct cpuid_reg reverse_cpuid[] = { [CPUID_24_0_EBX] = { 0x24, 0, CPUID_EBX}, [CPUID_8000_0021_ECX] = {0x80000021, 0, CPUID_ECX}, [CPUID_7_1_ECX] = { 7, 1, CPUID_ECX}, + [CPUID_1E_1_EAX] = { 0x1e, 1, CPUID_EAX}, }; /* -- 2.34.1