diff mbox series

[RESEND,2/2] target/i386: add kvm_exact_match_flags to FeatureWordInfo

Message ID 20210423022037.24733-2-like.xu@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series [RESEND,1/2] target/i386: add "-cpu, lbr-fmt=*" support to enable guest LBR | expand

Commit Message

Like Xu April 23, 2021, 2:20 a.m. UTC
Instead of hardcoding the PERF_CAPABILITIES rules in this loop,
this could become a FeatureWordInfo field. It would be very useful
for other features like intel-pt, where we need some bits to match
the host bits too.

Suggested-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Like Xu <like.xu@linux.intel.com>
---
 target/i386/cpu.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index eee6da3ad8..56a486b498 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -708,6 +708,8 @@  typedef struct FeatureWordInfo {
     uint64_t migratable_flags; /* Feature flags known to be migratable */
     /* Features that shouldn't be auto-enabled by "-cpu host" */
     uint64_t no_autoenable_flags;
+    /* Bits that must match host exactly when using KVM */
+    uint64_t kvm_exact_match_flags;
 } FeatureWordInfo;
 
 static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
@@ -1147,6 +1149,11 @@  static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
         .msr = {
             .index = MSR_IA32_PERF_CAPABILITIES,
         },
+        /*
+         * KVM is not able to emulate a VCPU with LBR_FMT different
+         * from the host, so LBR_FMT must match the host exactly.
+         */
+        .kvm_exact_match_flags = PERF_CAP_LBR_FMT,
     },
 
     [FEAT_VMX_PROCBASED_CTLS] = {
@@ -6623,16 +6630,18 @@  static void x86_cpu_filter_features(X86CPU *cpu, bool verbose)
     }
 
     for (w = 0; w < FEATURE_WORDS; w++) {
+        FeatureWordInfo *fi = &feature_word_info[w];
+        uint64_t match_flags = fi->kvm_exact_match_flags;
         uint64_t host_feat =
             x86_cpu_get_supported_feature_word(w, false);
         uint64_t requested_features = env->features[w];
         uint64_t unavailable_features = requested_features & ~host_feat;
-        if (kvm_enabled() && w == FEAT_PERF_CAPABILITIES &&
-            (requested_features & PERF_CAP_LBR_FMT)) {
-            if ((host_feat & PERF_CAP_LBR_FMT) !=
-                (requested_features & PERF_CAP_LBR_FMT)) {
-                unavailable_features |= PERF_CAP_LBR_FMT;
-            }
+        if (kvm_enabled() && match_flags) {
+            uint64_t mismatches = (requested_features & match_flags) &&
+                (requested_features ^ host_feat) & match_flags;
+            mark_unavailable_features(cpu, w,
+                mismatches, "feature doesn't match host");
+            unavailable_features &= ~match_flags;
         }
         mark_unavailable_features(cpu, w, unavailable_features, prefix);
     }