From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42126) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aK5rU-0002NW-Bu for qemu-devel@nongnu.org; Fri, 15 Jan 2016 10:00:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aK5rQ-0001m9-Da for qemu-devel@nongnu.org; Fri, 15 Jan 2016 10:00:24 -0500 Received: from e06smtp12.uk.ibm.com ([195.75.94.108]:45257) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aK5rQ-0001lg-4l for qemu-devel@nongnu.org; Fri, 15 Jan 2016 10:00:20 -0500 Received: from localhost by e06smtp12.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 15 Jan 2016 15:00:17 -0000 From: Greg Kurz Date: Fri, 15 Jan 2016 16:00:12 +0100 Message-ID: <20160115150012.17358.95155.stgit@bahia.huguette.org> In-Reply-To: <20160115150005.17358.43294.stgit@bahia.huguette.org> References: <20160115150005.17358.43294.stgit@bahia.huguette.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [PATCH 1/7] target-ppc: kvm: fix floating point registers sync on little-endian hosts List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alexander Graf , David Gibson Cc: Paolo Bonzini , qemu-ppc@nongnu.org, Anton Blanchard , qemu-devel@nongnu.org On VSX capable CPUs, the 32 FP registers are mapped to the high-bits of the 32 first VSX registers. So if you have: VSR31 = (uint128) 0x0102030405060708090a0b0c0d0e0f00 then FPR31 = (uint64) 0x0102030405060708 The kernel stores the VSX registers in the fp_state struct following the host endian element ordering. On big-endian: fp_state.fpr[31][0] = 0x0102030405060708 fp_state.fpr[31][1] = 0x090a0b0c0d0e0f00 On little-endian: fp_state.fpr[31][0] = 0x090a0b0c0d0e0f00 fp_state.fpr[31][1] = 0x0102030405060708 The KVM_GET_ONE_REG and KVM_SET_ONE_REG ioctls preserve this ordering, but QEMU considers it as big-endian and always copies element [0] to the fpr[] array and element [1] to the vsr[] array. This does not work with little-endian hosts, and you will get: (qemu) p $f31 0x90a0b0c0d0e0f00 instead of: (qemu) p $f31 0x102030405060708 This patch fixes the element ordering for little-endian hosts. Signed-off-by: Greg Kurz --- target-ppc/kvm.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 9940a9046220..45249990bda1 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -650,8 +650,13 @@ static int kvm_put_fp(CPUState *cs) for (i = 0; i < 32; i++) { uint64_t vsr[2]; +#ifdef HOST_WORDS_BIGENDIAN vsr[0] = float64_val(env->fpr[i]); vsr[1] = env->vsr[i]; +#else + vsr[0] = env->vsr[i]; + vsr[1] = float64_val(env->fpr[i]); +#endif reg.addr = (uintptr_t) &vsr; reg.id = vsx ? KVM_REG_PPC_VSR(i) : KVM_REG_PPC_FPR(i); @@ -721,10 +726,17 @@ static int kvm_get_fp(CPUState *cs) vsx ? "VSR" : "FPR", i, strerror(errno)); return ret; } else { +#ifdef HOST_WORDS_BIGENDIAN env->fpr[i] = vsr[0]; if (vsx) { env->vsr[i] = vsr[1]; } +#else + env->fpr[i] = vsr[1]; + if (vsx) { + env->vsr[i] = vsr[0]; + } +#endif } } }