]> git.ipfire.org Git - thirdparty/qemu.git/commit
target-ppc: kvm: fix floating point registers sync on little-endian hosts
authorGreg Kurz <gkurz@linux.vnet.ibm.com>
Fri, 15 Jan 2016 15:00:12 +0000 (16:00 +0100)
committerMichael Roth <mdroth@linux.vnet.ibm.com>
Tue, 15 Mar 2016 17:10:47 +0000 (12:10 -0500)
commitd4aed70099429161b2842135217553e822f86988
tree49a2c5f34e43f3b07346e1cf79db59cfb991536f
parent42ae4a3c610e05193a220ab4a6c046decb2866be
target-ppc: kvm: fix floating point registers sync on little-endian hosts

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 <gkurz@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 3a4b791b4c13e02537a5cc572fa3de70bc5f68da)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
target-ppc/kvm.c