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 <xudong.hao@intel.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
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
On Thu, Nov 20, 2025, Zhao Liu wrote: > Define and pass AMX CPUIDs (0x1E.0x1) through to userspace. Similar to the PASSTHROUGH_F() thing in the first patch, these aren't strictly being passed through. In practice, they are passed through as of the current code base due to the features residing in KVM-only words, but I'd like to avoid stating that features are being passed through unless KVM very deliberately wants to ignore the kernel. As before, I'll tweak when applying. Same goes for patches 3 and 4.
On Fri, Jan 23, 2026 at 10:06:32AM -0800, Sean Christopherson wrote: > Date: Fri, 23 Jan 2026 10:06:32 -0800 > From: Sean Christopherson <seanjc@google.com> > Subject: Re: [PATCH 2/4] KVM: x86: Advertise AMX CPUIDs in subleaf 0x1E.0x1 > to userspace > > On Thu, Nov 20, 2025, Zhao Liu wrote: > > Define and pass AMX CPUIDs (0x1E.0x1) through to userspace. > > Similar to the PASSTHROUGH_F() thing in the first patch, these aren't strictly > being passed through. In practice, they are passed through as of the current > code base due to the features residing in KVM-only words, but I'd like to avoid > stating that features are being passed through unless KVM very deliberately wants > to ignore the kernel. Good point, thanks for your reminder! > As before, I'll tweak when applying. Same goes for patches 3 and 4. Thanks! -Zhao
On Thu, Nov 20, 2025, Zhao Liu wrote: > 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 */ Unless someone feels *very* strongly about the "mirror" terminology, I'm going to use ALIAS instead of MIRROR when applying, to match KVM's existing terminology for the 8000_0001.EDX => 1.EDX aliases. /* * Intel-defined sub-features, CPUID level 0x0000001E:1 (EAX). Note, several * of the bits are aliases to features of the same name that are enumerated via * various CPUID.0x7 sub-leafs. */ #define X86_FEATURE_AMX_INT8_ALIAS KVM_X86_FEATURE(CPUID_1E_1_EAX, 0) #define X86_FEATURE_AMX_BF16_ALIAS KVM_X86_FEATURE(CPUID_1E_1_EAX, 1) #define X86_FEATURE_AMX_COMPLEX_ALIAS KVM_X86_FEATURE(CPUID_1E_1_EAX, 2) #define X86_FEATURE_AMX_FP16_ALIAS KVM_X86_FEATURE(CPUID_1E_1_EAX, 3)
> Unless someone feels *very* strongly about the "mirror" terminology, I'm going to > use ALIAS instead of MIRROR when applying, to match KVM's existing terminology for > the 8000_0001.EDX => 1.EDX aliases. > > /* > * Intel-defined sub-features, CPUID level 0x0000001E:1 (EAX). Note, several > * of the bits are aliases to features of the same name that are enumerated via > * various CPUID.0x7 sub-leafs. > */ > #define X86_FEATURE_AMX_INT8_ALIAS KVM_X86_FEATURE(CPUID_1E_1_EAX, 0) > #define X86_FEATURE_AMX_BF16_ALIAS KVM_X86_FEATURE(CPUID_1E_1_EAX, 1) > #define X86_FEATURE_AMX_COMPLEX_ALIAS KVM_X86_FEATURE(CPUID_1E_1_EAX, 2) > #define X86_FEATURE_AMX_FP16_ALIAS KVM_X86_FEATURE(CPUID_1E_1_EAX, 3) LGTM, yes, ALIAS sounds better than MIRROR. Thanks, Zhao
On 11/20/2025 1:07 PM, Zhao Liu wrote: > 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. It looks that KVM can emulate the mirroring CPUIDs regardless of whether hardware supports subleaf 1. However, given such emulation provides no real benefit but complicates KVM implementation, this patch looks good to me.
On Fri, Jan 23, 2026, Xiaoyao Li wrote: > On 11/20/2025 1:07 PM, Zhao Liu wrote: > > 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. > > It looks that KVM can emulate the mirroring CPUIDs regardless of whether > hardware supports subleaf 1. However, given such emulation provides no real > benefit but complicates KVM implementation, this patch looks good to me. Yeah, and it would run the risk of guest software doing stupid things like assuming a certain CPU generation if the leaf is supported.
© 2016 - 2026 Red Hat, Inc.