From: Eduardo Habkost <ehabkost@redhat.com>
To: qemu-devel@nongnu.org
Cc: Eric Blake <eblake@redhat.com>, Alexander Graf <agraf@suse.de>,
Richard Henderson <rth@twiddle.net>,
Paolo Bonzini <pbonzini@redhat.com>,
Markus Armbruster <armbru@redhat.com>,
Igor Mammedov <imammedo@redhat.com>,
Michael Roth <mdroth@linux.vnet.ibm.com>
Subject: [Qemu-devel] [PATCH 4/4] x86: Support feature=force on the command-line
Date: Tue, 2 May 2017 17:31:15 -0300 [thread overview]
Message-ID: <20170502203115.22233-5-ehabkost@redhat.com> (raw)
In-Reply-To: <20170502203115.22233-1-ehabkost@redhat.com>
Introduce a new CPUFeatureSetting QAPI data type, and use it to support
feature=force on -cpu.
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
qapi-schema.json | 32 +++++++++++++++++++++++++
target/i386/cpu.h | 2 ++
target/i386/cpu.c | 55 +++++++++++++++++++++++++++++++++----------
tests/test-x86-cpuid-compat.c | 14 ++++++++++-
4 files changed, 90 insertions(+), 13 deletions(-)
diff --git a/qapi-schema.json b/qapi-schema.json
index 01b087fa16..d716409114 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4250,6 +4250,38 @@
{ 'command': 'query-machines', 'returns': ['MachineInfo'] }
##
+# @CPUFeatureSettingEnum:
+#
+# Additional valid values for a CPUFeatureSetting property.
+#
+# @force: Force feature to be enabled, even if the accelerator
+# reports the feature as unavailable. Should be used only
+# for testing or debugging purposes.
+#
+# Since: 2.10
+##
+{ 'enum': 'CPUFeatureSettingEnum',
+ 'data': ['force'] }
+
+##
+# @CPUFeatureSetting:
+#
+# Values for a CPU feature property.
+#
+# @bool: If false, the feature is forcibly disabled.
+# If true, QEMU will try to enable the feature. QEMU will
+# refuse to start if the feature is unavailable and
+# 'enforce' mode is enabled in the CPU.
+#
+# @enum: See @CPUFeatureSettingEnum.
+#
+# Since: 2.10
+##
+{ 'alternate': 'CPUFeatureSetting',
+ 'data': { 'bool': 'bool',
+ 'enum': 'CPUFeatureSettingEnum' } }
+
+##
# @CpuDefinitionInfo:
#
# Virtual CPU definition.
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index c4602ca80d..7a34998e0a 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1149,6 +1149,8 @@ typedef struct CPUX86State {
FeatureWordArray features;
/* Features that were explicitly enabled/disabled */
FeatureWordArray user_features;
+ /* Features set to 'force' */
+ FeatureWordArray forced_features;
uint32_t cpuid_model[12];
/* MTRRs */
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 13c0985f11..6c24b92cee 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3463,7 +3463,7 @@ static int x86_cpu_filter_features(X86CPU *cpu)
uint32_t host_feat =
x86_cpu_get_supported_feature_word(w, false);
uint32_t requested_features = env->features[w];
- env->features[w] &= host_feat;
+ env->features[w] &= host_feat | env->forced_features[w];
cpu->filtered_features[w] = requested_features & ~env->features[w];
if (cpu->filtered_features[w]) {
rv = 1;
@@ -3705,9 +3705,19 @@ static void x86_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
{
X86CPU *cpu = X86_CPU(obj);
BitProperty *fp = opaque;
- uint32_t f = cpu->env.features[fp->w];
- bool value = (f & fp->mask) == fp->mask;
- visit_type_bool(v, name, &value, errp);
+ bool bvalue = (cpu->env.features[fp->w] & fp->mask) == fp->mask;
+ bool forced = (cpu->env.forced_features[fp->w] & fp->mask) == fp->mask;
+ CPUFeatureSetting *value = g_new0(CPUFeatureSetting, 1);
+
+ if (!forced) {
+ value->type = QTYPE_QBOOL;
+ value->u.q_bool = bvalue;
+ } else {
+ value->type = QTYPE_QSTRING;
+ value->u.q_enum = CPU_FEATURE_SETTING_ENUM_FORCE;
+ }
+ visit_type_CPUFeatureSetting(v, name, &value, errp);
+ qapi_free_CPUFeatureSetting(value);
}
static void x86_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
@@ -3717,25 +3727,46 @@ static void x86_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
X86CPU *cpu = X86_CPU(obj);
BitProperty *fp = opaque;
Error *local_err = NULL;
- bool value;
+ CPUFeatureSetting *value = NULL;
if (dev->realized) {
qdev_prop_set_after_realize(dev, name, errp);
return;
}
- visit_type_bool(v, name, &value, &local_err);
+ visit_type_CPUFeatureSetting(v, name, &value, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
- if (value) {
- cpu->env.features[fp->w] |= fp->mask;
- } else {
- cpu->env.features[fp->w] &= ~fp->mask;
+ switch (value->type) {
+ case QTYPE_QBOOL:
+ if (value->u.q_bool) {
+ cpu->env.features[fp->w] |= fp->mask;
+ } else {
+ cpu->env.features[fp->w] &= ~fp->mask;
+ }
+ cpu->env.forced_features[fp->w] &= ~fp->mask;
+ cpu->env.user_features[fp->w] |= fp->mask;
+ break;
+ case QTYPE_QSTRING:
+ switch (value->u.q_enum) {
+ case CPU_FEATURE_SETTING_ENUM_FORCE:
+ cpu->env.features[fp->w] |= fp->mask;
+ cpu->env.forced_features[fp->w] |= fp->mask;
+ break;
+ default:
+ error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name,
+ "CPUFeatureSetting");
+ }
+ break;
+ default:
+ error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name,
+ "CPUFeatureSetting");
}
- cpu->env.user_features[fp->w] |= fp->mask;
+
+ qapi_free_CPUFeatureSetting(value);
}
static void x86_cpu_release_bit_prop(Object *obj, const char *name,
@@ -3769,7 +3800,7 @@ static void x86_cpu_register_bit_prop(X86CPU *cpu,
fp = g_new0(BitProperty, 1);
fp->w = w;
fp->mask = mask;
- object_property_add(OBJECT(cpu), prop_name, "bool",
+ object_property_add(OBJECT(cpu), prop_name, "CPUFeatureSetting",
x86_cpu_get_bit_prop,
x86_cpu_set_bit_prop,
x86_cpu_release_bit_prop, fp, &error_abort);
diff --git a/tests/test-x86-cpuid-compat.c b/tests/test-x86-cpuid-compat.c
index 00ee8a264f..9940f4de1c 100644
--- a/tests/test-x86-cpuid-compat.c
+++ b/tests/test-x86-cpuid-compat.c
@@ -98,6 +98,8 @@ typedef struct FeatureTestArgs {
int bitnr;
/* The expected value for the bit in (X86CPUFeatureWordInfo.features) */
bool expected_value;
+ /* Don't look at filtered-features when checking feature value */
+ bool ignore_filtered_features;
} FeatureTestArgs;
/* Get the value for a feature word in a X86CPUFeatureWordInfo list */
@@ -129,7 +131,9 @@ static void test_feature_flag(const void *data)
present = qobject_to_qlist(qom_get(path, "feature-words"));
filtered = qobject_to_qlist(qom_get(path, "filtered-features"));
value = get_feature_word(present, args->input_eax, args->input_ecx, args->reg);
- value |= get_feature_word(filtered, args->input_eax, args->input_ecx, args->reg);
+ if (!args->ignore_filtered_features) {
+ value |= get_feature_word(filtered, args->input_eax, args->input_ecx, args->reg);
+ }
qtest_end();
g_assert(!!(value & (1U << args->bitnr)) == args->expected_value);
@@ -336,5 +340,13 @@ int main(int argc, char **argv)
"-machine accel=kvm:tcg -cpu max,mmx=off",
1, 0, "EDX", 23, false);
+ {
+ FeatureTestArgs *a;
+ a = add_feature_test("x86/cpuid/features/monitor-force",
+ "-machine accel=kvm:tcg -cpu 486,monitor=force",
+ 1, 0, "ECX", 3, true);
+ a->ignore_filtered_features = true;
+ }
+
return g_test_run();
}
--
2.11.0.259.g40922b1
next prev parent reply other threads:[~2017-05-02 20:31 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-02 20:31 [Qemu-devel] [PATCH 0/4] x86: Support "-cpu feature=force" Eduardo Habkost
2017-05-02 20:31 ` [Qemu-devel] [PATCH 1/4] visitor: Add 'supported_qtypes' parameter to visit_start_alternate() Eduardo Habkost
2017-05-02 21:29 ` Eric Blake
2017-05-02 22:35 ` Eduardo Habkost
2017-05-03 15:41 ` Markus Armbruster
2017-05-02 20:31 ` [Qemu-devel] [PATCH 2/4] string-input-visitor: Support alternate types Eduardo Habkost
2017-05-02 21:37 ` Eric Blake
2017-05-02 22:51 ` Eduardo Habkost
2017-05-03 16:07 ` Markus Armbruster
2017-05-03 18:30 ` Eduardo Habkost
2017-05-04 8:06 ` Markus Armbruster
2017-05-04 13:23 ` Eric Blake
2017-05-04 13:42 ` Markus Armbruster
2017-05-04 14:10 ` Eduardo Habkost
2017-05-04 19:42 ` Eduardo Habkost
2017-05-04 20:03 ` Eric Blake
2017-05-04 20:18 ` Eduardo Habkost
2017-05-05 6:26 ` Markus Armbruster
2017-05-02 20:31 ` [Qemu-devel] [PATCH 3/4] tests: Add [+-]feature and feature=on|off test cases Eduardo Habkost
2017-05-02 20:31 ` Eduardo Habkost [this message]
2017-05-02 20:43 ` [Qemu-devel] [PATCH] fixup! " Eduardo Habkost
2017-05-02 21:42 ` [Qemu-devel] [PATCH 4/4] x86: Support feature=force on the command-line Eric Blake
2017-05-02 22:51 ` Eduardo Habkost
2017-05-04 9:49 ` Igor Mammedov
2017-05-05 17:21 ` Eduardo Habkost
2017-05-04 10:16 ` Kashyap Chamarthy
2017-05-05 17:59 ` Eduardo Habkost
2017-05-08 10:56 ` Kashyap Chamarthy
2017-05-02 20:46 ` [Qemu-devel] [PATCH 0/4] x86: Support "-cpu feature=force" no-reply
2017-05-02 21:01 ` Eduardo Habkost
2017-05-02 20:47 ` no-reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170502203115.22233-5-ehabkost@redhat.com \
--to=ehabkost@redhat.com \
--cc=agraf@suse.de \
--cc=armbru@redhat.com \
--cc=eblake@redhat.com \
--cc=imammedo@redhat.com \
--cc=mdroth@linux.vnet.ibm.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).