From 5a853fc57a0860da4a55d1448a77845f97e7a9be Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Mon, 22 Apr 2019 20:47:41 -0300 Subject: [PATCH 1/3] i386: x86_cpu_list_feature_names() function Extract feature name listing code from x86_cpu_class_check_missing_features(). It will be reused to return information about CPU filtered features at runtime. Message-Id: <20190422234742.15780-2-ehabkost@redhat.com> Signed-off-by: Eduardo Habkost --- target/i386/cpu.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index b21ecaac17..36589adb1f 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -3671,6 +3671,27 @@ 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); +/* Build a list with the name of all features on a feature word array */ +static void x86_cpu_list_feature_names(FeatureWordArray features, + strList **feat_names) +{ + FeatureWord w; + strList **next = feat_names; + + for (w = 0; w < FEATURE_WORDS; w++) { + uint32_t filtered = features[w]; + int i; + for (i = 0; i < 32; i++) { + if (filtered & (1UL << i)) { + strList *new = g_new0(strList, 1); + new->value = g_strdup(x86_cpu_feature_name(w, i)); + *next = new; + next = &new->next; + } + } + } +} + /* Check for missing features that may prevent the CPU class from * running using the current machine and accelerator. */ @@ -3678,7 +3699,6 @@ static void x86_cpu_class_check_missing_features(X86CPUClass *xcc, strList **missing_feats) { X86CPU *xc; - FeatureWord w; Error *err = NULL; strList **next = missing_feats; @@ -3705,18 +3725,7 @@ static void x86_cpu_class_check_missing_features(X86CPUClass *xcc, x86_cpu_filter_features(xc); - for (w = 0; w < FEATURE_WORDS; w++) { - uint32_t filtered = xc->filtered_features[w]; - int i; - for (i = 0; i < 32; i++) { - if (filtered & (1UL << i)) { - strList *new = g_new0(strList, 1); - new->value = g_strdup(x86_cpu_feature_name(w, i)); - *next = new; - next = &new->next; - } - } - } + x86_cpu_list_feature_names(xc->filtered_features, next); object_unref(OBJECT(xc)); } From 506174bf8219dc6d56d2b1f7e66e8cf39157466f Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Mon, 22 Apr 2019 20:47:42 -0300 Subject: [PATCH 2/3] i386: "unavailable-features" QOM property Add a "unavailable-features" QOM property to X86CPU objects that have the same semantics of "unavailable-features" on query-cpu-definitions. The new property has the same goal of "filtered-features", but is generic enough to let any kind of CPU feature to be listed there without relying on low level details like CPUID leaves or MSR numbers. Message-Id: <20190422234742.15780-3-ehabkost@redhat.com> Signed-off-by: Eduardo Habkost --- target/i386/cpu.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 36589adb1f..7e5b545005 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -3692,6 +3692,17 @@ static void x86_cpu_list_feature_names(FeatureWordArray features, } } +static void x86_cpu_get_unavailable_features(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + X86CPU *xc = X86_CPU(obj); + strList *result = NULL; + + x86_cpu_list_feature_names(xc->filtered_features, &result); + visit_type_strList(v, "unavailable-features", &result, errp); +} + /* Check for missing features that may prevent the CPU class from * running using the current machine and accelerator. */ @@ -5632,6 +5643,15 @@ static void x86_cpu_initfn(Object *obj) object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo", x86_cpu_get_feature_words, NULL, NULL, (void *)cpu->filtered_features, NULL); + /* + * The "unavailable-features" property has the same semantics as + * CpuDefinitionInfo.unavailable-features on the "query-cpu-definitions" + * QMP command: they list the features that would have prevented the + * CPU from running if the "enforce" flag was set. + */ + object_property_add(obj, "unavailable-features", "strList", + x86_cpu_get_unavailable_features, + NULL, NULL, NULL, &error_abort); object_property_add(obj, "crash-information", "GuestPanicInformation", x86_cpu_get_crash_info_qom, NULL, NULL, NULL, NULL); From 89a44a103315267122119b4311218d00d2561ebe Mon Sep 17 00:00:00 2001 From: Pavel Dovgalyuk Date: Wed, 29 May 2019 15:41:56 +0300 Subject: [PATCH 3/3] i386: Save EFER for 32-bit targets i386 (32 bit) emulation uses EFER in wrmsr and in MMU fault processing. But it does not included in VMState, because "efer" field is disabled with This patch adds a section for 32-bit targets which saves EFER when it's value is non-zero. Signed-off-by: Pavel Dovgalyuk Message-Id: <155913371654.8429.1659082639780315242.stgit@pasha-Precision-3630-Tower> Reviewed-by: Peter Xu [ehabkost: indentation fix] Signed-off-by: Eduardo Habkost --- target/i386/machine.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/target/i386/machine.c b/target/i386/machine.c index 225b5d433b..2c96cfc9a2 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -964,6 +964,27 @@ static const VMStateDescription vmstate_svm_npt = { } }; +#ifndef TARGET_X86_64 +static bool intel_efer32_needed(void *opaque) +{ + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; + + return env->efer != 0; +} + +static const VMStateDescription vmstate_efer32 = { + .name = "cpu/efer32", + .version_id = 1, + .minimum_version_id = 1, + .needed = intel_efer32_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT64(env.efer, X86CPU), + VMSTATE_END_OF_LIST() + } +}; +#endif + VMStateDescription vmstate_x86_cpu = { .name = "cpu", .version_id = 12, @@ -1089,6 +1110,9 @@ VMStateDescription vmstate_x86_cpu = { &vmstate_msr_intel_pt, &vmstate_msr_virt_ssbd, &vmstate_svm_npt, +#ifndef TARGET_X86_64 + &vmstate_efer32, +#endif NULL } };