[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH 58/66] target-ppc: Synchronize FPU state with KVM
From: |
Alexander Graf |
Subject: |
[Qemu-ppc] [PATCH 58/66] target-ppc: Synchronize FPU state with KVM |
Date: |
Fri, 8 Mar 2013 21:07:00 +0100 |
From: David Gibson <address@hidden>
Currently qemu does not get and put the state of the floating point and
vector registers to KVM. This is obviously a problem for savevm, as well
as possibly being problematic for debugging of FP-using guests.
This patch fixes this by using new extensions to the ONE_REG interface to
synchronize the qemu floating point state with KVM.
Signed-off-by: David Gibson <address@hidden>
Signed-off-by: Alexander Graf <address@hidden>
---
target-ppc/kvm.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 130 insertions(+), 0 deletions(-)
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 02ab559..4451159 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -521,6 +521,132 @@ static void kvm_put_one_spr(CPUState *cs, uint64_t id,
int spr)
}
}
+static int kvm_put_fp(CPUState *cs)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+ struct kvm_one_reg reg;
+ int i;
+ int ret;
+
+ if (env->insns_flags & PPC_FLOAT) {
+ uint64_t fpscr = env->fpscr;
+ bool vsx = !!(env->insns_flags2 & PPC2_VSX);
+
+ reg.id = KVM_REG_PPC_FPSCR;
+ reg.addr = (uintptr_t)&fpscr;
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
+ if (ret < 0) {
+ dprintf("Unable to set FPSCR to KVM: %s\n", strerror(errno));
+ return ret;
+ }
+
+ for (i = 0; i < 32; i++) {
+ uint64_t vsr[2];
+
+ vsr[0] = float64_val(env->fpr[i]);
+ vsr[1] = env->vsr[i];
+ reg.addr = (uintptr_t) &vsr;
+ reg.id = vsx ? KVM_REG_PPC_VSR(i) : KVM_REG_PPC_FPR(i);
+
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
+ if (ret < 0) {
+ dprintf("Unable to set %s%d to KVM: %s\n", vsx ? "VSR" : "FPR",
+ i, strerror(errno));
+ return ret;
+ }
+ }
+ }
+
+ if (env->insns_flags & PPC_ALTIVEC) {
+ reg.id = KVM_REG_PPC_VSCR;
+ reg.addr = (uintptr_t)&env->vscr;
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
+ if (ret < 0) {
+ dprintf("Unable to set VSCR to KVM: %s\n", strerror(errno));
+ return ret;
+ }
+
+ for (i = 0; i < 32; i++) {
+ reg.id = KVM_REG_PPC_VR(i);
+ reg.addr = (uintptr_t)&env->avr[i];
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
+ if (ret < 0) {
+ dprintf("Unable to set VR%d to KVM: %s\n", i, strerror(errno));
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int kvm_get_fp(CPUState *cs)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+ struct kvm_one_reg reg;
+ int i;
+ int ret;
+
+ if (env->insns_flags & PPC_FLOAT) {
+ uint64_t fpscr;
+ bool vsx = !!(env->insns_flags2 & PPC2_VSX);
+
+ reg.id = KVM_REG_PPC_FPSCR;
+ reg.addr = (uintptr_t)&fpscr;
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
+ if (ret < 0) {
+ dprintf("Unable to get FPSCR from KVM: %s\n", strerror(errno));
+ return ret;
+ } else {
+ env->fpscr = fpscr;
+ }
+
+ for (i = 0; i < 32; i++) {
+ uint64_t vsr[2];
+
+ reg.addr = (uintptr_t) &vsr;
+ reg.id = vsx ? KVM_REG_PPC_VSR(i) : KVM_REG_PPC_FPR(i);
+
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
+ if (ret < 0) {
+ dprintf("Unable to get %s%d from KVM: %s\n",
+ vsx ? "VSR" : "FPR", i, strerror(errno));
+ return ret;
+ } else {
+ env->fpr[i] = vsr[0];
+ if (vsx) {
+ env->vsr[i] = vsr[1];
+ }
+ }
+ }
+ }
+
+ if (env->insns_flags & PPC_ALTIVEC) {
+ reg.id = KVM_REG_PPC_VSCR;
+ reg.addr = (uintptr_t)&env->vscr;
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
+ if (ret < 0) {
+ dprintf("Unable to get VSCR from KVM: %s\n", strerror(errno));
+ return ret;
+ }
+
+ for (i = 0; i < 32; i++) {
+ reg.id = KVM_REG_PPC_VR(i);
+ reg.addr = (uintptr_t)&env->avr[i];
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
+ if (ret < 0) {
+ dprintf("Unable to get VR%d from KVM: %s\n",
+ i, strerror(errno));
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
int kvm_arch_put_registers(CPUState *cs, int level)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
@@ -561,6 +687,8 @@ int kvm_arch_put_registers(CPUState *cs, int level)
if (ret < 0)
return ret;
+ kvm_put_fp(cs);
+
if (env->tlb_dirty) {
kvm_sw_tlb_put(cpu);
env->tlb_dirty = false;
@@ -666,6 +794,8 @@ int kvm_arch_get_registers(CPUState *cs)
for (i = 0;i < 32; i++)
env->gpr[i] = regs.gpr[i];
+ kvm_get_fp(cs);
+
if (cap_booke_sregs) {
ret = kvm_vcpu_ioctl(cs, KVM_GET_SREGS, &sregs);
if (ret < 0) {
--
1.6.0.2
- [Qemu-ppc] [PATCH 34/66] target-ppc: Extract MPC8247/MPC8248/MPC8270-80 aliases, (continued)
- [Qemu-ppc] [PATCH 34/66] target-ppc: Extract MPC8247/MPC8248/MPC8270-80 aliases, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 61/66] PPC: xnu kernel expects FLUSH to be cleared on STOP, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 53/66] target-ppc: Fix remaining microcontroller typos among models, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 55/66] pseries: Implement h_read hcall, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 44/66] target-ppc: Convert CPU definitions, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 63/66] target-ppc: List alias names alongside CPU models, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 56/66] Save memory allocation in the elf loader, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 60/66] PPC: Fix dma interrupt, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 51/66] target-ppc: Update Coding Style for CPU models, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 64/66] target-ppc: Report CPU aliases for QMP, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 58/66] target-ppc: Synchronize FPU state with KVM,
Alexander Graf <=
- [Qemu-ppc] [PATCH 62/66] target-ppc: Make host CPU a subclass of the host's CPU model, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 57/66] target-ppc: Add mechanism for synchronizing SPRs with KVM, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 65/66] target-ppc: Move CPU aliases out of translate_init.c, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 66/66] pseries: Add compatible property to root of device tree, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 49/66] target-ppc: Turn descriptive CPU family comments into device descriptions, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 48/66] target-ppc: Set remaining fields on CPU family classes, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 45/66] target-ppc: Introduce abstract CPU family types, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 06/66] target-ppc: Inline comma into POWERPC_DEF_SVR() macro, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 50/66] target-ppc: Turn descriptive CPU model comments into device descriptions, Alexander Graf, 2013/03/08
- [Qemu-ppc] [PATCH 52/66] target-ppc: Split model definitions out of translate_init.c, Alexander Graf, 2013/03/08