Cédric Le Goater
2014-10-02 16:58:00 UTC
Saving and restoring guests on a KVM little endian host is currently=20
broken because qemu assumes that htabs are big endian.=20
This patch modifies kvm_htab_read and kvm_htab_write to make sure=20
that the endianness expected by qemu is enforced on big and little
endian hosts.
Signed-off-by: C=C3=A9dric Le Goater <***@fr.ibm.com>
---
Tested on 3.17-rc7 with LE and BE host.
Looking at the code, it is not very clear what we are doing
in terms of endianness. May be this needs more work on both=20
side, KVM and qemu, to remove the big endian assumptions ?=20
Thanks,
arch/powerpc/kvm/book3s_64_mmu_hv.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/boo=
k3s_64_mmu_hv.c
index 79294c4c5015..51dbf772158b 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -1463,6 +1463,9 @@ static ssize_t kvm_htab_read(struct file *file, c=
har __user *buf,
}
=20
if (hdr.n_valid || hdr.n_invalid) {
+ hdr.index =3D cpu_to_be32(hdr.index);
+ hdr.n_valid =3D cpu_to_be16(hdr.n_valid);
+ hdr.n_invalid =3D cpu_to_be16(hdr.n_invalid);
/* write back the header */
if (__copy_to_user(hptr, &hdr, sizeof(hdr)))
return -EFAULT;
@@ -1542,6 +1545,8 @@ static ssize_t kvm_htab_write(struct file *file, =
const char __user *buf,
err =3D -EFAULT;
if (__get_user(v, lbuf) || __get_user(r, lbuf + 1))
goto out;
+ v =3D be64_to_cpu(v);
+ r =3D be64_to_cpu(r);
err =3D -EINVAL;
if (!(v & HPTE_V_VALID))
goto out;
--=20
1.7.10.4
broken because qemu assumes that htabs are big endian.=20
This patch modifies kvm_htab_read and kvm_htab_write to make sure=20
that the endianness expected by qemu is enforced on big and little
endian hosts.
Signed-off-by: C=C3=A9dric Le Goater <***@fr.ibm.com>
---
Tested on 3.17-rc7 with LE and BE host.
Looking at the code, it is not very clear what we are doing
in terms of endianness. May be this needs more work on both=20
side, KVM and qemu, to remove the big endian assumptions ?=20
Thanks,
arch/powerpc/kvm/book3s_64_mmu_hv.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/boo=
k3s_64_mmu_hv.c
index 79294c4c5015..51dbf772158b 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -1463,6 +1463,9 @@ static ssize_t kvm_htab_read(struct file *file, c=
har __user *buf,
}
=20
if (hdr.n_valid || hdr.n_invalid) {
+ hdr.index =3D cpu_to_be32(hdr.index);
+ hdr.n_valid =3D cpu_to_be16(hdr.n_valid);
+ hdr.n_invalid =3D cpu_to_be16(hdr.n_invalid);
/* write back the header */
if (__copy_to_user(hptr, &hdr, sizeof(hdr)))
return -EFAULT;
@@ -1542,6 +1545,8 @@ static ssize_t kvm_htab_write(struct file *file, =
const char __user *buf,
err =3D -EFAULT;
if (__get_user(v, lbuf) || __get_user(r, lbuf + 1))
goto out;
+ v =3D be64_to_cpu(v);
+ r =3D be64_to_cpu(r);
err =3D -EINVAL;
if (!(v & HPTE_V_VALID))
goto out;
--=20
1.7.10.4