Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.0/patches/2175187/?format=api
{ "id": 2175187, "url": "http://patchwork.ozlabs.org/api/1.0/patches/2175187/?format=api", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/1.0/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20251217143150.94463-8-philmd@linaro.org>", "date": "2025-12-17T14:31:43", "name": "[07/14] system/memory: Split MemoryRegionCache API to 'memory_cached.h'", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "bc27e28e232c667f30853d2d1a7460126ddf5aa0", "submitter": { "id": 85046, "url": "http://patchwork.ozlabs.org/api/1.0/people/85046/?format=api", "name": "Philippe Mathieu-Daudé", "email": "philmd@linaro.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20251217143150.94463-8-philmd@linaro.org/mbox/", "series": [ { "id": 485701, "url": "http://patchwork.ozlabs.org/api/1.0/series/485701/?format=api", "date": "2025-12-17T14:31:37", "name": "system/memory: Clean ups around address_space_ldst() endian variants", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/485701/mbox/" } ], "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2175187/checks/", "tags": {}, "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256\n header.s=google header.b=VveX+igS;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4dWbvF1wSdz1xty\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 18 Dec 2025 01:35:53 +1100 (AEDT)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1vVsaX-00021L-VO; Wed, 17 Dec 2025 09:33:13 -0500", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <philmd@linaro.org>) id 1vVsaG-0001k6-Or\n for qemu-devel@nongnu.org; Wed, 17 Dec 2025 09:32:58 -0500", "from mail-wm1-x32b.google.com ([2a00:1450:4864:20::32b])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <philmd@linaro.org>) id 1vVsaB-0007C6-CI\n for qemu-devel@nongnu.org; Wed, 17 Dec 2025 09:32:53 -0500", "by mail-wm1-x32b.google.com with SMTP id\n 5b1f17b1804b1-47796a837c7so43028935e9.0\n for <qemu-devel@nongnu.org>; Wed, 17 Dec 2025 06:32:49 -0800 (PST)", "from localhost.localdomain (88-187-86-199.subs.proxad.net.\n [88.187.86.199]) by smtp.gmail.com with ESMTPSA id\n 5b1f17b1804b1-47bd9cc37f0sm30740305e9.4.2025.12.17.06.32.44\n (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256);\n Wed, 17 Dec 2025 06:32:44 -0800 (PST)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=linaro.org; s=google; t=1765981967; x=1766586767; darn=nongnu.org;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=6YAsph7okBK8AuJ8n8nNBWNPp4wOy6eiaeIdpcOIdYY=;\n b=VveX+igSFvrtusPx/FyTD/Y9PBxYGuqxcK62/ua6hafa6f4wE6U7pZ6IoqG171W3PK\n BIQe69Iyd1iQcfDIMX5ZRbkmH5qc4jklZiYhUuQXGI/q9X5ZyA/7dLvzguYTidsaGp6k\n bY2AsnX0G4V4/3hqNIwD4E7Wo+1KFGcJz5DgIDuciueNPTyUS/R7HYj42NgB0z01aqdJ\n p+97Y2/4oXyWlwq5Fog1+RZzKRtIV83GBT5SF2n3Byf4mdDxKR60pZwPcKvQrqAUHyEu\n uTzRu5K0V9QYBD69k+yyvj9KIzzcPkRo8H5vo9Z85GH80+aBvGSUpWyvtwn0Flx9wurL\n dqJA==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1765981967; x=1766586767;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=6YAsph7okBK8AuJ8n8nNBWNPp4wOy6eiaeIdpcOIdYY=;\n b=G+4XbykJl5tH3WoQkwWRrsu7h2V6zLZY3MN7GH6sWRTHhA5y8geBjiO9BLEz2ySW12\n sJDQSmRXccmmZNX8yiu8TzUxxLENPYGzroxueCq+ef+Q9gQqgQg0K/W0V7xf9CCmZ4hj\n DJHL+S1tefFLrTgn3fttXuyhLZ9NLV3CHD83oAWVxYFIxXe32N7xJz8dnllUkgfuj8GL\n Fhsx3ZyU9GDCfHH0dKN9tsoVYbgf+bbSRQ2DiCoyAMq5hUmN5x1CAS0S2G2Fi+zB/av2\n XGRgsmmPjmkHxZbJ1xu7Kt9lkcrwsYFMoxo6tmajZTzkBqHS9RMzPmAVWKKhMkZxM8wE\n EkWQ==", "X-Gm-Message-State": "AOJu0Yzq8pi/rophYum+IqFOEb+fIihyPnrsebgLDw4RuGVKRzIEyj5Y\n yu0TK1bmv6/BWACcpdGyB99tnJJYv0aiZMqfhTPbC9OSZeQ7TkCbpx6D2wt7NyWHMe4mIbW48Je\n rhbWdXmsU8w==", "X-Gm-Gg": "AY/fxX489ecfxo61Vm4c1BXGt3BSKU5YMNFKEume35kv2UiwlUG+IR/KUrNhE1U0L1j\n 3z3F8HKmo6Ge/W1Rh9nqS+q8tiMKMXLTYJgNFpKR1VMOuApsX+tWnvqAS25k0gFY3gjJuXQzhuG\n 3FHvNcCJJOwleb6eK3STgq12NAY9kbDbXewHAbURqaDvIvl2fhT0VWsJEfIPWSLeZO4U1pbnW5P\n mkXdIzE6xZtenW+OQXcMgXmwl1dEib6JMIFvampF69HmAzzA9NitWGeo7hKMNZ/YuoSf5TDr9sE\n mZai8glNJf5mna44Q8I8nxSUYiKhX0FqD9AFJN5WEWf2RPXuLzoE+iMNekJrvLKky+8IkfnAAkp\n 83U4ShXrE6qs20o52BNOib8vaJ4y1Y+5J8dfAd5L7x2uEvD+mHFAXCmbC9YY8fefelAeczs6yPD\n f/FjKsDDchbec1zNaQRL0c7/B6+B1mtNjYPK+fSg3SuYlkeTgr0gj2Eg49lLJi", "X-Google-Smtp-Source": "\n AGHT+IFf79uMo8hEMhvgn211ETxm0/XeKA7EJwP8+cGqkOr1q7YBaCl5QACRDU32If929/+b35/BzQ==", "X-Received": "by 2002:a05:600c:6748:b0:479:2f95:5179 with SMTP id\n 5b1f17b1804b1-47a8f8c380emr172015875e9.15.1765981967082;\n Wed, 17 Dec 2025 06:32:47 -0800 (PST)", "From": "=?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= <philmd@linaro.org>", "To": "qemu-devel@nongnu.org", "Cc": "=?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= <philmd@linaro.org>,\n Anton Johansson <anjo@rev.ng>, qemu-arm@nongnu.org,\n Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>,\n Paolo Bonzini <pbonzini@redhat.com>, \"Michael S. Tsirkin\" <mst@redhat.com>,\n Artyom Tarasenko <atar4qemu@gmail.com>,\n Peter Maydell <peter.maydell@linaro.org>,\n David Hildenbrand <david@kernel.org>, Peter Xu <peterx@redhat.com>", "Subject": "[PATCH 07/14] system/memory: Split MemoryRegionCache API to\n 'memory_cached.h'", "Date": "Wed, 17 Dec 2025 15:31:43 +0100", "Message-ID": "<20251217143150.94463-8-philmd@linaro.org>", "X-Mailer": "git-send-email 2.52.0", "In-Reply-To": "<20251217143150.94463-1-philmd@linaro.org>", "References": "<20251217143150.94463-1-philmd@linaro.org>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "Received-SPF": "pass client-ip=2a00:1450:4864:20::32b;\n envelope-from=philmd@linaro.org; helo=mail-wm1-x32b.google.com", "X-Spam_score_int": "-20", "X-Spam_score": "-2.1", "X-Spam_bar": "--", "X-Spam_report": "(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,\n SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no", "X-Spam_action": "no action", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org" }, "content": "We have 115 direct inclusions of \"system/memory.h\", and 91 headers\nin include/ use it: hundreds of files have to process it.\nHowever only one single header really uses the MemoryRegionCache\nAPI: \"hw/virtio/virtio-access.h\". Split it out to a new header,\navoiding processing unused inlined functions hundreds of times.\n\nSigned-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>\n---\n MAINTAINERS | 1 +\n include/hw/virtio/virtio-access.h | 1 +\n include/system/memory.h | 185 --------------------------\n include/system/memory_cached.h | 207 ++++++++++++++++++++++++++++++\n system/physmem.c | 1 +\n 5 files changed, 210 insertions(+), 185 deletions(-)\n create mode 100644 include/system/memory_cached.h", "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex 63e9ba521bc..c299b84d418 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -3255,6 +3255,7 @@ S: Supported\n F: include/system/ioport.h\n F: include/exec/memop.h\n F: include/system/memory.h\n+F: include/system/memory_cached.h\n F: include/system/physmem.h\n F: include/system/ram_addr.h\n F: include/system/ramblock.h\ndiff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h\nindex 07aae69042a..3ea3acfe05a 100644\n--- a/include/hw/virtio/virtio-access.h\n+++ b/include/hw/virtio/virtio-access.h\n@@ -17,6 +17,7 @@\n #define QEMU_VIRTIO_ACCESS_H\n \n #include \"exec/hwaddr.h\"\n+#include \"system/memory_cached.h\"\n #include \"hw/virtio/virtio.h\"\n #include \"hw/virtio/virtio-bus.h\"\n \ndiff --git a/include/system/memory.h b/include/system/memory.h\nindex e69171de05a..90f375df5df 100644\n--- a/include/system/memory.h\n+++ b/include/system/memory.h\n@@ -2855,140 +2855,6 @@ MemTxResult address_space_write_rom(AddressSpace *as, hwaddr addr,\n #define ARG1_DECL AddressSpace *as\n #include \"exec/memory_ldst_phys.h.inc\"\n \n-struct MemoryRegionCache {\n- uint8_t *ptr;\n- hwaddr xlat;\n- hwaddr len;\n- FlatView *fv;\n- MemoryRegionSection mrs;\n- bool is_write;\n-};\n-\n-/* address_space_ld*_cached: load from a cached #MemoryRegion\n- * address_space_st*_cached: store into a cached #MemoryRegion\n- *\n- * These functions perform a load or store of the byte, word,\n- * longword or quad to the specified address. The address is\n- * a physical address in the AddressSpace, but it must lie within\n- * a #MemoryRegion that was mapped with address_space_cache_init.\n- *\n- * The _le suffixed functions treat the data as little endian;\n- * _be indicates big endian; no suffix indicates \"same endianness\n- * as guest CPU\".\n- *\n- * The \"guest CPU endianness\" accessors are deprecated for use outside\n- * target-* code; devices should be CPU-agnostic and use either the LE\n- * or the BE accessors.\n- *\n- * @cache: previously initialized #MemoryRegionCache to be accessed\n- * @addr: address within the address space\n- * @val: data value, for stores\n- * @attrs: memory transaction attributes\n- * @result: location to write the success/failure of the transaction;\n- * if NULL, this information is discarded\n- */\n-\n-#define SUFFIX _cached_slow\n-#define ARG1 cache\n-#define ARG1_DECL MemoryRegionCache *cache\n-#include \"exec/memory_ldst.h.inc\"\n-\n-/* Inline fast path for direct RAM access. */\n-static inline uint8_t address_space_ldub_cached(MemoryRegionCache *cache,\n- hwaddr addr, MemTxAttrs attrs, MemTxResult *result)\n-{\n- assert(addr < cache->len);\n- if (likely(cache->ptr)) {\n- return ldub_p(cache->ptr + addr);\n- } else {\n- return address_space_ldub_cached_slow(cache, addr, attrs, result);\n- }\n-}\n-\n-static inline void address_space_stb_cached(MemoryRegionCache *cache,\n- hwaddr addr, uint8_t val, MemTxAttrs attrs, MemTxResult *result)\n-{\n- assert(addr < cache->len);\n- if (likely(cache->ptr)) {\n- stb_p(cache->ptr + addr, val);\n- } else {\n- address_space_stb_cached_slow(cache, addr, val, attrs, result);\n- }\n-}\n-\n-#define ENDIANNESS\n-#include \"exec/memory_ldst_cached.h.inc\"\n-\n-#define ENDIANNESS _le\n-#include \"exec/memory_ldst_cached.h.inc\"\n-\n-#define ENDIANNESS _be\n-#include \"exec/memory_ldst_cached.h.inc\"\n-\n-#define SUFFIX _cached\n-#define ARG1 cache\n-#define ARG1_DECL MemoryRegionCache *cache\n-#include \"exec/memory_ldst_phys.h.inc\"\n-\n-/* address_space_cache_init: prepare for repeated access to a physical\n- * memory region\n- *\n- * @cache: #MemoryRegionCache to be filled\n- * @as: #AddressSpace to be accessed\n- * @addr: address within that address space\n- * @len: length of buffer\n- * @is_write: indicates the transfer direction\n- *\n- * Will only work with RAM, and may map a subset of the requested range by\n- * returning a value that is less than @len. On failure, return a negative\n- * errno value.\n- *\n- * Because it only works with RAM, this function can be used for\n- * read-modify-write operations. In this case, is_write should be %true.\n- *\n- * Note that addresses passed to the address_space_*_cached functions\n- * are relative to @addr.\n- */\n-int64_t address_space_cache_init(MemoryRegionCache *cache,\n- AddressSpace *as,\n- hwaddr addr,\n- hwaddr len,\n- bool is_write);\n-\n-/**\n- * address_space_cache_init_empty: Initialize empty #MemoryRegionCache\n- *\n- * @cache: The #MemoryRegionCache to operate on.\n- *\n- * Initializes #MemoryRegionCache structure without memory region attached.\n- * Cache initialized this way can only be safely destroyed, but not used.\n- */\n-static inline void address_space_cache_init_empty(MemoryRegionCache *cache)\n-{\n- cache->mrs.mr = NULL;\n- /* There is no real need to initialize fv, but it makes Coverity happy. */\n- cache->fv = NULL;\n-}\n-\n-/**\n- * address_space_cache_invalidate: complete a write to a #MemoryRegionCache\n- *\n- * @cache: The #MemoryRegionCache to operate on.\n- * @addr: The first physical address that was written, relative to the\n- * address that was passed to @address_space_cache_init.\n- * @access_len: The number of bytes that were written starting at @addr.\n- */\n-void address_space_cache_invalidate(MemoryRegionCache *cache,\n- hwaddr addr,\n- hwaddr access_len);\n-\n-/**\n- * address_space_cache_destroy: free a #MemoryRegionCache\n- *\n- * @cache: The #MemoryRegionCache whose memory should be released.\n- */\n-void address_space_cache_destroy(MemoryRegionCache *cache);\n-\n void address_space_flush_icache_range(AddressSpace *as, hwaddr addr, hwaddr len);\n \n /* address_space_get_iotlb_entry: translate an address into an IOTLB\n@@ -3116,14 +2982,6 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,\n MemoryRegion *mr);\n void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr);\n \n-/* Internal functions, part of the implementation of address_space_read_cached\n- * and address_space_write_cached. */\n-MemTxResult address_space_read_cached_slow(MemoryRegionCache *cache,\n- hwaddr addr, void *buf, hwaddr len);\n-MemTxResult address_space_write_cached_slow(MemoryRegionCache *cache,\n- hwaddr addr, const void *buf,\n- hwaddr len);\n-\n int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr);\n bool prepare_mmio_access(MemoryRegion *mr);\n \n@@ -3201,49 +3059,6 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr,\n return result;\n }\n \n-/**\n- * address_space_read_cached: read from a cached RAM region\n- *\n- * @cache: Cached region to be addressed\n- * @addr: address relative to the base of the RAM region\n- * @buf: buffer with the data transferred\n- * @len: length of the data transferred\n- */\n-static inline MemTxResult\n-address_space_read_cached(MemoryRegionCache *cache, hwaddr addr,\n- void *buf, hwaddr len)\n-{\n- assert(addr < cache->len && len <= cache->len - addr);\n- fuzz_dma_read_cb(cache->xlat + addr, len, cache->mrs.mr);\n- if (likely(cache->ptr)) {\n- memcpy(buf, cache->ptr + addr, len);\n- return MEMTX_OK;\n- } else {\n- return address_space_read_cached_slow(cache, addr, buf, len);\n- }\n-}\n-\n-/**\n- * address_space_write_cached: write to a cached RAM region\n- *\n- * @cache: Cached region to be addressed\n- * @addr: address relative to the base of the RAM region\n- * @buf: buffer with the data transferred\n- * @len: length of the data transferred\n- */\n-static inline MemTxResult\n-address_space_write_cached(MemoryRegionCache *cache, hwaddr addr,\n- const void *buf, hwaddr len)\n-{\n- assert(addr < cache->len && len <= cache->len - addr);\n- if (likely(cache->ptr)) {\n- memcpy(cache->ptr + addr, buf, len);\n- return MEMTX_OK;\n- } else {\n- return address_space_write_cached_slow(cache, addr, buf, len);\n- }\n-}\n-\n /**\n * address_space_set: Fill address space with a constant byte.\n *\ndiff --git a/include/system/memory_cached.h b/include/system/memory_cached.h\nnew file mode 100644\nindex 00000000000..1a07774b6ad\n--- /dev/null\n+++ b/include/system/memory_cached.h\n@@ -0,0 +1,207 @@\n+/*\n+ * Physical memory management API\n+ *\n+ * Copyright 2011 Red Hat, Inc. and/or its affiliates\n+ *\n+ * Authors:\n+ * Avi Kivity <avi@redhat.com>\n+ *\n+ * SPDX-License-Identifier: GPL-2.0-or-later\n+ */\n+\n+#ifndef SYSTEM_MEMORY_CACHED_H\n+#define SYSTEM_MEMORY_CACHED_H\n+\n+#include \"exec/hwaddr.h\"\n+#include \"system/memory.h\"\n+\n+struct MemoryRegionCache {\n+ uint8_t *ptr;\n+ hwaddr xlat;\n+ hwaddr len;\n+ FlatView *fv;\n+ MemoryRegionSection mrs;\n+ bool is_write;\n+};\n+\n+/**\n+ * address_space_ld*_cached: load from a cached #MemoryRegion\n+ * address_space_st*_cached: store into a cached #MemoryRegion\n+ *\n+ * These functions perform a load or store of the byte, word,\n+ * longword or quad to the specified address. The address is\n+ * a physical address in the AddressSpace, but it must lie within\n+ * a #MemoryRegion that was mapped with address_space_cache_init.\n+ *\n+ * The _le suffixed functions treat the data as little endian;\n+ * _be indicates big endian; no suffix indicates \"same endianness\n+ * as guest CPU\".\n+ *\n+ * The \"guest CPU endianness\" accessors are deprecated for use outside\n+ * target-* code; devices should be CPU-agnostic and use either the LE\n+ * or the BE accessors.\n+ *\n+ * @cache: previously initialized #MemoryRegionCache to be accessed\n+ * @addr: address within the address space\n+ * @val: data value, for stores\n+ * @attrs: memory transaction attributes\n+ * @result: location to write the success/failure of the transaction;\n+ * if NULL, this information is discarded\n+ */\n+\n+#define SUFFIX _cached_slow\n+#define ARG1 cache\n+#define ARG1_DECL MemoryRegionCache *cache\n+#include \"exec/memory_ldst.h.inc\"\n+\n+/* Inline fast path for direct RAM access. */\n+static inline uint8_t address_space_ldub_cached(MemoryRegionCache *cache,\n+ hwaddr addr, MemTxAttrs attrs, MemTxResult *result)\n+{\n+ assert(addr < cache->len);\n+ if (likely(cache->ptr)) {\n+ return ldub_p(cache->ptr + addr);\n+ } else {\n+ return address_space_ldub_cached_slow(cache, addr, attrs, result);\n+ }\n+}\n+\n+static inline void address_space_stb_cached(MemoryRegionCache *cache,\n+ hwaddr addr, uint8_t val, MemTxAttrs attrs, MemTxResult *result)\n+{\n+ assert(addr < cache->len);\n+ if (likely(cache->ptr)) {\n+ stb_p(cache->ptr + addr, val);\n+ } else {\n+ address_space_stb_cached_slow(cache, addr, val, attrs, result);\n+ }\n+}\n+\n+#define ENDIANNESS\n+#include \"exec/memory_ldst_cached.h.inc\"\n+\n+#define ENDIANNESS _le\n+#include \"exec/memory_ldst_cached.h.inc\"\n+\n+#define ENDIANNESS _be\n+#include \"exec/memory_ldst_cached.h.inc\"\n+\n+#define SUFFIX _cached\n+#define ARG1 cache\n+#define ARG1_DECL MemoryRegionCache *cache\n+#include \"exec/memory_ldst_phys.h.inc\"\n+\n+/**\n+ * address_space_cache_init: prepare for repeated access to a physical\n+ * memory region\n+ *\n+ * @cache: #MemoryRegionCache to be filled\n+ * @as: #AddressSpace to be accessed\n+ * @addr: address within that address space\n+ * @len: length of buffer\n+ * @is_write: indicates the transfer direction\n+ *\n+ * Will only work with RAM, and may map a subset of the requested range by\n+ * returning a value that is less than @len. On failure, return a negative\n+ * errno value.\n+ *\n+ * Because it only works with RAM, this function can be used for\n+ * read-modify-write operations. In this case, is_write should be %true.\n+ *\n+ * Note that addresses passed to the address_space_*_cached functions\n+ * are relative to @addr.\n+ */\n+int64_t address_space_cache_init(MemoryRegionCache *cache,\n+ AddressSpace *as,\n+ hwaddr addr,\n+ hwaddr len,\n+ bool is_write);\n+\n+/**\n+ * address_space_cache_init_empty: Initialize empty #MemoryRegionCache\n+ *\n+ * @cache: The #MemoryRegionCache to operate on.\n+ *\n+ * Initializes #MemoryRegionCache structure without memory region attached.\n+ * Cache initialized this way can only be safely destroyed, but not used.\n+ */\n+static inline void address_space_cache_init_empty(MemoryRegionCache *cache)\n+{\n+ cache->mrs.mr = NULL;\n+ /* There is no real need to initialize fv, but it makes Coverity happy. */\n+ cache->fv = NULL;\n+}\n+\n+/**\n+ * address_space_cache_invalidate: complete a write to a #MemoryRegionCache\n+ *\n+ * @cache: The #MemoryRegionCache to operate on.\n+ * @addr: The first physical address that was written, relative to the\n+ * address that was passed to @address_space_cache_init.\n+ * @access_len: The number of bytes that were written starting at @addr.\n+ */\n+void address_space_cache_invalidate(MemoryRegionCache *cache,\n+ hwaddr addr,\n+ hwaddr access_len);\n+\n+/**\n+ * address_space_cache_destroy: free a #MemoryRegionCache\n+ *\n+ * @cache: The #MemoryRegionCache whose memory should be released.\n+ */\n+void address_space_cache_destroy(MemoryRegionCache *cache);\n+\n+/*\n+ * Internal functions, part of the implementation of address_space_read_cached\n+ * and address_space_write_cached.\n+ */\n+MemTxResult address_space_read_cached_slow(MemoryRegionCache *cache,\n+ hwaddr addr, void *buf, hwaddr len);\n+MemTxResult address_space_write_cached_slow(MemoryRegionCache *cache,\n+ hwaddr addr, const void *buf,\n+ hwaddr len);\n+\n+/**\n+ * address_space_read_cached: read from a cached RAM region\n+ *\n+ * @cache: Cached region to be addressed\n+ * @addr: address relative to the base of the RAM region\n+ * @buf: buffer with the data transferred\n+ * @len: length of the data transferred\n+ */\n+static inline MemTxResult\n+address_space_read_cached(MemoryRegionCache *cache, hwaddr addr,\n+ void *buf, hwaddr len)\n+{\n+ assert(addr < cache->len && len <= cache->len - addr);\n+ fuzz_dma_read_cb(cache->xlat + addr, len, cache->mrs.mr);\n+ if (likely(cache->ptr)) {\n+ memcpy(buf, cache->ptr + addr, len);\n+ return MEMTX_OK;\n+ } else {\n+ return address_space_read_cached_slow(cache, addr, buf, len);\n+ }\n+}\n+\n+/**\n+ * address_space_write_cached: write to a cached RAM region\n+ *\n+ * @cache: Cached region to be addressed\n+ * @addr: address relative to the base of the RAM region\n+ * @buf: buffer with the data transferred\n+ * @len: length of the data transferred\n+ */\n+static inline MemTxResult\n+address_space_write_cached(MemoryRegionCache *cache, hwaddr addr,\n+ const void *buf, hwaddr len)\n+{\n+ assert(addr < cache->len && len <= cache->len - addr);\n+ if (likely(cache->ptr)) {\n+ memcpy(cache->ptr + addr, buf, len);\n+ return MEMTX_OK;\n+ } else {\n+ return address_space_write_cached_slow(cache, addr, buf, len);\n+ }\n+}\n+\n+#endif\ndiff --git a/system/physmem.c b/system/physmem.c\nindex d8465f085bd..853a8c00aa2 100644\n--- a/system/physmem.c\n+++ b/system/physmem.c\n@@ -53,6 +53,7 @@\n #include \"qemu/memalign.h\"\n #include \"qemu/memfd.h\"\n #include \"system/memory.h\"\n+#include \"system/memory_cached.h\"\n #include \"system/ioport.h\"\n #include \"system/dma.h\"\n #include \"system/hostmem.h\"\n", "prefixes": [ "07/14" ] }