[PATCH 2/4] KVM: x86: Advertise AMX CPUIDs in subleaf 0x1E.0x1 to userspace

Zhao Liu posted 4 patches 2 months, 2 weeks ago
[PATCH 2/4] KVM: x86: Advertise AMX CPUIDs in subleaf 0x1E.0x1 to userspace
Posted by Zhao Liu 2 months, 2 weeks ago
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
Re: [PATCH 2/4] KVM: x86: Advertise AMX CPUIDs in subleaf 0x1E.0x1 to userspace
Posted by Sean Christopherson 2 weeks ago
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.
Re: [PATCH 2/4] KVM: x86: Advertise AMX CPUIDs in subleaf 0x1E.0x1 to userspace
Posted by Zhao Liu 1 week, 5 days ago
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
Re: [PATCH 2/4] KVM: x86: Advertise AMX CPUIDs in subleaf 0x1E.0x1 to userspace
Posted by Sean Christopherson 2 weeks ago
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)
Re: [PATCH 2/4] KVM: x86: Advertise AMX CPUIDs in subleaf 0x1E.0x1 to userspace
Posted by Zhao Liu 1 week, 5 days ago
> 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
Re: [PATCH 2/4] KVM: x86: Advertise AMX CPUIDs in subleaf 0x1E.0x1 to userspace
Posted by Xiaoyao Li 2 weeks ago
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.
Re: [PATCH 2/4] KVM: x86: Advertise AMX CPUIDs in subleaf 0x1E.0x1 to userspace
Posted by Sean Christopherson 2 weeks ago
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.