diff --git a/qemu/target/i386/cpu.c b/qemu/target/i386/cpu.c index 952c256b..e1b2c27b 100644 --- a/qemu/target/i386/cpu.c +++ b/qemu/target/i386/cpu.c @@ -3111,15 +3111,19 @@ static void x86_cpu_expand_features(struct uc_struct *uc, X86CPU *cpu, Error **e FeatureWord w; Error *local_err = NULL; - /*TODO: cpu->max_features incorrectly overwrites features - * set using "feat=on|off". Once we fix this, we can convert + /*TODO: Now cpu->max_features doesn't overwrite features + * set using QOM properties, and we can convert * plus_features & minus_features to global properties * inside x86_cpu_parse_featurestr() too. */ if (cpu->max_features) { for (w = 0; w < FEATURE_WORDS; w++) { - env->features[w] = - x86_cpu_get_supported_feature_word(uc, w, cpu->migratable); + /* Override only features that weren't set explicitly + * by the user. + */ + env->features[w] |= + x86_cpu_get_supported_feature_word(uc, w, cpu->migratable) & + ~env->user_features[w]; } } diff --git a/qemu/target/i386/cpu.h b/qemu/target/i386/cpu.h index ff56baf6..f6eee187 100644 --- a/qemu/target/i386/cpu.h +++ b/qemu/target/i386/cpu.h @@ -1133,6 +1133,8 @@ typedef struct CPUX86State { uint32_t cpuid_version; FeatureWordArray features; uint64_t xsave_components; + /* Features that were explicitly enabled/disabled */ + FeatureWordArray user_features; uint32_t cpuid_model[12]; /* MTRRs */