From d7362c761ef55b7f665c4dff61d9e58b153ff11c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 22 Nov 2019 11:53:39 +0000 Subject: [PATCH 06/16] target/i386: handle filtered_features in a new function mark_unavailable_features RH-Author: Paolo Bonzini Message-id: <20191122115348.25000-7-pbonzini@redhat.com> Patchwork-id: 92600 O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 06/15] target/i386: handle filtered_features in a new function mark_unavailable_features Bugzilla: 1689270 RH-Acked-by: Dr. David Alan Gilbert RH-Acked-by: Eduardo Habkost RH-Acked-by: Maxim Levitsky The next patch will add a different reason for filtering features, unrelated to host feature support. Extract a new function that takes care of disabling the features and optionally reporting them. Signed-off-by: Paolo Bonzini (cherry picked from commit 245edd0cfb1481b7a0398cce45df23db50f00034) Signed-off-by: Danilo C. L. de Paula --- target/i386/cpu.c | 87 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 39 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index d0c48c2..b06ce9d 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -3121,17 +3121,41 @@ static char *feature_word_description(FeatureWordInfo *f, uint32_t bit) return NULL; } -static void report_unavailable_features(FeatureWord w, uint32_t mask) +static bool x86_cpu_have_filtered_features(X86CPU *cpu) { + FeatureWord w; + + for (w = 0; w < FEATURE_WORDS; w++) { + if (cpu->filtered_features[w]) { + return true; + } + } + + return false; +} + +static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint32_t mask, + const char *verbose_prefix) +{ + CPUX86State *env = &cpu->env; FeatureWordInfo *f = &feature_word_info[w]; int i; char *feat_word_str; + if (!cpu->force_features) { + env->features[w] &= ~mask; + } + cpu->filtered_features[w] |= mask; + + if (!verbose_prefix) { + return; + } + for (i = 0; i < 32; ++i) { if ((1UL << i) & mask) { feat_word_str = feature_word_description(f, i); - warn_report("%s doesn't support requested feature: %s%s%s [bit %d]", - accel_uses_host_cpuid() ? "host" : "TCG", + warn_report("%s: %s%s%s [bit %d]", + verbose_prefix, feat_word_str, f->feat_names[i] ? "." : "", f->feat_names[i] ? f->feat_names[i] : "", i); @@ -3577,7 +3601,7 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features, } static void x86_cpu_expand_features(X86CPU *cpu, Error **errp); -static int x86_cpu_filter_features(X86CPU *cpu); +static void x86_cpu_filter_features(X86CPU *cpu, bool verbose); /* Build a list with the name of all features on a feature word array */ static void x86_cpu_list_feature_names(FeatureWordArray features, @@ -3642,7 +3666,7 @@ static void x86_cpu_class_check_missing_features(X86CPUClass *xcc, next = &new->next; } - x86_cpu_filter_features(xc); + x86_cpu_filter_features(xc, false); x86_cpu_list_feature_names(xc->filtered_features, next); @@ -3811,15 +3835,6 @@ static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w, return r; } -static void x86_cpu_report_filtered_features(X86CPU *cpu) -{ - FeatureWord w; - - for (w = 0; w < FEATURE_WORDS; w++) { - report_unavailable_features(w, cpu->filtered_features[w]); - } -} - static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props) { PropValue *pv; @@ -5042,24 +5057,24 @@ out: * * Returns: 0 if all flags are supported by the host, non-zero otherwise. */ -static int x86_cpu_filter_features(X86CPU *cpu) +static void x86_cpu_filter_features(X86CPU *cpu, bool verbose) { CPUX86State *env = &cpu->env; FeatureWord w; - int rv = 0; + const char *prefix = NULL; + + if (verbose) { + prefix = accel_uses_host_cpuid() + ? "host doesn't support requested feature" + : "TCG doesn't support requested feature"; + } for (w = 0; w < FEATURE_WORDS; w++) { uint32_t host_feat = x86_cpu_get_supported_feature_word(w, false); uint32_t requested_features = env->features[w]; - uint32_t available_features = requested_features & host_feat; - if (!cpu->force_features) { - env->features[w] = available_features; - } - cpu->filtered_features[w] = requested_features & ~available_features; - if (cpu->filtered_features[w]) { - rv = 1; - } + uint32_t unavailable_features = requested_features & ~host_feat; + mark_unavailable_features(cpu, w, unavailable_features, prefix); } if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) && @@ -5085,13 +5100,9 @@ static int x86_cpu_filter_features(X86CPU *cpu) * host can't emulate the capabilities we report on * cpu_x86_cpuid(), intel-pt can't be enabled on the current host. */ - env->features[FEAT_7_0_EBX] &= ~CPUID_7_0_EBX_INTEL_PT; - cpu->filtered_features[FEAT_7_0_EBX] |= CPUID_7_0_EBX_INTEL_PT; - rv = 1; + mark_unavailable_features(cpu, FEAT_7_0_EBX, CPUID_7_0_EBX_INTEL_PT, prefix); } } - - return rv; } static void x86_cpu_realizefn(DeviceState *dev, Error **errp) @@ -5120,16 +5131,14 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) goto out; } - if (x86_cpu_filter_features(cpu) && - (cpu->check_cpuid || cpu->enforce_cpuid)) { - x86_cpu_report_filtered_features(cpu); - if (cpu->enforce_cpuid) { - error_setg(&local_err, - accel_uses_host_cpuid() ? - "Host doesn't support requested features" : - "TCG doesn't support requested features"); - goto out; - } + x86_cpu_filter_features(cpu, cpu->check_cpuid || cpu->enforce_cpuid); + + if (cpu->enforce_cpuid && x86_cpu_have_filtered_features(cpu)) { + error_setg(&local_err, + accel_uses_host_cpuid() ? + "Host doesn't support requested features" : + "TCG doesn't support requested features"); + goto out; } /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on -- 1.8.3.1