]> git.proxmox.com Git - qemu.git/commitdiff
kvm: Rework VCPU synchronization
authorJan Kiszka <jan.kiszka@web.de>
Sat, 27 Jun 2009 07:24:58 +0000 (09:24 +0200)
committerAnthony Liguori <aliguori@us.ibm.com>
Mon, 29 Jun 2009 19:18:07 +0000 (14:18 -0500)
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>
hw/apic.c
kvm-all.c
kvm.h
vl.c

index 3ec4156cf209ba8626a09b5da322b3d1ec5adac2..cb9f8ee04d8d50129742d09a319af38d3e297e64 100644 (file)
--- 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] = {
index d843338f39d1795e19f46abb497022c1fc3d2dba..017296bc0e9d771b9ba61f2216c95b7c94ca2bd8 100644 (file)
--- 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 560aef38725322617b693264a7c28e4c35a64b1f..96b4d726093d87a11395a6bc6a9e4b487f8f635d 100644 (file)
--- 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 eb2449a1334abeb63398c5611dc9cde014db027a..c84e2d1bc9a1c8a5fd90f495d9f36bb4cefdc4b4 100644 (file)
--- 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++) {