Add the "lbr-pmc-freeze" CPU feature (CPUID 0x80000022.EAX[2]), which lets a guest freeze the LBR stack and performance counters on a PMI. As it operates on the LBR v2 stack, make it depend on lbrext-v2. Signed-off-by: Shivansh Dhiman --- target/i386/cpu.c | 10 +++++++++- target/i386/cpu.h | 5 +++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 678863de68d5..b22a2a9314ac 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", "lbrext-v2", NULL, NULL, + "perfmon-v2", "lbrext-v2", "lbr-pmc-freeze", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -2048,6 +2048,10 @@ static FeatureDep feature_dependencies[] = { .from = { FEAT_8000_0022_EAX, CPUID_8000_0022_EAX_PERFMON_V2 }, .to = { FEAT_8000_0022_EAX, CPUID_8000_0022_EAX_LBREXT_V2 }, }, + { + .from = { FEAT_8000_0022_EAX, CPUID_8000_0022_EAX_LBREXT_V2 }, + .to = { FEAT_8000_0022_EAX, CPUID_8000_0022_EAX_LBR_PMC_FREEZE }, + }, }; typedef struct X86RegisterInfo32 { @@ -9156,6 +9160,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *ebx |= kvm_arch_get_supported_cpuid(cs->kvm_state, index, count, R_EBX) & 0x3f0; /* EBX[9:4] */ } + /* Dependency LBREXT_V2 => LBRPMC_FREEZE enforced via feature_dependencies[] */ + if (env->features[FEAT_8000_0022_EAX] & CPUID_8000_0022_EAX_LBR_PMC_FREEZE) { + *eax |= CPUID_8000_0022_EAX_LBR_PMC_FREEZE; + } break; case 0xC0000000: *eax = env->cpuid_xlevel2; diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 64e40a654260..c8f51531ba85 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1220,8 +1220,9 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); #define CPUID_8000_0021_ECX_TSA_L1_NO (1U << 2) /* Performance Monitoring Version 2 */ -#define CPUID_8000_0022_EAX_PERFMON_V2 (1U << 0) -#define CPUID_8000_0022_EAX_LBREXT_V2 (1U << 1) +#define CPUID_8000_0022_EAX_PERFMON_V2 (1U << 0) +#define CPUID_8000_0022_EAX_LBREXT_V2 (1U << 1) +#define CPUID_8000_0022_EAX_LBR_PMC_FREEZE (1U << 2) #define CPUID_XSAVE_XSAVEOPT (1U << 0) #define CPUID_XSAVE_XSAVEC (1U << 1) -- 2.43.0