feat: kvm and qemu patches grouped by the detection each clears

This commit is contained in:
2026-09-06 00:14:56 +02:00
commit 2e5269995a
17 changed files with 1912 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
Subject: [PATCH] cpu-misc: (CPU model plumbing)
Targets VMAware check: (CPU model plumbing)
CPU feature-word plumbing and an upstream backport; not aimed at a check.
Applies to QEMU v11.1.1. Apply from the source root with:
patch -p1 < 08-cpu-misc.patch
---
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 5805d33..1b0203e 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1009,6 +1009,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
#define TCG_7_2_EDX_FEATURES 0
#define TCG_APM_FEATURES 0
#define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT
+#define TCG_6_ECX_FEATURES 0
#define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1)
/* missing:
CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */
@@ -1545,6 +1546,21 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
.cpuid = { .eax = 6, .reg = R_EAX, },
.tcg_features = TCG_6_EAX_FEATURES,
},
+ [FEAT_6_ECX] = {
+ .type = CPUID_FEATURE_WORD,
+ .feat_names = {
+ "aperfmperf", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ },
+ .cpuid = { .eax = 6, .reg = R_ECX, },
+ .tcg_features = TCG_6_ECX_FEATURES,
+ },
[FEAT_XSAVE_XCR0_LO] = {
.type = CPUID_FEATURE_WORD,
.cpuid = {
@@ -8778,7 +8794,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
/* Thermal and Power Leaf */
*eax = env->features[FEAT_6_EAX];
*ebx = 0;
- *ecx = 0;
+ *ecx = env->features[FEAT_6_ECX];
*edx = 0;
break;
case 7:
@@ -9809,6 +9825,7 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
x86_cpu_adjust_feat_level(cpu, FEAT_1_EDX);
x86_cpu_adjust_feat_level(cpu, FEAT_1_ECX);
x86_cpu_adjust_feat_level(cpu, FEAT_6_EAX);
+ x86_cpu_adjust_feat_level(cpu, FEAT_6_ECX);
x86_cpu_adjust_feat_level(cpu, FEAT_7_0_ECX);
x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EAX);
x86_cpu_adjust_feat_level(cpu, FEAT_7_1_ECX);
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index e6a1976..2a6dbbf 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -700,6 +700,7 @@ typedef enum FeatureWord {
FEAT_SVM, /* CPUID[8000_000A].EDX */
FEAT_XSAVE, /* CPUID[EAX=0xd,ECX=1].EAX */
FEAT_6_EAX, /* CPUID[6].EAX */
+ FEAT_6_ECX, /* CPUID[6].ECX */
FEAT_XSAVE_XCR0_LO, /* CPUID[EAX=0xd,ECX=0].EAX */
FEAT_XSAVE_XCR0_HI, /* CPUID[EAX=0xd,ECX=0].EDX */
FEAT_ARCH_CAPABILITIES,
@@ -1232,6 +1233,7 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w);
#define CPUID_XSAVE_XFD (1U << 4)
#define CPUID_6_EAX_ARAT (1U << 2)
+#define CPUID_6_ECX_APERFMPERF (1U << 0)
/* CPUID[0x80000007].EDX flags: */
#define CPUID_APM_INVTSC (1U << 8)
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 644c45f..6f6862e 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -499,6 +499,14 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
}
} else if (function == 6 && reg == R_EAX) {
ret |= CPUID_6_EAX_ARAT; /* safe to allow because of emulated APIC */
+ } else if (function == 6 && reg == R_ECX) {
+ if (enable_cpu_pm) {
+ int disable_exits = kvm_check_extension(s,
+ KVM_CAP_X86_DISABLE_EXITS);
+ if (disable_exits & KVM_X86_DISABLE_EXITS_APERFMPERF) {
+ ret |= CPUID_6_ECX_APERFMPERF;
+ }
+ }
} else if (function == 7 && index == 0 && reg == R_EBX) {
/* Not new instructions, just an optimization. */
uint32_t ebx;
@@ -3292,7 +3300,8 @@ static int kvm_vm_enable_disable_exits(KVMState *s)
disable_exits &= (KVM_X86_DISABLE_EXITS_MWAIT |
KVM_X86_DISABLE_EXITS_HLT |
KVM_X86_DISABLE_EXITS_PAUSE |
- KVM_X86_DISABLE_EXITS_CSTATE);
+ KVM_X86_DISABLE_EXITS_CSTATE |
+ KVM_X86_DISABLE_EXITS_APERFMPERF);
}
return kvm_vm_enable_cap(s, KVM_CAP_X86_DISABLE_EXITS, 0,