@@ -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);
}
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(-)