From patchwork Mon Mar 16 11:01:54 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 450485 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)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 483901400D5 for ; Mon, 16 Mar 2015 22:07:29 +1100 (AEDT) Received: from localhost ([::1]:48401 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YXSrn-0008Sy-3a for incoming@patchwork.ozlabs.org; Mon, 16 Mar 2015 07:07:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50916) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YXSr7-0007Nv-7m for qemu-devel@nongnu.org; Mon, 16 Mar 2015 07:06:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YXSr0-00078d-Td for qemu-devel@nongnu.org; Mon, 16 Mar 2015 07:06:45 -0400 Received: from static.88-198-71-155.clients.your-server.de ([88.198.71.155]:33328 helo=socrates.bennee.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YXSr0-00078Q-Nh for qemu-devel@nongnu.org; Mon, 16 Mar 2015 07:06:38 -0400 Received: from localhost ([127.0.0.1] helo=zen.linaroharston) by socrates.bennee.com with esmtp (Exim 4.80) (envelope-from ) id 1YXTtX-0000VG-UK; Mon, 16 Mar 2015 13:13:20 +0100 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: qemu-devel@nongnu.org Date: Mon, 16 Mar 2015 11:01:54 +0000 Message-Id: <1426503716-13931-4-git-send-email-alex.bennee@linaro.org> X-Mailer: git-send-email 2.3.2 In-Reply-To: <1426503716-13931-1-git-send-email-alex.bennee@linaro.org> References: <1426503716-13931-1-git-send-email-alex.bennee@linaro.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 127.0.0.1 X-SA-Exim-Mail-From: alex.bennee@linaro.org X-SA-Exim-Scanned: No (on socrates.bennee.com); SAEximRunCond expanded to false X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 88.198.71.155 Cc: Peter Maydell , kvm@vger.kernel.org, marc.zyngier@arm.com, linux-arm-kernel@lists.infradead.org, =?UTF-8?q?Alex=20Benn=C3=A9e?= , kvmarm@lists.cs.columbia.edu, christoffer.dall@linaro.org Subject: [Qemu-devel] [PATCH v4 3/5] target-arm: kvm64 sync FP register state 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 For migration to work we need to sync all of the register state. This is especially noticeable when GCC starts using FP registers as spill registers even with integer programs. Signed-off-by: Alex BennĂ©e --- v4: - fixed merge conflicts - rm superfluous reg.id++ diff --git a/target-arm/kvm64.c b/target-arm/kvm64.c index fed03f2..8fd0c8d 100644 --- a/target-arm/kvm64.c +++ b/target-arm/kvm64.c @@ -126,9 +126,17 @@ bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx) #define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x)) +/* The linux headers don't define a 128 bit wide SIMD macro for us */ +#define AARCH64_SIMD_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U128 | \ + KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x)) + +#define AARCH64_SIMD_CTRL_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U32 | \ + KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x)) + int kvm_arch_put_registers(CPUState *cs, int level) { struct kvm_one_reg reg; + uint32_t fpr; uint64_t val; int i; int ret; @@ -207,15 +215,37 @@ int kvm_arch_put_registers(CPUState *cs, int level) } } + /* Advanced SIMD and FP registers */ + for (i = 0; i < 32; i++) { + reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]); + reg.addr = (uintptr_t)(&env->vfp.regs[i]); + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); + if (ret) { + return ret; + } + } + + reg.addr = (uintptr_t)(&fpr); + fpr = vfp_get_fpsr(env); + reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr); + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); + if (ret) { + return ret; + } + + fpr = vfp_get_fpcr(env); + reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr); + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); + if (ret) { + return ret; + } + if (!write_list_to_kvmstate(cpu)) { return EINVAL; } kvm_arm_sync_mpstate_to_kvm(cpu); - /* TODO: - * FP state - */ return ret; } @@ -223,6 +253,7 @@ int kvm_arch_get_registers(CPUState *cs) { struct kvm_one_reg reg; uint64_t val; + uint32_t fpr; int i; int ret; @@ -304,6 +335,31 @@ int kvm_arch_get_registers(CPUState *cs) } } + /* Advanced SIMD and FP registers */ + for (i = 0; i < 32; i++) { + reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]); + reg.addr = (uintptr_t)(&env->vfp.regs[i]); + ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); + if (ret) { + return ret; + } + } + + reg.addr = (uintptr_t)(&fpr); + reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr); + ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); + if (ret) { + return ret; + } + vfp_set_fpsr(env, fpr); + + reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr); + ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); + if (ret) { + return ret; + } + vfp_set_fpcr(env, fpr); + if (!write_kvmstate_to_list(cpu)) { return EINVAL; }