Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2217950/?format=api
{ "id": 2217950, "url": "http://patchwork.ozlabs.org/api/patches/2217950/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260331040659.401397-3-tangtao1634@phytium.com.cn/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/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": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260331040659.401397-3-tangtao1634@phytium.com.cn>", "list_archive_url": null, "date": "2026-03-31T04:06:57", "name": "[2/4] tests/qtest: Add libqtest attrs helpers for memory accesses", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "f47cb626e229022f32131042f81f89b868add532", "submitter": { "id": 91412, "url": "http://patchwork.ozlabs.org/api/people/91412/?format=api", "name": "Tao Tang", "email": "tangtao1634@phytium.com.cn" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260331040659.401397-3-tangtao1634@phytium.com.cn/mbox/", "series": [ { "id": 498122, "url": "http://patchwork.ozlabs.org/api/series/498122/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=498122", "date": "2026-03-31T04:06:55", "name": "tests/qtest: Add memory-access attributes (secure/space)", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/498122/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2217950/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2217950/checks/", "tags": {}, "related": [], "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 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)", "hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163\n 4@phytium.com.cn;" ], "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 4flF3L3vNgz1yGT\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 31 Mar 2026 15:08:29 +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 1w7QOe-0001CB-V9; Tue, 31 Mar 2026 00:08:09 -0400", "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 <tangtao1634@phytium.com.cn>)\n id 1w7QON-00010F-MG; Tue, 31 Mar 2026 00:07:52 -0400", "from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118])\n by eggs.gnu.org with esmtp (Exim 4.90_1)\n (envelope-from <tangtao1634@phytium.com.cn>)\n id 1w7QOK-0002F6-42; Tue, 31 Mar 2026 00:07:51 -0400", "from prodtpl.icoremail.net (unknown [10.12.1.20])\n by hzbj-icmmx-7 (Coremail) with SMTP id AQAAfwCnrmKHSMtpeojBCA--.71S2;\n Tue, 31 Mar 2026 12:07:35 +0800 (CST)", "from phytium.com.cn (unknown [218.76.62.144])\n by mail (Coremail) with SMTP id AQAAf8DwSJR6SMtpYqQHAA--.18366S5;\n Tue, 31 Mar 2026 12:07:34 +0800 (CST)" ], "From": "Tao Tang <tangtao1634@phytium.com.cn>", "To": "Fabiano Rosas <farosas@suse.de>, Laurent Vivier <lvivier@redhat.com>,\n Paolo Bonzini <pbonzini@redhat.com>", "Cc": "qemu-devel@nongnu.org, qemu-arm@nongnu.org,\n Peter Maydell <peter.maydell@linaro.org>,\n Chen Baozi <chenbaozi@phytium.com.cn>,\n Pierrick Bouvier <pierrick.bouvier@linaro.org>,\n Chao Liu <chao.liu.zevorn@gmail.com>, Tao Tang <tangtao1634@phytium.com.cn>", "Subject": "[PATCH 2/4] tests/qtest: Add libqtest attrs helpers for memory\n accesses", "Date": "Tue, 31 Mar 2026 12:06:57 +0800", "Message-Id": "<20260331040659.401397-3-tangtao1634@phytium.com.cn>", "X-Mailer": "git-send-email 2.34.1", "In-Reply-To": "<20260331040659.401397-1-tangtao1634@phytium.com.cn>", "References": "<20260331040659.401397-1-tangtao1634@phytium.com.cn>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-CM-TRANSID": "AQAAf8DwSJR6SMtpYqQHAA--.18366S5", "X-CM-SenderInfo": "pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQALBWnKzfEBsQAAsg", "X-Coremail-Antispam": "1Uk129KBjvAXoWfZw1xtw1kAw17Zw1xJrW5KFg_yoW8try3uo\n WrtF1jq34DXwnxZrW09ryxGr9rXw47Cr15Xwn8t3WUKas3Grn09a13KanxZa4j9F1rGrWU\n XFZ7XrW5WrWIyFZ7n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf\n J3UbIjqfuFe4nvWSU8nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UU\n UUUUUUU==", "Received-SPF": "pass client-ip=162.243.164.118;\n envelope-from=tangtao1634@phytium.com.cn;\n helo=zg8tmtyylji0my4xnjqumte4.icoremail.net", "X-Spam_score_int": "-5", "X-Spam_score": "-0.6", "X-Spam_bar": "/", "X-Spam_report": "(-0.6 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_LOW=-0.7,\n RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01,\n RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=1, RCVD_IN_VALIDITY_RPBL_BLOCKED=1,\n SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 development <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": "Expose libqtest APIs for qtest memory commands with optional attrs:\n- qtest_{read,write}{b,w,l,q}_attrs()\n- qtest_mem{read,write,set}_attrs()\n- qtest_buf{read,write}_attrs()\n\nKeep the existing libqtest memory access helpers as wrappers passing\nNULL attrs, so current users remain unchanged.\n\nAlso add matching libqtest-single shortcut wrappers for the *_attrs\nhelpers.\n\nRefactor libqtest response parsing by splitting qtest_rsp_args() into a\nraw tokenizing helper, qtest_rsp_words(), and the existing OK-checking\nwrapper. Add qtest_raw_cmd() on top of qtest_rsp_words() so tests can\nsend raw qtest protocol commands and inspect non-OK responses such as\nERR and FAIL.\n\nSigned-off-by: Tao Tang <tangtao1634@phytium.com.cn>\nReviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>\n---\n tests/qtest/libqtest-single.h | 156 +++++++++++++++++++++\n tests/qtest/libqtest.c | 246 ++++++++++++++++++++++++++--------\n tests/qtest/libqtest.h | 177 ++++++++++++++++++++++++\n 3 files changed, 524 insertions(+), 55 deletions(-)", "diff": "diff --git a/tests/qtest/libqtest-single.h b/tests/qtest/libqtest-single.h\nindex 851724cbcb..2812b86bd4 100644\n--- a/tests/qtest/libqtest-single.h\n+++ b/tests/qtest/libqtest-single.h\n@@ -291,6 +291,162 @@ static inline void memwrite(uint64_t addr, const void *data, size_t size)\n qtest_memwrite(global_qtest, addr, data, size);\n }\n \n+/**\n+ * writeb_attrs:\n+ * @addr: Guest address to write to.\n+ * @value: Value being written.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Writes an 8-bit value to guest memory with optional transaction attributes.\n+ */\n+static inline void writeb_attrs(uint64_t addr, uint8_t value, const char *attrs)\n+{\n+ qtest_writeb_attrs(global_qtest, addr, value, attrs);\n+}\n+\n+/**\n+ * writew_attrs:\n+ * @addr: Guest address to write to.\n+ * @value: Value being written.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Writes a 16-bit value to guest memory with optional transaction attributes.\n+ */\n+static inline void writew_attrs(uint64_t addr, uint16_t value,\n+ const char *attrs)\n+{\n+ qtest_writew_attrs(global_qtest, addr, value, attrs);\n+}\n+\n+/**\n+ * writel_attrs:\n+ * @addr: Guest address to write to.\n+ * @value: Value being written.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Writes a 32-bit value to guest memory with optional transaction attributes.\n+ */\n+static inline void writel_attrs(uint64_t addr, uint32_t value,\n+ const char *attrs)\n+{\n+ qtest_writel_attrs(global_qtest, addr, value, attrs);\n+}\n+\n+/**\n+ * writeq_attrs:\n+ * @addr: Guest address to write to.\n+ * @value: Value being written.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Writes a 64-bit value to guest memory with optional transaction attributes.\n+ */\n+static inline void writeq_attrs(uint64_t addr, uint64_t value,\n+ const char *attrs)\n+{\n+ qtest_writeq_attrs(global_qtest, addr, value, attrs);\n+}\n+\n+/**\n+ * readb_attrs:\n+ * @addr: Guest address to read from.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Reads an 8-bit value from guest memory with optional transaction attributes.\n+ *\n+ * Returns: Value read.\n+ */\n+static inline uint8_t readb_attrs(uint64_t addr, const char *attrs)\n+{\n+ return qtest_readb_attrs(global_qtest, addr, attrs);\n+}\n+\n+/**\n+ * readw_attrs:\n+ * @addr: Guest address to read from.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Reads a 16-bit value from guest memory with optional transaction attributes.\n+ *\n+ * Returns: Value read.\n+ */\n+static inline uint16_t readw_attrs(uint64_t addr, const char *attrs)\n+{\n+ return qtest_readw_attrs(global_qtest, addr, attrs);\n+}\n+\n+/**\n+ * readl_attrs:\n+ * @addr: Guest address to read from.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Reads a 32-bit value from guest memory with optional transaction attributes.\n+ *\n+ * Returns: Value read.\n+ */\n+static inline uint32_t readl_attrs(uint64_t addr, const char *attrs)\n+{\n+ return qtest_readl_attrs(global_qtest, addr, attrs);\n+}\n+\n+/**\n+ * readq_attrs:\n+ * @addr: Guest address to read from.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Reads a 64-bit value from guest memory with optional transaction attributes.\n+ *\n+ * Returns: Value read.\n+ */\n+static inline uint64_t readq_attrs(uint64_t addr, const char *attrs)\n+{\n+ return qtest_readq_attrs(global_qtest, addr, attrs);\n+}\n+\n+/**\n+ * memread_attrs:\n+ * @addr: Guest address to read from.\n+ * @data: Pointer to where memory contents will be stored.\n+ * @size: Number of bytes to read.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Read guest memory into a buffer with optional transaction attributes.\n+ */\n+static inline void memread_attrs(uint64_t addr, void *data, size_t size,\n+ const char *attrs)\n+{\n+ qtest_memread_attrs(global_qtest, addr, data, size, attrs);\n+}\n+\n+/**\n+ * memwrite_attrs:\n+ * @addr: Guest address to write to.\n+ * @data: Pointer to the bytes that will be written to guest memory.\n+ * @size: Number of bytes to write.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Write a buffer to guest memory with optional transaction attributes.\n+ */\n+static inline void memwrite_attrs(uint64_t addr, const void *data, size_t size,\n+ const char *attrs)\n+{\n+ qtest_memwrite_attrs(global_qtest, addr, data, size, attrs);\n+}\n+\n+/**\n+ * memset_attrs:\n+ * @addr: Guest address to write to.\n+ * @pattern: Byte pattern to fill the guest memory region with.\n+ * @size: Number of bytes to write.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Write a pattern to guest memory with optional transaction attributes.\n+ */\n+static inline void memset_attrs(uint64_t addr, uint8_t pattern, size_t size,\n+ const char *attrs)\n+{\n+ qtest_memset_attrs(global_qtest, addr, pattern, size, attrs);\n+}\n+\n /**\n * clock_step_next:\n *\ndiff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c\nindex 051faf31e1..b67786f1ad 100644\n--- a/tests/qtest/libqtest.c\n+++ b/tests/qtest/libqtest.c\n@@ -747,11 +747,10 @@ static GString *qtest_client_socket_recv_line(QTestState *s)\n return line;\n }\n \n-static gchar **qtest_rsp_args(QTestState *s, int expected_args)\n+static gchar **qtest_rsp_words(QTestState *s)\n {\n GString *line;\n gchar **words;\n- int i;\n \n redo:\n line = s->ops.recv_line(s);\n@@ -781,6 +780,15 @@ redo:\n }\n \n g_assert(words[0] != NULL);\n+\n+ return words;\n+}\n+\n+static gchar **qtest_rsp_args(QTestState *s, int expected_args)\n+{\n+ gchar **words = qtest_rsp_words(s);\n+ int i;\n+\n g_assert_cmpstr(words[0], ==, \"OK\");\n \n for (i = 0; i < expected_args; i++) {\n@@ -790,6 +798,21 @@ redo:\n return words;\n }\n \n+gchar **qtest_raw_cmd(QTestState *s, const char *fmt, ...)\n+{\n+ va_list ap;\n+ gchar *str;\n+\n+ va_start(ap, fmt);\n+ str = g_strdup_vprintf(fmt, ap);\n+ va_end(ap);\n+\n+ s->ops.send(s, str);\n+ g_free(str);\n+\n+ return qtest_rsp_words(s);\n+}\n+\n static void qtest_rsp(QTestState *s)\n {\n gchar **words = qtest_rsp_args(s, 0);\n@@ -1232,66 +1255,44 @@ uint32_t qtest_inl(QTestState *s, uint16_t addr)\n return qtest_big_endian(s) ? bswap32(v) : v;\n }\n \n-static void qtest_write(QTestState *s, const char *cmd, uint64_t addr,\n- uint64_t value)\n-{\n- qtest_sendf(s, \"%s 0x%\" PRIx64 \" 0x%\" PRIx64 \"\\n\", cmd, addr, value);\n- qtest_rsp(s);\n-}\n-\n void qtest_writeb(QTestState *s, uint64_t addr, uint8_t value)\n {\n- qtest_write(s, \"writeb\", addr, value);\n+ qtest_writeb_attrs(s, addr, value, NULL);\n }\n \n void qtest_writew(QTestState *s, uint64_t addr, uint16_t value)\n {\n- qtest_write(s, \"writew\", addr, value);\n+ qtest_writew_attrs(s, addr, value, NULL);\n }\n \n void qtest_writel(QTestState *s, uint64_t addr, uint32_t value)\n {\n- qtest_write(s, \"writel\", addr, value);\n+ qtest_writel_attrs(s, addr, value, NULL);\n }\n \n void qtest_writeq(QTestState *s, uint64_t addr, uint64_t value)\n {\n- qtest_write(s, \"writeq\", addr, value);\n-}\n-\n-static uint64_t qtest_read(QTestState *s, const char *cmd, uint64_t addr)\n-{\n- gchar **args;\n- int ret;\n- uint64_t value;\n-\n- qtest_sendf(s, \"%s 0x%\" PRIx64 \"\\n\", cmd, addr);\n- args = qtest_rsp_args(s, 2);\n- ret = qemu_strtou64(args[1], NULL, 0, &value);\n- g_assert(!ret);\n- g_strfreev(args);\n-\n- return value;\n+ qtest_writeq_attrs(s, addr, value, NULL);\n }\n \n uint8_t qtest_readb(QTestState *s, uint64_t addr)\n {\n- return qtest_read(s, \"readb\", addr);\n+ return qtest_readb_attrs(s, addr, NULL);\n }\n \n uint16_t qtest_readw(QTestState *s, uint64_t addr)\n {\n- return qtest_read(s, \"readw\", addr);\n+ return qtest_readw_attrs(s, addr, NULL);\n }\n \n uint32_t qtest_readl(QTestState *s, uint64_t addr)\n {\n- return qtest_read(s, \"readl\", addr);\n+ return qtest_readl_attrs(s, addr, NULL);\n }\n \n uint64_t qtest_readq(QTestState *s, uint64_t addr)\n {\n- return qtest_read(s, \"readq\", addr);\n+ return qtest_readq_attrs(s, addr, NULL);\n }\n \n static int hex2nib(char ch)\n@@ -1309,23 +1310,7 @@ static int hex2nib(char ch)\n \n void qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size)\n {\n- uint8_t *ptr = data;\n- gchar **args;\n- size_t i;\n-\n- if (!size) {\n- return;\n- }\n-\n- qtest_sendf(s, \"read 0x%\" PRIx64 \" 0x%zx\\n\", addr, size);\n- args = qtest_rsp_args(s, 2);\n-\n- for (i = 0; i < size; i++) {\n- ptr[i] = hex2nib(args[1][2 + (i * 2)]) << 4;\n- ptr[i] |= hex2nib(args[1][2 + (i * 2) + 1]);\n- }\n-\n- g_strfreev(args);\n+ qtest_memread_attrs(s, addr, data, size, NULL);\n }\n \n uint64_t qtest_rtas_call(QTestState *s, const char *name,\n@@ -1390,23 +1375,58 @@ void qtest_add_data_func(const char *str, const void *data,\n }\n \n void qtest_bufwrite(QTestState *s, uint64_t addr, const void *data, size_t size)\n+{\n+ qtest_bufwrite_attrs(s, addr, data, size, NULL);\n+}\n+\n+void qtest_bufread(QTestState *s, uint64_t addr, void *data, size_t size)\n+{\n+ qtest_bufread_attrs(s, addr, data, size, NULL);\n+}\n+\n+void qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t size)\n+{\n+ qtest_memwrite_attrs(s, addr, data, size, NULL);\n+}\n+\n+void qtest_memset(QTestState *s, uint64_t addr, uint8_t pattern, size_t size)\n+{\n+ qtest_memset_attrs(s, addr, pattern, size, NULL);\n+}\n+\n+static bool qtest_has_attrs(const char *attrs)\n+{\n+ return attrs && attrs[0];\n+}\n+\n+void qtest_bufwrite_attrs(QTestState *s, uint64_t addr, const void *data,\n+ size_t size, const char *attrs)\n {\n gchar *bdata;\n \n bdata = g_base64_encode(data, size);\n qtest_sendf(s, \"b64write 0x%\" PRIx64 \" 0x%zx \", addr, size);\n s->ops.send(s, bdata);\n+ if (qtest_has_attrs(attrs)) {\n+ s->ops.send(s, \" \");\n+ s->ops.send(s, attrs);\n+ }\n s->ops.send(s, \"\\n\");\n qtest_rsp(s);\n g_free(bdata);\n }\n \n-void qtest_bufread(QTestState *s, uint64_t addr, void *data, size_t size)\n+void qtest_bufread_attrs(QTestState *s, uint64_t addr, void *data, size_t size,\n+ const char *attrs)\n {\n gchar **args;\n size_t len;\n \n- qtest_sendf(s, \"b64read 0x%\" PRIx64 \" 0x%zx\\n\", addr, size);\n+ if (qtest_has_attrs(attrs)) {\n+ qtest_sendf(s, \"b64read 0x%\" PRIx64 \" 0x%zx %s\\n\", addr, size, attrs);\n+ } else {\n+ qtest_sendf(s, \"b64read 0x%\" PRIx64 \" 0x%zx\\n\", addr, size);\n+ }\n args = qtest_rsp_args(s, 2);\n \n g_base64_decode_inplace(args[1], &len);\n@@ -1420,7 +1440,111 @@ void qtest_bufread(QTestState *s, uint64_t addr, void *data, size_t size)\n g_strfreev(args);\n }\n \n-void qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t size)\n+static void qtest_write_attrs(QTestState *s, const char *cmd,\n+ uint64_t addr, uint64_t value,\n+ const char *attrs)\n+{\n+ if (qtest_has_attrs(attrs)) {\n+ qtest_sendf(s, \"%s 0x%\" PRIx64 \" 0x%\" PRIx64 \" %s\\n\",\n+ cmd, addr, value, attrs);\n+ } else {\n+ qtest_sendf(s, \"%s 0x%\" PRIx64 \" 0x%\" PRIx64 \"\\n\", cmd, addr, value);\n+ }\n+ qtest_rsp(s);\n+}\n+\n+static uint64_t qtest_read_attrs(QTestState *s, const char *cmd,\n+ uint64_t addr, const char *attrs)\n+{\n+ gchar **args;\n+ int ret;\n+ uint64_t value;\n+\n+ if (qtest_has_attrs(attrs)) {\n+ qtest_sendf(s, \"%s 0x%\" PRIx64 \" %s\\n\", cmd, addr, attrs);\n+ } else {\n+ qtest_sendf(s, \"%s 0x%\" PRIx64 \"\\n\", cmd, addr);\n+ }\n+ args = qtest_rsp_args(s, 2);\n+ ret = qemu_strtou64(args[1], NULL, 0, &value);\n+ g_assert(!ret);\n+ g_strfreev(args);\n+\n+ return value;\n+}\n+\n+void qtest_writeb_attrs(QTestState *s, uint64_t addr, uint8_t value,\n+ const char *attrs)\n+{\n+ qtest_write_attrs(s, \"writeb\", addr, value, attrs);\n+}\n+\n+void qtest_writew_attrs(QTestState *s, uint64_t addr, uint16_t value,\n+ const char *attrs)\n+{\n+ qtest_write_attrs(s, \"writew\", addr, value, attrs);\n+}\n+\n+void qtest_writel_attrs(QTestState *s, uint64_t addr, uint32_t value,\n+ const char *attrs)\n+{\n+ qtest_write_attrs(s, \"writel\", addr, value, attrs);\n+}\n+\n+void qtest_writeq_attrs(QTestState *s, uint64_t addr, uint64_t value,\n+ const char *attrs)\n+{\n+ qtest_write_attrs(s, \"writeq\", addr, value, attrs);\n+}\n+\n+uint8_t qtest_readb_attrs(QTestState *s, uint64_t addr, const char *attrs)\n+{\n+ return qtest_read_attrs(s, \"readb\", addr, attrs);\n+}\n+\n+uint16_t qtest_readw_attrs(QTestState *s, uint64_t addr, const char *attrs)\n+{\n+ return qtest_read_attrs(s, \"readw\", addr, attrs);\n+}\n+\n+uint32_t qtest_readl_attrs(QTestState *s, uint64_t addr, const char *attrs)\n+{\n+ return qtest_read_attrs(s, \"readl\", addr, attrs);\n+}\n+\n+uint64_t qtest_readq_attrs(QTestState *s, uint64_t addr, const char *attrs)\n+{\n+ return qtest_read_attrs(s, \"readq\", addr, attrs);\n+}\n+\n+void qtest_memread_attrs(QTestState *s, uint64_t addr, void *data,\n+ size_t size, const char *attrs)\n+{\n+ uint8_t *ptr = data;\n+ gchar **args;\n+ size_t i;\n+\n+ if (!size) {\n+ return;\n+ }\n+\n+ if (qtest_has_attrs(attrs)) {\n+ qtest_sendf(s, \"read 0x%\" PRIx64 \" 0x%zx %s\\n\", addr, size, attrs);\n+ } else {\n+ qtest_sendf(s, \"read 0x%\" PRIx64 \" 0x%zx\\n\", addr, size);\n+ }\n+ args = qtest_rsp_args(s, 2);\n+\n+ for (i = 0; i < size; i++) {\n+ ptr[i] = hex2nib(args[1][2 + (i * 2)]) << 4;\n+ ptr[i] |= hex2nib(args[1][2 + (i * 2) + 1]);\n+ }\n+\n+ g_strfreev(args);\n+}\n+\n+void qtest_memwrite_attrs(QTestState *s, uint64_t addr, const void *data,\n+ size_t size, const char *attrs)\n {\n const uint8_t *ptr = data;\n size_t i;\n@@ -1436,14 +1560,26 @@ void qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t size)\n sprintf(&enc[i * 2], \"%02x\", ptr[i]);\n }\n \n- qtest_sendf(s, \"write 0x%\" PRIx64 \" 0x%zx 0x%s\\n\", addr, size, enc);\n+ if (qtest_has_attrs(attrs)) {\n+ qtest_sendf(s, \"write 0x%\" PRIx64 \" 0x%zx 0x%s %s\\n\",\n+ addr, size, enc, attrs);\n+ } else {\n+ qtest_sendf(s, \"write 0x%\" PRIx64 \" 0x%zx 0x%s\\n\", addr, size, enc);\n+ }\n qtest_rsp(s);\n g_free(enc);\n }\n \n-void qtest_memset(QTestState *s, uint64_t addr, uint8_t pattern, size_t size)\n+void qtest_memset_attrs(QTestState *s, uint64_t addr, uint8_t pattern,\n+ size_t size, const char *attrs)\n {\n- qtest_sendf(s, \"memset 0x%\" PRIx64 \" 0x%zx 0x%02x\\n\", addr, size, pattern);\n+ if (qtest_has_attrs(attrs)) {\n+ qtest_sendf(s, \"memset 0x%\" PRIx64 \" 0x%zx 0x%02x %s\\n\",\n+ addr, size, pattern, attrs);\n+ } else {\n+ qtest_sendf(s, \"memset 0x%\" PRIx64 \" 0x%zx 0x%02x\\n\",\n+ addr, size, pattern);\n+ }\n qtest_rsp(s);\n }\n \ndiff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h\nindex 9c118c89ca..cee74cf2a4 100644\n--- a/tests/qtest/libqtest.h\n+++ b/tests/qtest/libqtest.h\n@@ -239,6 +239,19 @@ void qtest_qmp_send(QTestState *s, const char *fmt, ...)\n void qtest_qmp_send_raw(QTestState *s, const char *fmt, ...)\n G_GNUC_PRINTF(2, 3);\n \n+/**\n+ * qtest_raw_cmd:\n+ * @s: #QTestState instance to operate on.\n+ * @fmt: raw qtest protocol text to send, formatted like sprintf().\n+ *\n+ * Sends a raw qtest command and returns the response split on spaces.\n+ * The response is not required to start with ``OK``; callers can inspect\n+ * ``args[0]`` for ``OK``, ``ERR``, or ``FAIL`` and must free the returned\n+ * vector with g_strfreev().\n+ */\n+gchar **qtest_raw_cmd(QTestState *s, const char *fmt, ...)\n+ G_GNUC_PRINTF(2, 3);\n+\n /**\n * qtest_socket_server:\n * @socket_path: the UNIX domain socket path\n@@ -671,6 +684,20 @@ uint64_t qtest_csr_call(QTestState *s, const char *name,\n */\n void qtest_bufread(QTestState *s, uint64_t addr, void *data, size_t size);\n \n+/**\n+ * qtest_bufread_attrs:\n+ * @s: #QTestState instance to operate on.\n+ * @addr: Guest address to read from.\n+ * @data: Pointer to where memory contents will be stored.\n+ * @size: Number of bytes to read.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Read guest memory into a buffer and receive using a base64 encoding with\n+ * optional transaction attributes.\n+ */\n+void qtest_bufread_attrs(QTestState *s, uint64_t addr, void *data, size_t size,\n+ const char *attrs);\n+\n /**\n * qtest_memwrite:\n * @s: #QTestState instance to operate on.\n@@ -694,6 +721,21 @@ void qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t size)\n void qtest_bufwrite(QTestState *s, uint64_t addr,\n const void *data, size_t size);\n \n+/**\n+ * qtest_bufwrite_attrs:\n+ * @s: #QTestState instance to operate on.\n+ * @addr: Guest address to write to.\n+ * @data: Pointer to the bytes that will be written to guest memory.\n+ * @size: Number of bytes to write.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Write a buffer to guest memory and transmit using a base64 encoding with\n+ * optional transaction attributes.\n+ */\n+void qtest_bufwrite_attrs(QTestState *s, uint64_t addr,\n+ const void *data, size_t size,\n+ const char *attrs);\n+\n /**\n * qtest_memset:\n * @s: #QTestState instance to operate on.\n@@ -705,6 +747,141 @@ void qtest_bufwrite(QTestState *s, uint64_t addr,\n */\n void qtest_memset(QTestState *s, uint64_t addr, uint8_t patt, size_t size);\n \n+/**\n+ * qtest_writeb_attrs:\n+ * @s: #QTestState instance to operate on.\n+ * @addr: Guest address to write to.\n+ * @value: Value being written.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Writes an 8-bit value to guest memory with optional transaction attributes.\n+ */\n+void qtest_writeb_attrs(QTestState *s, uint64_t addr, uint8_t value,\n+ const char *attrs);\n+\n+/**\n+ * qtest_writew_attrs:\n+ * @s: #QTestState instance to operate on.\n+ * @addr: Guest address to write to.\n+ * @value: Value being written.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Writes a 16-bit value to guest memory with optional transaction attributes.\n+ */\n+void qtest_writew_attrs(QTestState *s, uint64_t addr, uint16_t value,\n+ const char *attrs);\n+\n+/**\n+ * qtest_writel_attrs:\n+ * @s: #QTestState instance to operate on.\n+ * @addr: Guest address to write to.\n+ * @value: Value being written.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Writes a 32-bit value to guest memory with optional transaction attributes.\n+ */\n+void qtest_writel_attrs(QTestState *s, uint64_t addr, uint32_t value,\n+ const char *attrs);\n+\n+/**\n+ * qtest_writeq_attrs:\n+ * @s: #QTestState instance to operate on.\n+ * @addr: Guest address to write to.\n+ * @value: Value being written.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Writes a 64-bit value to guest memory with optional transaction attributes.\n+ */\n+void qtest_writeq_attrs(QTestState *s, uint64_t addr, uint64_t value,\n+ const char *attrs);\n+\n+/**\n+ * qtest_readb_attrs:\n+ * @s: #QTestState instance to operate on.\n+ * @addr: Guest address to read from.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Reads an 8-bit value from guest memory with optional transaction attributes.\n+ *\n+ * Returns: Value read.\n+ */\n+uint8_t qtest_readb_attrs(QTestState *s, uint64_t addr, const char *attrs);\n+\n+/**\n+ * qtest_readw_attrs:\n+ * @s: #QTestState instance to operate on.\n+ * @addr: Guest address to read from.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Reads a 16-bit value from guest memory with optional transaction attributes.\n+ *\n+ * Returns: Value read.\n+ */\n+uint16_t qtest_readw_attrs(QTestState *s, uint64_t addr, const char *attrs);\n+\n+/**\n+ * qtest_readl_attrs:\n+ * @s: #QTestState instance to operate on.\n+ * @addr: Guest address to read from.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Reads a 32-bit value from guest memory with optional transaction attributes.\n+ *\n+ * Returns: Value read.\n+ */\n+uint32_t qtest_readl_attrs(QTestState *s, uint64_t addr, const char *attrs);\n+\n+/**\n+ * qtest_readq_attrs:\n+ * @s: #QTestState instance to operate on.\n+ * @addr: Guest address to read from.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Reads a 64-bit value from guest memory with optional transaction attributes.\n+ *\n+ * Returns: Value read.\n+ */\n+uint64_t qtest_readq_attrs(QTestState *s, uint64_t addr, const char *attrs);\n+\n+/**\n+ * qtest_memread_attrs:\n+ * @s: #QTestState instance to operate on.\n+ * @addr: Guest address to read from.\n+ * @data: Pointer to where memory contents will be stored.\n+ * @size: Number of bytes to read.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Read guest memory into a buffer with optional transaction attributes.\n+ */\n+void qtest_memread_attrs(QTestState *s, uint64_t addr, void *data, size_t size,\n+ const char *attrs);\n+\n+/**\n+ * qtest_memwrite_attrs:\n+ * @s: #QTestState instance to operate on.\n+ * @addr: Guest address to write to.\n+ * @data: Pointer to the bytes that will be written to guest memory.\n+ * @size: Number of bytes to write.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Write a buffer to guest memory with optional transaction attributes.\n+ */\n+void qtest_memwrite_attrs(QTestState *s, uint64_t addr, const void *data,\n+ size_t size, const char *attrs);\n+\n+/**\n+ * qtest_memset_attrs:\n+ * @s: #QTestState instance to operate on.\n+ * @addr: Guest address to write to.\n+ * @patt: Byte pattern to fill the guest memory region with.\n+ * @size: Number of bytes to write.\n+ * @attrs: Optional transaction attributes string.\n+ *\n+ * Write a pattern to guest memory with optional transaction attributes.\n+ */\n+void qtest_memset_attrs(QTestState *s, uint64_t addr, uint8_t patt, size_t size,\n+ const char *attrs);\n+\n /**\n * qtest_clock_step_next:\n * @s: #QTestState instance to operate on.\n", "prefixes": [ "2/4" ] }