qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-ppc] [PATCH 4/4] ppc: kvm: update HPT pointer in KVM PR after migr


From: Greg Kurz
Subject: [Qemu-ppc] [PATCH 4/4] ppc: kvm: update HPT pointer in KVM PR after migration
Date: Mon, 04 Sep 2017 23:47:24 +0200
User-agent: StGit/0.17.1-46-g6855-dirty

When running with KVM PR, a pseries machine needs to allocate an HPT in
userspace and pass its address to KVM. This is done by hijacking the SDR1
slot.

It is very likely that the destination QEMU will allocate the HPT at
a different address, ie, the SDR1 value we get from the migration
stream is wrong and the guest ends up badly broken.

Let's fix this by re-computing the appropriate value for SDR1 and pushing
it to KVM at CPU post load. This is achieved by extending the PPC virtual
hypervisor interface.

Signed-off-by: Greg Kurz <address@hidden>
---
 hw/ppc/spapr.c       |    6 ++++++
 target/ppc/cpu.h     |    1 +
 target/ppc/machine.c |    7 +++++++
 3 files changed, 14 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index bf24c26b756d..11c65563bb6e 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1299,6 +1299,11 @@ target_ulong spapr_get_hpt_pointer(sPAPRMachineState 
*spapr)
     return (target_ulong)(uintptr_t)spapr->htab | (spapr->htab_shift - 18);
 }
 
+static target_ulong get_spapr_hpt_pointer(PPCVirtualHypervisor *vhyp)
+{
+    return spapr_get_hpt_pointer(SPAPR_MACHINE(vhyp));
+}
+
 int spapr_hpt_shift_for_ramsize(uint64_t ramsize)
 {
     int shift;
@@ -3613,6 +3618,7 @@ static void spapr_machine_class_init(ObjectClass *oc, 
void *data)
     vhc->unmap_hptes = spapr_unmap_hptes;
     vhc->store_hpte = spapr_store_hpte;
     vhc->get_patbe = spapr_get_patbe;
+    vhc->get_hpt_pointer = get_spapr_hpt_pointer;
     xic->ics_get = spapr_ics_get;
     xic->ics_resend = spapr_ics_resend;
     xic->icp_get = spapr_icp_get;
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index c9d3ffa89bcb..bb1d61c9358c 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1243,6 +1243,7 @@ struct PPCVirtualHypervisorClass {
     void (*store_hpte)(PPCVirtualHypervisor *vhyp, hwaddr ptex,
                        uint64_t pte0, uint64_t pte1);
     uint64_t (*get_patbe)(PPCVirtualHypervisor *vhyp);
+    target_ulong (*get_hpt_pointer)(PPCVirtualHypervisor *vhyp);
 };
 
 #define TYPE_PPC_VIRTUAL_HYPERVISOR "ppc-virtual-hypervisor"
diff --git a/target/ppc/machine.c b/target/ppc/machine.c
index e36b7100cb66..6ec4b3214a2d 100644
--- a/target/ppc/machine.c
+++ b/target/ppc/machine.c
@@ -294,6 +294,13 @@ static int cpu_post_load(void *opaque, int version_id)
 
     if (!cpu->vhyp) {
         ppc_store_sdr1(env, env->spr[SPR_SDR1]);
+    } else if (kvm_enabled()) {
+        PPCVirtualHypervisorClass *vhc =
+            PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
+        target_ulong sdr1 = vhc->get_hpt_pointer(cpu->vhyp);
+        if (sdr1) {
+            kvmppc_update_sdr1(cpu, sdr1);
+        }
     }
 
     /* Invalidate all msr bits except MSR_TGPR/MSR_HVB before restoring */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]