From nobody Wed May 8 00:23:00 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 (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507007893207712.9747658159306; Mon, 2 Oct 2017 22:18:13 -0700 (PDT) Received: from localhost ([::1]:56184 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dzFap-0007cJ-T6 for importer@patchew.org; Tue, 03 Oct 2017 01:18:07 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57722) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dzFZw-0007Cs-3C for qemu-devel@nongnu.org; Tue, 03 Oct 2017 01:17:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dzFZr-0000xt-NI for qemu-devel@nongnu.org; Tue, 03 Oct 2017 01:17:12 -0400 Received: from ozlabs.ru ([107.173.13.209]:37010) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dzFZr-0000uJ-Ec; Tue, 03 Oct 2017 01:17:07 -0400 Received: from vpl1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 336F03A60479; Tue, 3 Oct 2017 01:15:46 -0400 (EDT) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Tue, 3 Oct 2017 16:17:01 +1100 Message-Id: <20171003051701.17721-1-aik@ozlabs.ru> X-Mailer: git-send-email 2.11.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 107.173.13.209 Subject: [Qemu-devel] [RFC PATCH qemu v2] ppc/spapr: Receive and store device tree blob from SLOF 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: Alexey Kardashevskiy , Aravinda Prasad , Balbir Singh , 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 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" SLOF receives a device tree and updates it with various properties before switching to the guest kernel and QEMU is not aware of any changes made by SLOF. Since there is no real RTAS and QEMU implements it, it makes sense to pass the SLOF device tree to QEMU so the latter could implement RTAS related tasks better. Specifially, now QEMU can find out the actual XICS phandle (for PHB hotplug) and the RTAS linux,rtas-entry/base properties (for firmware assisted NMI - FWNMI). This stores the initial DT blob in the sPAPR machine and replaces it in the KVMPPC_H_UPDATE_DT (new private hypercall) handler. This implements a very basic validity check of the new blob - magic and size are checked; the new blob size should not increase more than twice. This requires SLOF update: "fdt: Pass the resulting device tree to QEMU". Signed-off-by: Alexey Kardashevskiy --- I could store just a size of the QEMU's blob, or a tree, not sure which one makes more sense here. This allows up to 2 times blob increase. Not 1.5 just to avoid float/double, just looks a bit ugly imho. --- include/hw/ppc/spapr.h | 4 +++- hw/ppc/spapr.c | 4 +++- hw/ppc/spapr_hcall.c | 33 +++++++++++++++++++++++++++++++++ hw/ppc/trace-events | 2 ++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index a805b817a5..09f3a54dc2 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -92,6 +92,7 @@ struct sPAPRMachineState { int vrma_adjust; ssize_t rtas_size; void *rtas_blob; + void *fdt_blob; long kernel_size; bool kernel_le; uint32_t initrd_base; @@ -400,7 +401,8 @@ struct sPAPRMachineState { #define KVMPPC_H_LOGICAL_MEMOP (KVMPPC_HCALL_BASE + 0x1) /* Client Architecture support */ #define KVMPPC_H_CAS (KVMPPC_HCALL_BASE + 0x2) -#define KVMPPC_HCALL_MAX KVMPPC_H_CAS +#define KVMPPC_H_UPDATE_DT (KVMPPC_HCALL_BASE + 0x3) +#define KVMPPC_HCALL_MAX KVMPPC_H_UPDATE_DT =20 typedef struct sPAPRDeviceTreeUpdateHeader { uint32_t version_id; diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 17ea77618c..b471f7e1ff 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1453,7 +1453,9 @@ static void ppc_spapr_reset(void) /* Load the fdt */ qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt)); cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt)); - g_free(fdt); + g_free(spapr->fdt_blob); + spapr->fdt_blob =3D fdt; + spapr->fdt_size =3D fdt_totalsize(fdt); =20 /* Set up the entry state */ first_ppc_cpu =3D POWERPC_CPU(first_cpu); diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 57bb411394..a11831d3b2 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1635,6 +1635,37 @@ static target_ulong h_client_architecture_support(Po= werPCCPU *cpu, return H_SUCCESS; } =20 +static target_ulong h_update_dt(PowerPCCPU *cpu, sPAPRMachineState *spapr, + target_ulong opcode, target_ulong *args) +{ + target_ulong dt =3D ppc64_phys_to_real(args[0]); + struct fdt_header hdr =3D { 0 }; + unsigned cb, magic, old_cb =3D fdt_totalsize(spapr->fdt_blob); + + cpu_physical_memory_read(dt, &hdr, sizeof(hdr)); + cb =3D fdt32_to_cpu(hdr.totalsize); + magic =3D fdt32_to_cpu(hdr.magic); + if (magic !=3D FDT_MAGIC || cb / old_cb > 2) { + trace_spapr_update_dt_failed(old_cb, cb, magic); + return H_PARAMETER; + } + + g_free(spapr->fdt_blob); + spapr->fdt_blob =3D g_malloc0(cb); + cpu_physical_memory_read(dt, spapr->fdt_blob, cb); + +#ifdef DEBUG + { + FILE *f =3D fopen("dbg.dtb", "wb"); + fwrite(spapr->fdt_blob, cb, 1, f); + fclose(f); + } +#endif + trace_spapr_update_dt(cb); + + return H_SUCCESS; +} + static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1]; static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCA= LL_BASE + 1]; =20 @@ -1732,6 +1763,8 @@ static void hypercall_register_types(void) =20 /* ibm,client-architecture-support support */ spapr_register_hypercall(KVMPPC_H_CAS, h_client_architecture_support); + + spapr_register_hypercall(KVMPPC_H_UPDATE_DT, h_update_dt); } =20 type_init(hypercall_register_types) diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events index 4a6a6490fa..60ee4e3a4b 100644 --- a/hw/ppc/trace-events +++ b/hw/ppc/trace-events @@ -18,6 +18,8 @@ spapr_cas_pvr_try(uint32_t pvr) "0x%x" spapr_cas_pvr(uint32_t cur_pvr, bool explicit_match, uint32_t new_pvr) "cu= rrent=3D0x%x, explicit_match=3D%u, new=3D0x%x" spapr_h_resize_hpt_prepare(uint64_t flags, uint64_t shift) "flags=3D0x%"PR= Ix64", shift=3D%"PRIu64 spapr_h_resize_hpt_commit(uint64_t flags, uint64_t shift) "flags=3D0x%"PRI= x64", shift=3D%"PRIu64 +spapr_update_dt(unsigned cb) "New blob %u bytes" +spapr_update_dt_failed(unsigned cbold, unsigned cbnew, unsigned magic) "Ol= d blob %u bytes, new blob %u bytes, magic 0x%x" =20 # hw/ppc/spapr_iommu.c spapr_iommu_put(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t ret)= "liobn=3D0x%"PRIx64" ioba=3D0x%"PRIx64" tce=3D0x%"PRIx64" ret=3D%"PRId64 --=20 2.11.0