From patchwork Mon Jun 3 13:47:16 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 248291 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id D254B2C009C for ; Tue, 4 Jun 2013 00:14:45 +1000 (EST) Received: from localhost ([::1]:45809 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UjVX1-0004mO-SE for incoming@patchwork.ozlabs.org; Mon, 03 Jun 2013 10:14:43 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54413) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UjVWe-0004hT-Tm for qemu-devel@nongnu.org; Mon, 03 Jun 2013 10:14:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UjVWY-00089W-M2 for qemu-devel@nongnu.org; Mon, 03 Jun 2013 10:14:20 -0400 Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.1.0.0.b.8.0.1.0.0.2.ip6.arpa ([2001:8b0:1d0::1]:57752 helo=mnementh.archaic.org.uk) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UjVEO-0002X8-IT for qemu-devel@nongnu.org; Mon, 03 Jun 2013 09:55:28 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1UjV6U-0006iJ-4S; Mon, 03 Jun 2013 14:47:18 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Mon, 3 Jun 2013 14:47:16 +0100 Message-Id: <1370267237-25772-7-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1370267237-25772-1-git-send-email-peter.maydell@linaro.org> References: <1370267237-25772-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:8b0:1d0::1 Cc: kvm@vger.kernel.org, Juan Quintela , patches@linaro.org, Andre Przywara , kvmarm@lists.cs.columbia.edu, Christoffer Dall Subject: [Qemu-devel] [PATCH v2 6/7] target-arm: Reinitialize all KVM VCPU registers on reset X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- target-arm/cpu-qom.h | 6 +++++- target-arm/kvm.c | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index 2242eee..25239b8 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -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 diff --git a/target-arm/kvm.c b/target-arm/kvm.c index 746ae02..f4a835d 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)