]> xenbits.xensource.com Git - qemu-xen-unstable.git/commitdiff
target-arm: Reinitialize all KVM VCPU registers on reset
authorPeter Maydell <peter.maydell@linaro.org>
Tue, 25 Jun 2013 17:16:07 +0000 (18:16 +0100)
committerPeter Maydell <peter.maydell@linaro.org>
Tue, 25 Jun 2013 17:16:10 +0000 (18:16 +0100)
Since the ARM KVM API doesn't include a "reset this VCPU"
ioctl, we have to capture the initial values of every
register it knows about so that we can reset the VCPU
by feeding those values back again.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
target-arm/cpu-qom.h
target-arm/kvm.c

index 2242eee51417faa590960dca3ca1ea93722d9a0f..25239b89524693791c1a01c40d4af0a7300f0507 100644 (file)
@@ -72,7 +72,11 @@ typedef struct ARMCPU {
     uint64_t *cpreg_indexes;
     /* Values of the registers (cpreg_indexes[i]'s value is cpreg_values[i]) */
     uint64_t *cpreg_values;
-    /* Length of the indexes, values arrays */
+    /* When using KVM, keeps a copy of the initial state of the VCPU,
+     * so that on reset we can feed the reset values back into the kernel.
+     */
+    uint64_t *cpreg_reset_values;
+    /* Length of the indexes, values, reset_values arrays */
     int32_t cpreg_array_len;
     /* These are used only for migration: incoming data arrives in
      * these fields and is sanity checked in post_load before copying
index 66ce67a46f06d1aa4c22b1e1b3e3005ed8d9c058..49108cfd338cd587c2597e3d62e27e12525ad354 100644 (file)
@@ -162,6 +162,13 @@ int kvm_arch_init_vcpu(CPUState *cs)
         goto out;
     }
 
+    /* Save a copy of the initial register values so that we can
+     * feed it back to the kernel on VCPU reset.
+     */
+    cpu->cpreg_reset_values = g_memdup(cpu->cpreg_values,
+                                       cpu->cpreg_array_len *
+                                       sizeof(cpu->cpreg_values[0]));
+
 out:
     g_free(rlp);
     return ret;
@@ -603,6 +610,15 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
 
 void kvm_arch_reset_vcpu(CPUState *cs)
 {
+    /* Feed the kernel back its initial register state */
+    ARMCPU *cpu = ARM_CPU(cs);
+
+    memmove(cpu->cpreg_values, cpu->cpreg_reset_values,
+            cpu->cpreg_array_len * sizeof(cpu->cpreg_values[0]));
+
+    if (!write_list_to_kvmstate(cpu)) {
+        abort();
+    }
 }
 
 bool kvm_arch_stop_on_emulation_error(CPUState *cs)