From patchwork Tue Dec 17 04:42:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11296655 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7E29F6C1 for ; Tue, 17 Dec 2019 05:20:22 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 53FC02072D for ; Tue, 17 Dec 2019 05:20:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="M5UZYxJf" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 53FC02072D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:35696 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ih5HQ-00017U-Uj for patchwork-qemu-devel@patchwork.kernel.org; Tue, 17 Dec 2019 00:20:20 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35074) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ih4ji-00027S-7Q for qemu-devel@nongnu.org; Mon, 16 Dec 2019 23:45:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ih4jf-0007Ul-Mk for qemu-devel@nongnu.org; Mon, 16 Dec 2019 23:45:30 -0500 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:33205 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ih4je-00070D-C9; Mon, 16 Dec 2019 23:45:26 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 47cQWd03LLz9sTF; Tue, 17 Dec 2019 15:43:37 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1576557821; bh=teDKDGq3dNeff5zj6qtCOnSpMhJGW5rjS89bzWKzkDA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=M5UZYxJf0e5jTMYIEWYM6vyLSLTbF6kSn+ROf0UpdZTpUM2vKXYruHWIM5twlnb4y +ISC+Ib882K64EUA/Ioiix/Ck8/Sba/DDoqJzhv8KQq2Y8WVLkiJxsAlpk1FvycMAH DLflyAMfg/rUJT1ZfHzCLI1eW8fftV5iBeNoh+nc= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 53/88] spapr: Improve handling of fdt buffer size Date: Tue, 17 Dec 2019 15:42:47 +1100 Message-Id: <20191217044322.351838-54-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191217044322.351838-1-david@gibson.dropbear.id.au> References: <20191217044322.351838-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, Cedric Le Goater , qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Previously, spapr_build_fdt() constructed the device tree in a fixed buffer of size FDT_MAX_SIZE. This is a bit inflexible, but more importantly it's awkward for the case where we use it during CAS. In that case the guest firmware supplies a buffer and we have to awkwardly check that what we generated fits into it afterwards, after doing a lot of size checks during spapr_build_fdt(). Simplify this by having spapr_build_fdt() take a 'space' parameter. For the CAS case, we pass in the buffer size provided by SLOF, for the machine init case, we continue to pass FDT_MAX_SIZE. Signed-off-by: David Gibson Reviewed-by: Cedric Le Goater Reviewed-by: Greg Kurz --- hw/ppc/spapr.c | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index e3c7d487b8..df5bea1bd4 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -917,7 +917,8 @@ static bool spapr_hotplugged_dev_before_cas(void) return false; } -static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset); +static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset, + size_t space); int spapr_h_cas_compose_response(SpaprMachineState *spapr, target_ulong addr, target_ulong size, @@ -930,24 +931,17 @@ int spapr_h_cas_compose_response(SpaprMachineState *spapr, return 1; } - if (size < sizeof(hdr) || size > FW_MAX_SIZE) { - error_report("SLOF provided an unexpected CAS buffer size " - TARGET_FMT_lu " (min: %zu, max: %u)", - size, sizeof(hdr), FW_MAX_SIZE); + if (size < sizeof(hdr)) { + error_report("SLOF provided insufficient CAS buffer " + TARGET_FMT_lu " (min: %zu)", size, sizeof(hdr)); exit(EXIT_FAILURE); } size -= sizeof(hdr); - fdt = spapr_build_fdt(spapr, false); + fdt = spapr_build_fdt(spapr, false, size); _FDT((fdt_pack(fdt))); - if (fdt_totalsize(fdt) + sizeof(hdr) > size) { - g_free(fdt); - trace_spapr_cas_failed(size); - return -1; - } - cpu_physical_memory_write(addr, &hdr, sizeof(hdr)); cpu_physical_memory_write(addr + sizeof(hdr), fdt, fdt_totalsize(fdt)); trace_spapr_cas_continue(fdt_totalsize(fdt) + sizeof(hdr)); @@ -1197,7 +1191,8 @@ static void spapr_dt_hypervisor(SpaprMachineState *spapr, void *fdt) } } -static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset) +static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset, + size_t space) { MachineState *machine = MACHINE(spapr); MachineClass *mc = MACHINE_GET_CLASS(machine); @@ -1207,8 +1202,8 @@ static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset) SpaprPhbState *phb; char *buf; - fdt = g_malloc0(FDT_MAX_SIZE); - _FDT((fdt_create_empty_tree(fdt, FDT_MAX_SIZE))); + fdt = g_malloc0(space); + _FDT((fdt_create_empty_tree(fdt, space))); /* Root node */ _FDT(fdt_setprop_string(fdt, 0, "device_type", "chrp")); @@ -1723,19 +1718,13 @@ static void spapr_machine_reset(MachineState *machine) */ fdt_addr = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FDT_MAX_SIZE; - fdt = spapr_build_fdt(spapr, true); + fdt = spapr_build_fdt(spapr, true, FDT_MAX_SIZE); rc = fdt_pack(fdt); /* Should only fail if we've built a corrupted tree */ assert(rc == 0); - if (fdt_totalsize(fdt) > FDT_MAX_SIZE) { - error_report("FDT too big ! 0x%x bytes (max is 0x%x)", - fdt_totalsize(fdt), FDT_MAX_SIZE); - exit(1); - } - /* Load the fdt */ qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt)); cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));