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 <[email protected]>
---
 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


Reply via email to