Add the "lbrext-v2" CPU feature (CPUID 0x80000022.EAX[1]) and report the 16-entry LBR stack size in EBX[9:4], allowing guests to use AMD's Last Branch Record Extension v2 when KVM virtualizes it.
Signed-off-by: Shivansh Dhiman <[email protected]> --- target/i386/cpu.c | 18 +++++++++++++++--- target/i386/cpu.h | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 9d126600c057..678863de68d5 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -1464,7 +1464,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { [FEAT_8000_0022_EAX] = { .type = CPUID_FEATURE_WORD, .feat_names = { - "perfmon-v2", NULL, NULL, NULL, + "perfmon-v2", "lbrext-v2", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -2044,6 +2044,10 @@ static FeatureDep feature_dependencies[] = { .from = { FEAT_7_1_EAX, CPUID_7_1_EAX_FRED }, .to = { FEAT_VMX_ENTRY_CTLS, VMX_VM_ENTRY_LOAD_IA32_FRED }, }, + { + .from = { FEAT_8000_0022_EAX, CPUID_8000_0022_EAX_PERFMON_V2 }, + .to = { FEAT_8000_0022_EAX, CPUID_8000_0022_EAX_LBREXT_V2 }, + }, }; typedef struct X86RegisterInfo32 { @@ -9138,12 +9142,20 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, case 0x80000022: *eax = *ebx = *ecx = *edx = 0; /* AMD Extended Performance Monitoring and Debug */ - if (kvm_enabled() && cpu->enable_pmu && - (env->features[FEAT_8000_0022_EAX] & CPUID_8000_0022_EAX_PERFMON_V2)) { + if (!kvm_enabled() || !cpu->enable_pmu) { + break; + } + if (env->features[FEAT_8000_0022_EAX] & CPUID_8000_0022_EAX_PERFMON_V2) { *eax |= CPUID_8000_0022_EAX_PERFMON_V2; *ebx |= kvm_arch_get_supported_cpuid(cs->kvm_state, index, count, R_EBX) & 0xf; } + /* Dependency PERFMON_V2 => LBREXT_V2 enforced via feature_dependencies[] */ + if (env->features[FEAT_8000_0022_EAX] & CPUID_8000_0022_EAX_LBREXT_V2) { + *eax |= CPUID_8000_0022_EAX_LBREXT_V2; + *ebx |= kvm_arch_get_supported_cpuid(cs->kvm_state, index, count, + R_EBX) & 0x3f0; /* EBX[9:4] */ + } break; case 0xC0000000: *eax = env->cpuid_xlevel2; diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 0b539155c409..64e40a654260 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1221,6 +1221,7 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); /* Performance Monitoring Version 2 */ #define CPUID_8000_0022_EAX_PERFMON_V2 (1U << 0) +#define CPUID_8000_0022_EAX_LBREXT_V2 (1U << 1) #define CPUID_XSAVE_XSAVEOPT (1U << 0) #define CPUID_XSAVE_XSAVEC (1U << 1) -- 2.43.0
