diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2013-06-25 18:16:07 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2013-06-25 18:16:10 +0100 |
commit | 2d8e5a0e25171eca30a72a450826f539f05951d0 (patch) | |
tree | 3375a5860412b5ec30c009f270744ceda5c46d2e /target-arm/kvm.c | |
parent | ff047453f56713aa627e63aade1a9046ccd3bdfd (diff) |
target-arm: Reinitialize all KVM VCPU registers on reset
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>
Diffstat (limited to 'target-arm/kvm.c')
-rw-r--r-- | target-arm/kvm.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/target-arm/kvm.c b/target-arm/kvm.c index 66ce67a46f..49108cfd33 100644 --- a/target-arm/kvm.c +++ b/target-arm/kvm.c @@ -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) |