static void x86_cpu_load_features(X86CPU *cpu, Error **errp) { CPUX86State *env = &cpu->env; FeatureWord w; GList *l; Error *local_err = NULL; /*TODO: cpu->max_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->max_features) { for (w = 0; w < FEATURE_WORDS; w++) { env->features[w] = x86_cpu_get_supported_feature_word(w, cpu->migratable); } } for (l = plus_features; l; l = l->next) { const char *prop = l->data; object_property_set_bool(OBJECT(cpu), true, prop, &local_err); if (local_err) { goto out; } } for (l = minus_features; l; l = l->next) { const char *prop = l->data; object_property_set_bool(OBJECT(cpu), false, prop, &local_err); if (local_err) { goto out; } } if (!kvm_enabled() || !cpu->expose_kvm) { env->features[FEAT_KVM] = 0; } x86_cpu_enable_xsave_components(cpu); /* CPUID[EAX=7,ECX=0].EBX always increased level automatically: */ x86_cpu_adjust_feat_level(cpu, FEAT_7_0_EBX); if (cpu->full_cpuid_auto_level) { x86_cpu_adjust_feat_level(cpu, FEAT_1_EDX); x86_cpu_adjust_feat_level(cpu, FEAT_1_ECX); x86_cpu_adjust_feat_level(cpu, FEAT_6_EAX); x86_cpu_adjust_feat_level(cpu, FEAT_7_0_ECX); x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_EDX); x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_ECX); x86_cpu_adjust_feat_level(cpu, FEAT_8000_0007_EDX); x86_cpu_adjust_feat_level(cpu, FEAT_C000_0001_EDX); x86_cpu_adjust_feat_level(cpu, FEAT_SVM); x86_cpu_adjust_feat_level(cpu, FEAT_XSAVE); /* SVM requires CPUID[0x8000000A] */ if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) { x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A); } } /* Set cpuid_*level* based on cpuid_min_*level, if not explicitly set */ if (env->cpuid_level == UINT32_MAX) { env->cpuid_level = env->cpuid_min_level; } if (env->cpuid_xlevel == UINT32_MAX) { env->cpuid_xlevel = env->cpuid_min_xlevel; } if (env->cpuid_xlevel2 == UINT32_MAX) { env->cpuid_xlevel2 = env->cpuid_min_xlevel2; } out: if (local_err != NULL) { error_propagate(errp, local_err); } }
static void x86_cpu_load_features(X86CPU *cpu, Error **errp) { CPUX86State *env = &cpu->env; FeatureWord w; GList *l; Error *local_err = NULL;   if (cpu->max_features) { for (w = 0; w < FEATURE_WORDS; w++) { env->features[w] = x86_cpu_get_supported_feature_word(w, cpu->migratable); } } for (l = plus_features; l; l = l->next) { const char *prop = l->data; object_property_set_bool(OBJECT(cpu), true, prop, &local_err); if (local_err) { goto out; } } for (l = minus_features; l; l = l->next) { const char *prop = l->data; object_property_set_bool(OBJECT(cpu), false, prop, &local_err); if (local_err) { goto out; } } if (!kvm_enabled() || !cpu->expose_kvm) { env->features[FEAT_KVM] = 0; } x86_cpu_enable_xsave_components(cpu);   x86_cpu_adjust_feat_level(cpu, FEAT_7_0_EBX); if (cpu->full_cpuid_auto_level) { x86_cpu_adjust_feat_level(cpu, FEAT_1_EDX); x86_cpu_adjust_feat_level(cpu, FEAT_1_ECX); x86_cpu_adjust_feat_level(cpu, FEAT_6_EAX); x86_cpu_adjust_feat_level(cpu, FEAT_7_0_ECX); x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_EDX); x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_ECX); x86_cpu_adjust_feat_level(cpu, FEAT_8000_0007_EDX); x86_cpu_adjust_feat_level(cpu, FEAT_C000_0001_EDX); x86_cpu_adjust_feat_level(cpu, FEAT_SVM); x86_cpu_adjust_feat_level(cpu, FEAT_XSAVE);   if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) { x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A); } }   if (env->cpuid_level == UINT32_MAX) { env->cpuid_level = env->cpuid_min_level; } if (env->cpuid_xlevel == UINT32_MAX) { env->cpuid_xlevel = env->cpuid_min_xlevel; } if (env->cpuid_xlevel2 == UINT32_MAX) { env->cpuid_xlevel2 = env->cpuid_min_xlevel2; } out: if (local_err != NULL) { error_propagate(errp, local_err); } }