summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@web.de>2009-06-27 09:24:58 +0200
committerAnthony Liguori <aliguori@us.ibm.com>2009-06-29 14:18:07 -0500
commit8d2ba1fb9c8e7006e10d71fa51a020977f14c8b0 (patch)
treefe229d578c3380d6b9e874337f06413a9a1160af
parentmonitor: Drop pci_addr prefix from hotplug commands (diff)
downloadqemu-kvm-8d2ba1fb9c8e7006e10d71fa51a020977f14c8b0.tar.gz
qemu-kvm-8d2ba1fb9c8e7006e10d71fa51a020977f14c8b0.tar.bz2
qemu-kvm-8d2ba1fb9c8e7006e10d71fa51a020977f14c8b0.zip
kvm: Rework VCPU synchronization
During startup and after reset we have to synchronize user space to the in-kernel KVM state. Namely, we need to transfer the VCPU registers when they change due to VCPU as well as APIC reset. This patch refactors the required hooks so that kvm_init_vcpu registers its own per-VCPU reset handler and adds a cpu_synchronize_state to the APIC reset. That way we no longer depend on the new reset order (and can drop this disliked interface again) and we can even drop a KVM hook in main(). Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r--hw/apic.c3
-rw-r--r--kvm-all.c36
-rw-r--r--kvm.h1
-rw-r--r--vl.c11
4 files changed, 16 insertions, 35 deletions
diff --git a/hw/apic.c b/hw/apic.c
index 3ec4156cf..cb9f8ee04 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -23,6 +23,7 @@
#include "msix.h"
#include "qemu-timer.h"
#include "host-utils.h"
+#include "kvm.h"
//#define DEBUG_APIC
@@ -953,6 +954,8 @@ static void apic_reset(void *opaque)
*/
s->lvt[APIC_LVT_LINT0] = 0x700;
}
+
+ cpu_synchronize_state(s->cpu_env, 1);
}
static CPUReadMemoryFunc *apic_mem_read[3] = {
diff --git a/kvm-all.c b/kvm-all.c
index d843338f3..017296bc0 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -143,6 +143,15 @@ static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot)
return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
}
+static void kvm_reset_vcpu(void *opaque)
+{
+ CPUState *env = opaque;
+
+ if (kvm_arch_put_registers(env)) {
+ fprintf(stderr, "Fatal: kvm vcpu reset failed\n");
+ abort();
+ }
+}
int kvm_init_vcpu(CPUState *env)
{
@@ -176,7 +185,10 @@ int kvm_init_vcpu(CPUState *env)
}
ret = kvm_arch_init_vcpu(env);
-
+ if (ret == 0) {
+ qemu_register_reset(kvm_reset_vcpu, 0, env);
+ ret = kvm_arch_put_registers(env);
+ }
err:
return ret;
}
@@ -201,21 +213,6 @@ int kvm_get_mp_state(CPUState *env)
return 0;
}
-int kvm_sync_vcpus(void)
-{
- CPUState *env;
-
- for (env = first_cpu; env != NULL; env = env->next_cpu) {
- int ret;
-
- ret = kvm_arch_put_registers(env);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
/*
* dirty pages logging control
*/
@@ -397,11 +394,6 @@ int kvm_check_extension(KVMState *s, unsigned int extension)
return ret;
}
-static void kvm_reset_vcpus(void *opaque)
-{
- kvm_sync_vcpus();
-}
-
int kvm_init(int smp_cpus)
{
static const char upgrade_note[] =
@@ -492,8 +484,6 @@ int kvm_init(int smp_cpus)
if (ret < 0)
goto err;
- qemu_register_reset(kvm_reset_vcpus, INT_MAX, NULL);
-
kvm_state = s;
return 0;
diff --git a/kvm.h b/kvm.h
index 560aef387..96b4d7260 100644
--- a/kvm.h
+++ b/kvm.h
@@ -32,7 +32,6 @@ struct kvm_run;
int kvm_init(int smp_cpus);
int kvm_init_vcpu(CPUState *env);
-int kvm_sync_vcpus(void);
int kvm_cpu_exec(CPUState *env);
diff --git a/vl.c b/vl.c
index eb2449a13..c84e2d1bc 100644
--- a/vl.c
+++ b/vl.c
@@ -6057,17 +6057,6 @@ int main(int argc, char **argv, char **envp)
current_machine = machine;
- /* Set KVM's vcpu state to qemu's initial CPUState. */
- if (kvm_enabled()) {
- int ret;
-
- ret = kvm_sync_vcpus();
- if (ret < 0) {
- fprintf(stderr, "failed to initialize vcpus\n");
- exit(1);
- }
- }
-
/* init USB devices */
if (usb_enabled) {
for(i = 0; i < usb_devices_index; i++) {