[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 13/28] i386: kvm: filter CPUID feature words earlier
From: |
Marcelo Tosatti |
Subject: |
[Qemu-devel] [PATCH 13/28] i386: kvm: filter CPUID feature words earlier, on cpu.c |
Date: |
Wed, 31 Oct 2012 07:39:51 -0200 |
From: Eduardo Habkost <address@hidden>
cpu.c contains the code that will check if all requested CPU features
are available, so the filtering of KVM features must be there, so we can
implement "check" and "enforce" properly.
The only point where kvm_arch_init_vcpu() is called on i386 is:
- cpu_x86_init()
- x86_cpu_realize() (after cpu_x86_register() is called)
- qemu_init_vcpu()
- qemu_kvm_start_vcpu()
- qemu_kvm_thread_fn() (on a new thread)
- kvm_init_vcpu()
- kvm_arch_init_vcpu()
With this patch, the filtering will be done earlier, at:
- cpu_x86_init()
- cpu_x86_register() (before x86_cpu_realize() is called)
Also, the KVM CPUID filtering will now be done at the same place where
the TCG CPUID feature filtering is done. Later, the code can be changed
to use the same filtering code for the "check" and "enforce" modes, as
now the cpu.c code knows exactly which CPU features are going to be
exposed to the guest (and much earlier).
One thing I was worrying about when doing this is that
kvm_arch_get_supported_cpuid() depends on kvm_irqchip_in_kernel(), and
maybe the 'kvm_kernel_irqchip' global variable wasn't initialized yet at
CPU creation time. But kvm_kernel_irqchip is initialized during
kvm_init(), that is called very early (much earlier than the machine
init function), and kvm_init() is already a requirement to run the
GET_SUPPORTED_CPUID ioctl() (as kvm_init() initializes the kvm_state
global variable).
Side note: it would be nice to keep KVM-specific code inside kvm.c. The
problem is that properly implementing -cpu check/enforce code (that's
inside cpu.c) depends directly on the feature bit filtering done using
kvm_arch_get_supported_cpuid(). Currently -cpu check/enforce is broken
because it simply uses the host CPU feature bits instead of
GET_SUPPORTED_CPUID, and we need to fix that.
Signed-off-by: Eduardo Habkost <address@hidden>
Signed-off-by: Marcelo Tosatti <address@hidden>
---
kvm.h | 1 +
target-i386/cpu.c | 30 ++++++++++++++++++++++++++++++
target-i386/kvm.c | 18 ------------------
3 files changed, 31 insertions(+), 18 deletions(-)
diff --git a/kvm.h b/kvm.h
index 2b26dcb..1e7f244 100644
--- a/kvm.h
+++ b/kvm.h
@@ -20,6 +20,7 @@
#ifdef CONFIG_KVM
#include <linux/kvm.h>
+#include <linux/kvm_para.h>
#endif
extern int kvm_allowed;
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index d4f2e65..78876f6 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1368,6 +1368,32 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error
**errp)
return cpu_list;
}
+#ifdef CONFIG_KVM
+static void filter_features_for_kvm(X86CPU *cpu)
+{
+ CPUX86State *env = &cpu->env;
+ KVMState *s = kvm_state;
+
+ env->cpuid_features &= kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX);
+
+ env->cpuid_ext_features &= kvm_arch_get_supported_cpuid(s, 1, 0, R_ECX);
+
+ env->cpuid_ext2_features &= kvm_arch_get_supported_cpuid(s, 0x80000001,
+ 0, R_EDX);
+ env->cpuid_ext3_features &= kvm_arch_get_supported_cpuid(s, 0x80000001,
+ 0, R_ECX);
+ env->cpuid_svm_features &= kvm_arch_get_supported_cpuid(s, 0x8000000A,
+ 0, R_EDX);
+
+ env->cpuid_kvm_features &=
+ kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX);
+
+ env->cpuid_ext4_features &= kvm_arch_get_supported_cpuid(s, 0xC0000001,
+ 0, R_EDX);
+
+}
+#endif
+
int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
{
CPUX86State *env = &cpu->env;
@@ -1425,6 +1451,10 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
);
env->cpuid_ext3_features &= TCG_EXT3_FEATURES;
env->cpuid_svm_features &= TCG_SVM_FEATURES;
+ } else {
+#ifdef CONFIG_KVM
+ filter_features_for_kvm(cpu);
+#endif
}
object_property_set_str(OBJECT(cpu), def->model_id, "model-id", &error);
if (error_is_set(&error)) {
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index be37a1f..593e9d3 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -410,30 +410,12 @@ int kvm_arch_init_vcpu(CPUX86State *env)
struct kvm_cpuid2 cpuid;
struct kvm_cpuid_entry2 entries[100];
} QEMU_PACKED cpuid_data;
- KVMState *s = env->kvm_state;
uint32_t limit, i, j, cpuid_i;
uint32_t unused;
struct kvm_cpuid_entry2 *c;
uint32_t signature[3];
int r;
- env->cpuid_features &= kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX);
-
- env->cpuid_ext_features &= kvm_arch_get_supported_cpuid(s, 1, 0, R_ECX);
-
- env->cpuid_ext2_features &= kvm_arch_get_supported_cpuid(s, 0x80000001,
- 0, R_EDX);
- env->cpuid_ext3_features &= kvm_arch_get_supported_cpuid(s, 0x80000001,
- 0, R_ECX);
- env->cpuid_svm_features &= kvm_arch_get_supported_cpuid(s, 0x8000000A,
- 0, R_EDX);
-
- env->cpuid_kvm_features &=
- kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX);
-
- env->cpuid_ext4_features &= kvm_arch_get_supported_cpuid(s, 0xC0000001,
- 0, R_EDX);
-
cpuid_i = 0;
/* Paravirtualization CPUIDs */
--
1.7.6.4
- [Qemu-devel] [PATCH 19/28] Use machine options to emulate -no-kvm-irqchip, (continued)
- [Qemu-devel] [PATCH 19/28] Use machine options to emulate -no-kvm-irqchip, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 27/28] target-i386: kvm_cpu_fill_host: use GET_SUPPORTED_CPUID, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 14/28] i386: kvm: reformat filter_features_for_kvm() code, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 04/28] i386: kvm: extract register switch to cpuid_entry_get_reg() function, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 26/28] target-i386: cpu: make -cpu host/check/enforce code KVM-specific, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 17/28] target-i386: Add missing kvm cpuid feature name, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 15/28] i386: kvm: filter CPUID leaf 7 based on GET_SUPPORTED_CPUID, too, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 23/28] Issue warning when deprecated -tdf option is used, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 08/28] i386: kvm: set CPUID_EXT_HYPERVISOR on kvm_arch_get_supported_cpuid(), Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 09/28] i386: kvm: set CPUID_EXT_TSC_DEADLINE_TIMER on kvm_arch_get_supported_cpuid(), Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 13/28] i386: kvm: filter CPUID feature words earlier, on cpu.c,
Marcelo Tosatti <=
- [Qemu-devel] [PATCH 03/28] i386: kvm: kvm_arch_get_supported_cpuid: use 'entry' variable, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 11/28] i386: kvm: mask cpuid_kvm_features earlier, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 01/28] i386: kvm: kvm_arch_get_supported_cpuid: move R_EDX hack outside of for loop, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 18/28] cirrus_vga: allow configurable vram size, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 21/28] Use global properties to emulate -no-kvm-pit-reinjection, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 10/28] i386: kvm: x2apic is not supported without in-kernel irqchip, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 24/28] Emulate qemu-kvms -no-kvm option, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 16/28] i386: cpu: add missing CPUID[EAX=7, ECX=0] flag names, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 02/28] i386: kvm: kvm_arch_get_supported_cpuid: clean up has_kvm_features check, Marcelo Tosatti, 2012/10/31
- [Qemu-devel] [PATCH 22/28] Issue warning when deprecated drive parameter boot=on|off is used, Marcelo Tosatti, 2012/10/31