From nobody Sun May 5 09:57:24 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505255195847235.6741217984993; Tue, 12 Sep 2017 15:26:35 -0700 (PDT) Received: from localhost ([::1]:38989 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtdb-000425-10 for importer@patchew.org; Tue, 12 Sep 2017 18:26:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52157) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtc6-000358-DF for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:25:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drtc1-0005ar-Sx for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:25:02 -0400 Received: from 8.mo2.mail-out.ovh.net ([188.165.52.147]:42428) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drtc1-0005Za-JV for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:24:57 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id 523D3AA673 for ; Wed, 13 Sep 2017 00:24:56 +0200 (CEST) Received: from bahia.lan (gar31-1-82-66-74-139.fbx.proxad.net [82.66.74.139]) (Authenticated sender: groug@kaod.org) by player770.ha.ovh.net (Postfix) with ESMTPA id 11EF83C006C; Wed, 13 Sep 2017 00:24:54 +0200 (CEST) From: Greg Kurz To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:24:53 +0200 Message-ID: <150525509384.11068.12660058285712851211.stgit@bahia.lan> In-Reply-To: <150525508489.11068.5231444460720976552.stgit@bahia.lan> References: <150525508489.11068.5231444460720976552.stgit@bahia.lan> User-Agent: StGit/0.17.1-46-g6855-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 6825205235612227923 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedvgdduieeiucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.52.147 Subject: [Qemu-devel] [PATCH v2 1/2] spapr: introduce common helper to write HPT address to KVM PR X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 When running with KVM PR, if a new HPT is allocated we need to inform KVM about the HPT address and size. This is currently done with a hack which is open-coded in several places. This patch consolidate the code in a dedicated helper that records the HPT address and size in the sPAPR context, and then does the magic for KVM PR. Note that ppc_spapr_reset() now resets all devices and CPUs before allocating the HPT. This allows to drop the hack from spapr_cpu_reset(). Signed-off-by: Greg Kurz --- hw/ppc/spapr.c | 31 ++++++++++++++++++++++++++----- hw/ppc/spapr_cpu_core.c | 15 --------------- hw/ppc/spapr_hcall.c | 16 +--------------- include/hw/ppc/spapr.h | 1 + 4 files changed, 28 insertions(+), 35 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index f680f28a15ea..97f8afdbd7fe 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1309,6 +1309,25 @@ void spapr_free_hpt(sPAPRMachineState *spapr) close_htab_fd(spapr); } =20 +void spapr_install_hpt(sPAPRMachineState *spapr, void *htab, uint32_t shif= t) +{ + assert(htab); + + spapr->htab =3D htab; + spapr->htab_shift =3D shift; + + /* + * This is a hack for the benefit of KVM PR - it abuses the SDR1 + * slot in kvm_sregs to communicate the userspace address of the + * HPT + */ + if (kvm_enabled()) { + target_ulong sdr1 =3D (target_ulong)(uintptr_t)spapr->htab + | (spapr->htab_shift - 18); + kvmppc_update_sdr1(sdr1); + } +} + void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift, Error **errp) { @@ -1339,16 +1358,17 @@ void spapr_reallocate_hpt(sPAPRMachineState *spapr,= int shift, /* kernel-side HPT not needed, allocate in userspace instead */ size_t size =3D 1ULL << shift; int i; + void *htab; =20 - spapr->htab =3D qemu_memalign(size, size); - if (!spapr->htab) { + htab =3D qemu_memalign(size, size); + if (!htab) { error_setg_errno(errp, errno, "Could not allocate HPT of order %d", shift); return; } =20 - memset(spapr->htab, 0, size); - spapr->htab_shift =3D shift; + memset(htab, 0, size); + spapr_install_hpt(spapr, htab, shift); =20 for (i =3D 0; i < size / HASH_PTE_SIZE_64; i++) { DIRTY_HPTE(HPTE(spapr->htab, i)); @@ -1405,6 +1425,8 @@ static void ppc_spapr_reset(void) /* Check for unknown sysbus devices */ foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL); =20 + qemu_devices_reset(); + if (kvm_enabled() && kvmppc_has_cap_mmu_radix()) { /* If using KVM with radix mode available, VCPUs can be started * without a HPT because KVM will start them in radix mode. @@ -1414,7 +1436,6 @@ static void ppc_spapr_reset(void) spapr_setup_hpt_and_vrma(spapr); } =20 - qemu_devices_reset(); spapr_clear_pending_events(spapr); =20 /* diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index c08ee7571a50..c20b5c64b045 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -73,7 +73,6 @@ void spapr_cpu_parse_features(sPAPRMachineState *spapr) =20 static void spapr_cpu_reset(void *opaque) { - sPAPRMachineState *spapr =3D SPAPR_MACHINE(qdev_get_machine()); PowerPCCPU *cpu =3D opaque; CPUState *cs =3D CPU(cpu); CPUPPCState *env =3D &cpu->env; @@ -86,20 +85,6 @@ static void spapr_cpu_reset(void *opaque) cs->halted =3D 1; =20 env->spr[SPR_HIOR] =3D 0; - - /* - * This is a hack for the benefit of KVM PR - it abuses the SDR1 - * slot in kvm_sregs to communicate the userspace address of the - * HPT - */ - if (kvm_enabled()) { - env->spr[SPR_SDR1] =3D (target_ulong)(uintptr_t)spapr->htab - | (spapr->htab_shift - 18); - if (kvmppc_put_books_sregs(cpu) < 0) { - error_report("Unable to update SDR1 in KVM"); - exit(1); - } - } } =20 static void spapr_cpu_destroy(PowerPCCPU *cpu) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 57bb411394ed..7892cd3e7ffa 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -730,15 +730,7 @@ static target_ulong h_resize_hpt_commit(PowerPCCPU *cp= u, pending->hpt, newsize); if (rc =3D=3D H_SUCCESS) { qemu_vfree(spapr->htab); - spapr->htab =3D pending->hpt; - spapr->htab_shift =3D pending->shift; - - if (kvm_enabled()) { - /* For KVM PR, update the HPT pointer */ - target_ulong sdr1 =3D (target_ulong)(uintptr_t)spapr->htab - | (spapr->htab_shift - 18); - kvmppc_update_sdr1(sdr1); - } + spapr_install_hpt(spapr, pending->hpt, pending->shift); =20 pending->hpt =3D NULL; /* so it's not free()d */ } @@ -1564,12 +1556,6 @@ static target_ulong h_client_architecture_support(Po= werPCCPU *cpu, * the point this is called, nothing should have been * entered into the existing HPT */ spapr_reallocate_hpt(spapr, maxshift, &error_fatal); - if (kvm_enabled()) { - /* For KVM PR, update the HPT pointer */ - target_ulong sdr1 =3D (target_ulong)(uintptr_t)spapr->htab - | (spapr->htab_shift - 18); - kvmppc_update_sdr1(sdr1); - } } } =20 diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index c1b365f56431..30e5805acca4 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -709,4 +709,5 @@ void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_= cpu_data arg); int spapr_vcpu_id(PowerPCCPU *cpu); PowerPCCPU *spapr_find_cpu(int vcpu_id); =20 +void spapr_install_hpt(sPAPRMachineState *spapr, void *htab, uint32_t shif= t); #endif /* HW_SPAPR_H */ From nobody Sun May 5 09:57:24 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505255277670834.5227354047363; Tue, 12 Sep 2017 15:27:57 -0700 (PDT) Received: from localhost ([::1]:38996 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drteu-00051O-Ti for importer@patchew.org; Tue, 12 Sep 2017 18:27:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52242) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtcD-0003DW-So for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:25:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drtc8-0005hF-UD for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:25:09 -0400 Received: from 1.mo2.mail-out.ovh.net ([46.105.63.121]:40812) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drtc8-0005gW-Nz for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:25:04 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id C4F9BAA9F7 for ; Wed, 13 Sep 2017 00:25:03 +0200 (CEST) Received: from bahia.lan (gar31-1-82-66-74-139.fbx.proxad.net [82.66.74.139]) (Authenticated sender: groug@kaod.org) by player770.ha.ovh.net (Postfix) with ESMTPA id 8A5153C006C; Wed, 13 Sep 2017 00:25:01 +0200 (CEST) From: Greg Kurz To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:25:01 +0200 Message-ID: <150525510133.11068.18348168748736729990.stgit@bahia.lan> In-Reply-To: <150525508489.11068.5231444460720976552.stgit@bahia.lan> References: <150525508489.11068.5231444460720976552.stgit@bahia.lan> User-Agent: StGit/0.17.1-46-g6855-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 6827175560286411091 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedvgdduieeiucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 46.105.63.121 Subject: [Qemu-devel] [PATCH v2 2/2] spapr: preserve SDR1 during migration X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 When running with KVM PR, a pseries machine needs to allocate an HPT in userspace and pass its address and size too KVM. This is done at machine reset time by hijacking SDR1. 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 preserving the pre-load value of SDR1. Since this is a spapr specific hack, this is achieved by extending the PPC virtual hypervisor interface. Signed-off-by: Greg Kurz --- hw/ppc/spapr.c | 30 ++++++++++++++++++++++++++++++ target/ppc/cpu.h | 5 +++++ target/ppc/machine.c | 18 ++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 97f8afdbd7fe..aa280c9d767f 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1200,6 +1200,34 @@ static uint64_t spapr_get_patbe(PPCVirtualHypervisor= *vhyp) return spapr->patb_entry; } =20 +static void spapr_cpu_pre_load(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu) +{ + sPAPRMachineState *spapr =3D SPAPR_MACHINE(vhyp); + + /* This is a hack for KVM PR: SDR1 contains the address and size of th= e HPT + * allocated by QEMU. We must preserve it. + */ + if (kvm_enabled() && spapr->htab) { + CPUPPCState *env =3D &cpu->env; + + cpu->sdr1_kvm_pr =3D env->spr[SPR_SDR1]; + } +} + +static void spapr_cpu_post_load(PPCVirtualHypervisor *vhyp, PowerPCCPU *cp= u) +{ + sPAPRMachineState *spapr =3D SPAPR_MACHINE(vhyp); + + /* This is a hack for KVM PR: SDR1 contains the address and size of th= e HPT + * allocated by QEMU. We must preserve it. + */ + if (kvm_enabled() && spapr->htab) { + CPUPPCState *env =3D &cpu->env; + + env->spr[SPR_SDR1] =3D cpu->sdr1_kvm_pr; + } +} + #define HPTE(_table, _i) (void *)(((uint64_t *)(_table)) + ((_i) * 2)) #define HPTE_VALID(_hpte) (tswap64(*((uint64_t *)(_hpte))) & HPTE64_V_VAL= ID) #define HPTE_DIRTY(_hpte) (tswap64(*((uint64_t *)(_hpte))) & HPTE64_V_HPT= E_DIRTY) @@ -3624,6 +3652,8 @@ static void spapr_machine_class_init(ObjectClass *oc,= void *data) vhc->unmap_hptes =3D spapr_unmap_hptes; vhc->store_hpte =3D spapr_store_hpte; vhc->get_patbe =3D spapr_get_patbe; + vhc->cpu_pre_load =3D spapr_cpu_pre_load; + vhc->cpu_post_load =3D spapr_cpu_post_load; xic->ics_get =3D spapr_ics_get; xic->ics_resend =3D spapr_ics_resend; xic->icp_get =3D spapr_icp_get; diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index c9d3ffa89bcb..22ea2538d923 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1212,6 +1212,9 @@ struct PowerPCCPU { uint64_t mig_insns_flags2; uint32_t mig_nb_BATs; bool pre_2_10_migration; + + /* KVM PR hack to preserve SDR1 (HPT) */ + target_ulong sdr1_kvm_pr; }; =20 static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env) @@ -1243,6 +1246,8 @@ struct PPCVirtualHypervisorClass { void (*store_hpte)(PPCVirtualHypervisor *vhyp, hwaddr ptex, uint64_t pte0, uint64_t pte1); uint64_t (*get_patbe)(PPCVirtualHypervisor *vhyp); + void (*cpu_pre_load)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu); + void (*cpu_post_load)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu); }; =20 #define TYPE_PPC_VIRTUAL_HYPERVISOR "ppc-virtual-hypervisor" diff --git a/target/ppc/machine.c b/target/ppc/machine.c index e36b7100cb66..c4d32c886367 100644 --- a/target/ppc/machine.c +++ b/target/ppc/machine.c @@ -218,6 +218,19 @@ static bool pvr_match(PowerPCCPU *cpu, uint32_t pvr) return pcc->pvr_match(pcc, pvr); } =20 +static int cpu_pre_load(void *opaque) +{ + PowerPCCPU *cpu =3D opaque; + + if (cpu->vhyp) { + PPCVirtualHypervisorClass *vhc =3D + PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); + vhc->cpu_pre_load(cpu->vhyp, cpu); + } + + return 0; +} + static int cpu_post_load(void *opaque, int version_id) { PowerPCCPU *cpu =3D opaque; @@ -294,6 +307,10 @@ static int cpu_post_load(void *opaque, int version_id) =20 if (!cpu->vhyp) { ppc_store_sdr1(env, env->spr[SPR_SDR1]); + } else { + PPCVirtualHypervisorClass *vhc =3D + PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); + vhc->cpu_post_load(cpu->vhyp, cpu); } =20 /* Invalidate all msr bits except MSR_TGPR/MSR_HVB before restoring */ @@ -650,6 +667,7 @@ const VMStateDescription vmstate_ppc_cpu =3D { .minimum_version_id_old =3D 4, .load_state_old =3D cpu_load_old, .pre_save =3D cpu_pre_save, + .pre_load =3D cpu_pre_load, .post_load =3D cpu_post_load, .fields =3D (VMStateField[]) { VMSTATE_UNUSED(sizeof(target_ulong)), /* was _EQUAL(env.spr[SPR_PV= R]) */