diff options
author | Igor Mammedov <imammedo@redhat.com> | 2016-06-06 17:16:44 +0200 |
---|---|---|
committer | Eduardo Habkost <ehabkost@redhat.com> | 2016-06-14 16:17:09 -0300 |
commit | dc15c0517b010a9444a2c05794dae980f2a2cbd9 (patch) | |
tree | 8e40faa2dfd7499aa6bde438647561181c516f1d /target-i386 | |
parent | c19b85216b5d47d922ac010931d4c7b2d79b2f68 (diff) |
target-i386: Move features logic that requires CPUState to realize time
Making x86_cpu_parse_featurestr() a pure convertor
of legacy feature string into global properties, needs
it to be called before a CPU instance is created so
parser shouldn't modify CPUState directly or access
it at all. Hence move current hack that directly pokes
into CPUState, to set/unset +-feats, from parser to
CPU's realize method.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Diffstat (limited to 'target-i386')
-rw-r--r-- | target-i386/cpu.c | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/target-i386/cpu.c b/target-i386/cpu.c index a62d731af4..647cd307ff 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -1940,6 +1940,14 @@ static inline void feat2prop(char *s) } } +/* Compatibily hack to maintain legacy +-feat semantic, + * where +-feat overwrites any feature set by + * feat=on|feat even if the later is parsed after +-feat + * (i.e. "-x2apic,x2apic=on" will result in x2apic disabled) + */ +static FeatureWordArray plus_features = { 0 }; +static FeatureWordArray minus_features = { 0 }; + /* Parse "+feature,-feature,feature=foo" CPU feature string */ static void x86_cpu_parse_featurestr(CPUState *cs, char *features, @@ -1947,12 +1955,6 @@ static void x86_cpu_parse_featurestr(CPUState *cs, char *features, { X86CPU *cpu = X86_CPU(cs); char *featurestr; /* Single 'key=value" string being parsed */ - FeatureWord w; - /* Features to be added */ - FeatureWordArray plus_features = { 0 }; - /* Features to be removed */ - FeatureWordArray minus_features = { 0 }; - CPUX86State *env = &cpu->env; Error *local_err = NULL; featurestr = features ? strtok(features, ",") : NULL; @@ -1993,18 +1995,6 @@ static void x86_cpu_parse_featurestr(CPUState *cs, char *features, } featurestr = strtok(NULL, ","); } - - if (cpu->host_features) { - for (w = 0; w < FEATURE_WORDS; w++) { - env->features[w] = - x86_cpu_get_supported_feature_word(w, cpu->migratable); - } - } - - for (w = 0; w < FEATURE_WORDS; w++) { - env->features[w] |= plus_features[w]; - env->features[w] &= ~minus_features[w]; - } } /* Print all cpuid feature names in featureset @@ -2916,12 +2906,30 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) CPUX86State *env = &cpu->env; Error *local_err = NULL; static bool ht_warned; + FeatureWord w; if (cpu->apic_id < 0) { error_setg(errp, "apic-id property was not initialized properly"); return; } + /*TODO: cpu->host_features incorrectly overwrites features + * set using "feat=on|off". Once we fix this, we can convert + * plus_features & minus_features to global properties + * inside x86_cpu_parse_featurestr() too. + */ + if (cpu->host_features) { + for (w = 0; w < FEATURE_WORDS; w++) { + env->features[w] = + x86_cpu_get_supported_feature_word(w, cpu->migratable); + } + } + + for (w = 0; w < FEATURE_WORDS; w++) { + cpu->env.features[w] |= plus_features[w]; + cpu->env.features[w] &= ~minus_features[w]; + } + if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) { env->cpuid_level = 7; } |