From nobody Sun May 19 10:14:39 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=oracle.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1628602965480116.2525916038793; Tue, 10 Aug 2021 06:42:45 -0700 (PDT) Received: from localhost ([::1]:41372 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mDS1k-0001r7-Ag for importer@patchew.org; Tue, 10 Aug 2021 09:42:44 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42602) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mDS0C-0007GA-TC; Tue, 10 Aug 2021 09:41:08 -0400 Received: from forward3-smtp.messagingengine.com ([66.111.4.237]:46223) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mDS08-0003hp-Rg; Tue, 10 Aug 2021 09:41:08 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailforward.nyi.internal (Postfix) with ESMTP id 3FD36194009B; Tue, 10 Aug 2021 09:41:01 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Tue, 10 Aug 2021 09:41:01 -0400 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 10 Aug 2021 09:40:53 -0400 (EDT) Received: from localhost (disaster-area.hh.sledj.net [local]) by disaster-area.hh.sledj.net (OpenSMTPD) with ESMTPA id a555f518; Tue, 10 Aug 2021 13:40:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=B7yw234pFsdlhlhxFOpTGWvxm5kTKGDXEngEIAXEhMk=; b=uP85APQq y2gyKcmmvscMiYWdtLq+tTS+znnD8y499eaRiFdJ+TOjqYlFl0IOhEj4//e4gs5b AqypzEL9qCdYOnYjzaFGBIm9AlQiJtiq1jW8w/s2x9B6YZoRSoxtSFddMWDwa8dc 5ZkOJ9l2eVdCttRzUalrSD/ow8O6SpTjd0dgyvn7KCfKZtlb/1AXipldMNWuHVqb g38qaq0UEfA1VwTYp3VwDLQIGo3ake80FWACI5gbOUgX2dMbCuaszDvUpLLBo1LR /6k5EH2XDQlYxxJevLkSOP6aVkI+kc+iphmCLbUHgMVqdGrAKbTsMZetyts751+Z VuQYROM2XRJhmg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrjeelgdeikecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepffgrvhhiugcu gfgumhhonhgushhonhcuoegurghvihgurdgvughmohhnughsohhnsehorhgrtghlvgdrtg homheqnecuggftrfgrthhtvghrnhepudefteejgfefhfdtjefhhedtffethfetkeehgfel heffhfeihfeglefgjedtheeknecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpe hmrghilhhfrhhomhepuggrvhhiugdrvggumhhonhgushhonhesohhrrggtlhgvrdgtohhm X-ME-Proxy: From: David Edmondson To: qemu-devel@nongnu.org Subject: [PATCH v4 1/1] hw/pflash_cfi01: Allow backing devices to be smaller than memory region Date: Tue, 10 Aug 2021 14:40:50 +0100 Message-Id: <20210810134050.396747-2-david.edmondson@oracle.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210810134050.396747-1-david.edmondson@oracle.com> References: <20210810134050.396747-1-david.edmondson@oracle.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: softfail client-ip=66.111.4.237; envelope-from=david.edmondson@oracle.com; helo=forward3-smtp.messagingengine.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_PASS=-0.001, SPF_SOFTFAIL=0.665, UNPARSEABLE_RELAY=0.001 autolearn=no autolearn_force=no X-Spam_action: no action 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: Kevin Wolf , Peter Maydell , qemu-block@nongnu.org, "Michael S. Tsirkin" , Xu Yandong , John Snow , Markus Armbruster , Max Reitz , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Shannon Zhao , Zheng Xiang , qemu-arm@nongnu.org, =?UTF-8?q?haibinzhang=28=E5=BC=A0=E6=B5=B7=E6=96=8C=29?= , Stefan Hajnoczi , Paolo Bonzini , Igor Mammedov , David Edmondson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Stefano Garzarella Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1628602966456100005 Content-Type: text/plain; charset="utf-8" Allow the backing device to be smaller than the extent of the flash device by mapping it as a subregion of the flash device region. Return zeroes for all reads of the flash device beyond the extent of the backing device. For writes beyond the extent of the underlying device, fail on read-only devices and discard them for writable devices. Signed-off-by: David Edmondson --- hw/block/pflash_cfi01.c | 105 ++++++++++++++++++++++++++++++++-------- hw/block/trace-events | 3 ++ 2 files changed, 87 insertions(+), 21 deletions(-) diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 81f9f971d8..f3289b6a2f 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -83,6 +83,8 @@ struct PFlashCFI01 { uint64_t counter; unsigned int writeblock_size; MemoryRegion mem; + MemoryRegion mem_outer; + char outer_name[64]; char *name; void *storage; VMChangeStateEntry *vmstate; @@ -434,7 +436,6 @@ static inline void pflash_data_write(PFlashCFI01 *pfl, = hwaddr offset, } break; } - } =20 static void pflash_write(PFlashCFI01 *pfl, hwaddr offset, @@ -656,8 +657,44 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offs= et, } =20 =20 -static MemTxResult pflash_mem_read_with_attrs(void *opaque, hwaddr addr, u= int64_t *value, - unsigned len, MemTxAttrs att= rs) +static MemTxResult pflash_outer_read_with_attrs(void *opaque, hwaddr addr, + uint64_t *value, unsigned = len, + MemTxAttrs attrs) +{ + PFlashCFI01 *pfl =3D opaque; + + trace_pflash_outer_read(pfl->name, addr, len); + *value =3D 0; + return MEMTX_OK; +} + +static MemTxResult pflash_outer_write_with_attrs(void *opaque, hwaddr addr, + uint64_t value, unsigned = len, + MemTxAttrs attrs) +{ + PFlashCFI01 *pfl =3D opaque; + + trace_pflash_outer_write(pfl->name, addr, len); + if (pfl->ro) { + return MEMTX_ERROR; + } else { + warn_report_once("%s: " + "attempt to write outside of the backing block de= vice " + "(offset " TARGET_FMT_plx ") ignored", + pfl->name, addr); + return MEMTX_OK; + } +} + +static const MemoryRegionOps pflash_cfi01_outer_ops =3D { + .read_with_attrs =3D pflash_outer_read_with_attrs, + .write_with_attrs =3D pflash_outer_write_with_attrs, + .endianness =3D DEVICE_NATIVE_ENDIAN, +}; + +static MemTxResult pflash_mem_read_with_attrs(void *opaque, hwaddr addr, + uint64_t *value, unsigned le= n, + MemTxAttrs attrs) { PFlashCFI01 *pfl =3D opaque; bool be =3D !!(pfl->features & (1 << PFLASH_BE)); @@ -670,8 +707,9 @@ static MemTxResult pflash_mem_read_with_attrs(void *opa= que, hwaddr addr, uint64_ return MEMTX_OK; } =20 -static MemTxResult pflash_mem_write_with_attrs(void *opaque, hwaddr addr, = uint64_t value, - unsigned len, MemTxAttrs at= trs) +static MemTxResult pflash_mem_write_with_attrs(void *opaque, hwaddr addr, + uint64_t value, unsigned le= n, + MemTxAttrs attrs) { PFlashCFI01 *pfl =3D opaque; bool be =3D !!(pfl->features & (1 << PFLASH_BE)); @@ -800,7 +838,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Erro= r **errp) { ERRP_GUARD(); PFlashCFI01 *pfl =3D PFLASH_CFI01(dev); - uint64_t total_len; + uint64_t outer_len, inner_len; int ret; =20 if (pfl->sector_len =3D=3D 0) { @@ -816,35 +854,60 @@ static void pflash_cfi01_realize(DeviceState *dev, Er= ror **errp) return; } =20 - total_len =3D pfl->sector_len * pfl->nb_blocs; - - memory_region_init_rom_device( - &pfl->mem, OBJECT(dev), - &pflash_cfi01_ops, - pfl, - pfl->name, total_len, errp); - if (*errp) { - return; - } - - pfl->storage =3D memory_region_get_ram_ptr(&pfl->mem); - sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem); + outer_len =3D pfl->sector_len * pfl->nb_blocs; =20 if (pfl->blk) { uint64_t perm; + pfl->ro =3D !blk_supports_write_perm(pfl->blk); perm =3D BLK_PERM_CONSISTENT_READ | (pfl->ro ? 0 : BLK_PERM_WRITE); ret =3D blk_set_perm(pfl->blk, perm, BLK_PERM_ALL, errp); if (ret < 0) { return; } + + inner_len =3D blk_getlength(pfl->blk); + + if (inner_len > outer_len) { + error_setg(errp, "%s: " + "block backend provides %" PRIu64 " bytes, " + "device limited to %" PRIu64 " bytes", + pfl->name, inner_len, outer_len); + return; + } } else { pfl->ro =3D false; + inner_len =3D outer_len; } =20 + trace_pflash_realize(pfl->name, pfl->ro, inner_len, outer_len); + + snprintf(pfl->outer_name, sizeof(pfl->outer_name), + "%s container", pfl->name); + memory_region_init_io(&pfl->mem_outer, OBJECT(dev), + &pflash_cfi01_outer_ops, + pfl, pfl->outer_name, outer_len); + + memory_region_init_rom_device(&pfl->mem, OBJECT(dev), + &pflash_cfi01_ops, + pfl, pfl->name, inner_len, errp); + if (*errp) { + return; + } + + memory_region_add_subregion(&pfl->mem_outer, 0, &pfl->mem); + + pfl->storage =3D memory_region_get_ram_ptr(&pfl->mem); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem_outer); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem); + if (pfl->blk) { - if (!blk_check_size_and_read_all(pfl->blk, pfl->storage, total_len, - errp)) { + int ret =3D blk_pread(pfl->blk, 0, pfl->storage, inner_len); + + if (ret < 0) { + error_setg_errno(errp, -ret, + "cannot read %" PRIu64 " " + "bytes from block backend", inner_len); vmstate_unregister_ram(&pfl->mem, DEVICE(pfl)); return; } diff --git a/hw/block/trace-events b/hw/block/trace-events index d86b53520c..3d1e07261e 100644 --- a/hw/block/trace-events +++ b/hw/block/trace-events @@ -21,10 +21,13 @@ pflash_io_read(const char *name, uint64_t offset, unsig= ned int size, uint32_t va pflash_io_write(const char *name, uint64_t offset, unsigned int size, uint= 32_t value, uint8_t wcycle) "%s: offset:0x%04"PRIx64" size:%u value:0x%04x = wcycle:%u" pflash_manufacturer_id(const char *name, uint16_t id) "%s: read manufactur= er ID: 0x%04x" pflash_mode_read_array(const char *name) "%s: read array mode" +pflash_outer_read(const char *name, uint64_t addr, unsigned int len) "%s: = addr:0x%" PRIx64 " len:%d" +pflash_outer_write(const char *name, uint64_t addr, unsigned int len) "%s:= addr:0x%" PRIx64 " len:%d" pflash_postload_cb(const char *name) "%s: updating bdrv" pflash_read_done(const char *name, uint64_t offset, uint64_t ret) "%s: ID:= 0x%" PRIx64 " ret:0x%" PRIx64 pflash_read_status(const char *name, uint32_t ret) "%s: status:0x%x" pflash_read_unknown_state(const char *name, uint8_t cmd) "%s: unknown comm= and state:0x%x" +pflash_realize(const char *name, bool ro, uint64_t blk_len, uint64_t total= _len) "%s: ro:%d blk_len:0x%" PRIx64 " total_len:0x%" PRIx64 pflash_reset(const char *name) "%s: reset" pflash_sector_erase_start(const char *name, int width1, uint64_t start, in= t width2, uint64_t end) "%s: start sector erase at: 0x%0*" PRIx64 "-0x%0*" = PRIx64 pflash_timer_expired(const char *name, uint8_t cmd) "%s: command 0x%02x do= ne" --=20 2.30.2