Commit 58cbaf64 authored by Zhao Liu's avatar Zhao Liu Committed by Sean Christopherson
Browse files

KVM: x86: Advertise AMX CPUIDs in subleaf 0x1E.0x1 to userspace



Define and advertise AMX CPUIDs (0x1E.0x1) to userspace when the leaf is
supported by the host.

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
aliaseed positions of existing AMX feature bits distributed across the
0x7 leaves. To avoid duplicate feature names, name these aliases with an
*_ALIAS 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: default avatarXudong Hao <xudong.hao@intel.com>
Signed-off-by: default avatarZhao Liu <zhao1.liu@intel.com>
Reviewed-by: default avatarXiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Link: https://patch.msgid.link/20251120050720.931449-3-zhao1.liu@intel.com


Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent f24ef009
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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,
+25 −0
Original line number Diff line number Diff line
@@ -1067,6 +1067,17 @@ void kvm_set_cpu_caps(void)
		SCATTERED_F(SGX_EDECCSSA),
	);

	kvm_cpu_cap_init(CPUID_1E_1_EAX,
		F(AMX_INT8_ALIAS),
		F(AMX_BF16_ALIAS),
		F(AMX_COMPLEX_ALIAS),
		F(AMX_FP16_ALIAS),
		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),
@@ -1627,6 +1638,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;
+15 −0
Original line number Diff line number Diff line
@@ -44,6 +44,20 @@
#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).  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)
#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)
@@ -90,6 +104,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},
};

/*