2017-05-11 23:48:59 +02:00
|
|
|
From 5cff035804d92d336b27c368754b63e2dccbba90 Mon Sep 17 00:00:00 2001
|
2017-04-28 13:47:25 +02:00
|
|
|
From: Alexander Graf <agraf@suse.de>
|
|
|
|
Date: Tue, 28 Mar 2017 05:27:00 -0600
|
|
|
|
Subject: [PATCH] i386: Allow cpuid bit override
|
|
|
|
|
|
|
|
KVM has a feature bitmap of CPUID bits that it knows works for guests.
|
|
|
|
QEMU removes bits that are not part of that bitmap automatically on VM
|
|
|
|
start.
|
|
|
|
|
|
|
|
However, some times we just don't list features in that list because
|
|
|
|
they don't make sense for normal scenarios, but may be useful in specific,
|
|
|
|
targeted workloads.
|
|
|
|
|
|
|
|
For that purpose, add a new =force option to all CPUID feature flags in
|
|
|
|
the CPU property. With that we can override the accel filtering and give
|
|
|
|
users full control over the CPUID feature bits exposed into guests.
|
|
|
|
|
|
|
|
Signed-off-by: Alexander Graf <agraf@suse.de>
|
|
|
|
---
|
|
|
|
target/i386/cpu.c | 25 ++++++++++++++++++++++---
|
|
|
|
target/i386/cpu.h | 3 +++
|
|
|
|
2 files changed, 25 insertions(+), 3 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
|
2017-05-05 17:05:43 +02:00
|
|
|
index 13c0985f11..6105fc513e 100644
|
2017-04-28 13:47:25 +02:00
|
|
|
--- a/target/i386/cpu.c
|
|
|
|
+++ b/target/i386/cpu.c
|
|
|
|
@@ -2229,7 +2229,7 @@ void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
|
|
|
|
g_slist_foreach(list, x86_cpu_list_entry, &s);
|
|
|
|
g_slist_free(list);
|
|
|
|
|
|
|
|
- (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
|
|
|
|
+ (*cpu_fprintf)(f, "\nRecognized CPUID flags (=on|=off|=force):\n");
|
|
|
|
for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
|
|
|
|
FeatureWordInfo *fw = &feature_word_info[i];
|
|
|
|
|
|
|
|
@@ -3464,6 +3464,7 @@ static int x86_cpu_filter_features(X86CPU *cpu)
|
|
|
|
x86_cpu_get_supported_feature_word(w, false);
|
|
|
|
uint32_t requested_features = env->features[w];
|
|
|
|
env->features[w] &= host_feat;
|
|
|
|
+ env->features[w] |= cpu->forced_features[w];
|
|
|
|
cpu->filtered_features[w] = requested_features & ~env->features[w];
|
|
|
|
if (cpu->filtered_features[w]) {
|
|
|
|
rv = 1;
|
|
|
|
@@ -3706,8 +3707,17 @@ 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];
|
|
|
|
+ uint32_t ff = cpu->forced_features[fp->w];
|
|
|
|
bool value = (f & fp->mask) == fp->mask;
|
|
|
|
- visit_type_bool(v, name, &value, errp);
|
|
|
|
+ bool forced = (ff & fp->mask) == fp->mask;
|
|
|
|
+ char str[] = "force";
|
|
|
|
+ char *strval = str;
|
|
|
|
+
|
|
|
|
+ if (forced) {
|
|
|
|
+ visit_type_str(v, name, &strval, errp);
|
|
|
|
+ } else {
|
|
|
|
+ visit_type_bool(v, name, &value, errp);
|
|
|
|
+ }
|
|
|
|
}
|
|
|
|
|
|
|
|
static void x86_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
|
|
|
|
@@ -3717,6 +3727,7 @@ 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;
|
|
|
|
+ char *strval = NULL;
|
|
|
|
bool value;
|
|
|
|
|
|
|
|
if (dev->realized) {
|
|
|
|
@@ -3724,7 +3735,15 @@ static void x86_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
- visit_type_bool(v, name, &value, &local_err);
|
|
|
|
+ visit_type_str(v, name, &strval, &local_err);
|
|
|
|
+ if (!local_err && !strcmp(strval, "force")) {
|
|
|
|
+ value = true;
|
|
|
|
+ cpu->forced_features[fp->w] |= fp->mask;
|
|
|
|
+ } else {
|
|
|
|
+ local_err = NULL;
|
|
|
|
+ visit_type_bool(v, name, &value, &local_err);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
if (local_err) {
|
|
|
|
error_propagate(errp, local_err);
|
|
|
|
return;
|
|
|
|
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
|
2017-05-05 17:05:43 +02:00
|
|
|
index 81c02c5a3b..a458c3af9b 100644
|
2017-04-28 13:47:25 +02:00
|
|
|
--- a/target/i386/cpu.h
|
|
|
|
+++ b/target/i386/cpu.h
|
|
|
|
@@ -1230,6 +1230,9 @@ struct X86CPU {
|
|
|
|
/* Features that were filtered out because of missing host capabilities */
|
|
|
|
uint32_t filtered_features[FEATURE_WORDS];
|
|
|
|
|
|
|
|
+ /* Features that are force enabled despite incompatible accel */
|
|
|
|
+ uint32_t forced_features[FEATURE_WORDS];
|
|
|
|
+
|
|
|
|
/* Enable PMU CPUID bits. This can't be enabled by default yet because
|
|
|
|
* it doesn't have ABI stability guarantees, as it passes all PMU CPUID
|
|
|
|
* bits returned by GET_SUPPORTED_CPUID (that depend on host CPU and kernel
|