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,