get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2217951/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2217951,
    "url": "http://patchwork.ozlabs.org/api/patches/2217951/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260331040659.401397-4-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-4-tangtao1634@phytium.com.cn>",
    "list_archive_url": null,
    "date": "2026-03-31T04:06:58",
    "name": "[3/4] tests/qtest: Add qtest-attrs-test for memory access attrs",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "4f8ca6118a421a34698df00d39c743bbd9acf571",
    "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-4-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/2217951/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2217951/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-6; 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 4flF466JJXz1xtJ\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 31 Mar 2026 15:09:10 +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 1w7QOS-00011t-K9; Tue, 31 Mar 2026 00:07:56 -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-0000zn-3o; Tue, 31 Mar 2026 00:07:51 -0400",
            "from zg8tmja5ljk3lje4ms43mwaa.icoremail.net ([209.97.181.73])\n by eggs.gnu.org with esmtp (Exim 4.90_1)\n (envelope-from <tangtao1634@phytium.com.cn>)\n id 1w7QOK-0002HD-DU; Tue, 31 Mar 2026 00:07:50 -0400",
            "from prodtpl.icoremail.net (unknown [10.12.1.20])\n by hzbj-icmmx-6 (Coremail) with SMTP id AQAAfwD3iWWQSMtp08g9AA--.23002S2;\n Tue, 31 Mar 2026 12:07:44 +0800 (CST)",
            "from phytium.com.cn (unknown [218.76.62.144])\n by mail (Coremail) with SMTP id AQAAf8DwSJR6SMtpYqQHAA--.18366S6;\n Tue, 31 Mar 2026 12:07:37 +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 3/4] tests/qtest: Add qtest-attrs-test for memory access attrs",
        "Date": "Tue, 31 Mar 2026 12:06:58 +0800",
        "Message-Id": "<20260331040659.401397-4-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--.18366S6",
        "X-CM-SenderInfo": "pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQALBWnKzfEBswAAsi",
        "X-Coremail-Antispam": "1Uk129KBjvAXoW3ZF47Kw4fZw4rKFW5GrW3KFg_yoW8GrW3uo\n WfJF12q3W7t3W3Gr92krZ7CrWqqa92kFsxJr40qw1UXF1xGF42yw13JFZxX34rtw48J34U\n GFZrKr1Syrs7trn3n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf\n J3UbIjqfuFe4nvWSU8nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UU\n UUUUUUU==",
        "Received-SPF": "pass client-ip=209.97.181.73;\n envelope-from=tangtao1634@phytium.com.cn;\n helo=zg8tmja5ljk3lje4ms43mwaa.icoremail.net",
        "X-Spam_score_int": "-8",
        "X-Spam_score": "-0.9",
        "X-Spam_bar": "/",
        "X-Spam_report": "(-0.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_MSPIKE_H5=-1,\n RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=1,\n RCVD_IN_VALIDITY_RPBL_BLOCKED=1, SPF_HELO_NONE=0.001,\n 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": "Add qtest-attrs-test to exercise qtest memory access commands with attrs\non both aarch64 and x86.\n\nThe test covers:\n- Arm virt,secure=on: scalar and bulk accesses across non-secure,\n  secure, and root spaces, plus negative coverage for realm and for\n  non-secure accesses into secure-only RAM\n- x86 q35: normal accesses\n- libqtest-single *_attrs shortcut wrappers\n\nFor negative cases, use qtest_raw_cmd() to check that accesses which\nmiss the intended AddressSpace fail with ERR responses emitted via\nqtest_send_memtx_error().\n\nOn Arm, the test targets the virt machine's secure-only RAM window so\nthat the requested attrs must select the correct address space.\n\nAlso wire qtest-attrs-test into the aarch64 and i386/x86_64 qtest\nbuilds.\n\nSigned-off-by: Tao Tang <tangtao1634@phytium.com.cn>\n---\n tests/qtest/meson.build        |   7 +-\n tests/qtest/qtest-attrs-test.c | 350 +++++++++++++++++++++++++++++++++\n 2 files changed, 355 insertions(+), 2 deletions(-)\n create mode 100644 tests/qtest/qtest-attrs-test.c",
    "diff": "diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build\nindex be4fa627b5..87aa104d23 100644\n--- a/tests/qtest/meson.build\n+++ b/tests/qtest/meson.build\n@@ -115,6 +115,7 @@ qtests_i386 = \\\n    'drive_del-test',\n    'cpu-plug-test',\n    'migration-test',\n+   'qtest-attrs-test',\n   ]\n \n if dbus_display and config_all_devices.has_key('CONFIG_VGA')\n@@ -249,7 +250,8 @@ qtests_arm = \\\n   (config_all_devices.has_key('CONFIG_STM32L4X5_SOC') and\n    config_all_devices.has_key('CONFIG_DM163')? ['dm163-test'] : []) + \\\n   ['arm-cpu-features',\n-   'boot-serial-test']\n+   'boot-serial-test',\n+   'qtest-attrs-test',]\n \n # TODO: once aarch64 TCG is fixed on ARM 32 bit host, make bios-tables-test unconditional\n qtests_aarch64 = \\\n@@ -270,7 +272,8 @@ qtests_aarch64 = \\\n   ['arm-cpu-features',\n    'numa-test',\n    'boot-serial-test',\n-   'migration-test']\n+   'migration-test',\n+   'qtest-attrs-test']\n \n qtests_s390x = \\\n   qtests_filter + \\\ndiff --git a/tests/qtest/qtest-attrs-test.c b/tests/qtest/qtest-attrs-test.c\nnew file mode 100644\nindex 0000000000..cd6b81e505\n--- /dev/null\n+++ b/tests/qtest/qtest-attrs-test.c\n@@ -0,0 +1,350 @@\n+/*\n+ * QTest for memory access with transaction attributes\n+ *\n+ * Verify optional attrs argument support for qtest memory commands.\n+ *\n+ * Copyright (c) 2026 Phytium Technology\n+ *\n+ * Author:\n+ *  Tao Tang <tangtao1634@phytium.com.cn>\n+ *\n+ * SPDX-License-Identifier: GPL-2.0-or-later\n+ */\n+\n+#include \"qemu/osdep.h\"\n+#include \"libqtest.h\"\n+#include \"libqtest-single.h\"\n+\n+/*\n+ * The Arm virt test uses both the default non-secure RAM at 0x4000_0000 and\n+ * the secure-only RAM window at 0x0e00_0000. The x86 q35 test only exercises\n+ * regular RAM that is visible from both the default and SMM address spaces.\n+ */\n+#define TEST_ADDR_OFFSET_NS     0x1000ULL\n+#define TEST_ADDR_OFFSET_S      0xe000000ULL\n+#define TEST_ARM_SEC_BASE       0x0ULL\n+#define TEST_ARM_NS_BASE        0x40000000ULL\n+#define TEST_X86_BASE           0x0ULL\n+\n+#define TEST_ADDR_ARM_S         (TEST_ARM_SEC_BASE + TEST_ADDR_OFFSET_S)\n+#define TEST_ADDR_ARM_NS        (TEST_ARM_NS_BASE + TEST_ADDR_OFFSET_NS)\n+#define TEST_ADDR_X86           (TEST_X86_BASE + TEST_ADDR_OFFSET_NS)\n+\n+#define ARM_MACHINE_ARGS        \"-machine virt,secure=on -accel tcg\"\n+#define X86_MACHINE_ARGS        \"-machine q35,smm=on -m 1G -accel tcg\"\n+\n+static void G_GNUC_PRINTF(3, 4) assert_qtest_response(QTestState *qts,\n+                                                      const char *expected,\n+                                                      const char *fmt, ...)\n+{\n+    va_list ap;\n+    g_autofree gchar *cmd = NULL;\n+    g_autofree gchar *line = NULL;\n+    g_auto(GStrv) response = NULL;\n+\n+    va_start(ap, fmt);\n+    cmd = g_strdup_vprintf(fmt, ap);\n+    va_end(ap);\n+\n+    response = qtest_raw_cmd(qts, \"%s\", cmd);\n+    line = g_strjoinv(\" \", response);\n+    g_assert_cmpstr(line, ==, expected);\n+}\n+\n+static void G_GNUC_PRINTF(2, 3) assert_qtest_error_prefix(QTestState *qts,\n+                                                          const char *fmt, ...)\n+{\n+    va_list ap;\n+    g_autofree gchar *cmd = NULL;\n+    g_auto(GStrv) response = NULL;\n+\n+    va_start(ap, fmt);\n+    cmd = g_strdup_vprintf(fmt, ap);\n+    va_end(ap);\n+\n+    response = qtest_raw_cmd(qts, \"%s\", cmd);\n+    g_assert_cmpstr(response[0], ==, \"ERR\");\n+}\n+\n+static void test_arm_scalar_attrs(void)\n+{\n+    QTestState *qts;\n+    uint8_t val;\n+\n+    if (!qtest_has_machine(\"virt\")) {\n+        g_test_skip(\"virt machine not available\");\n+        return;\n+    }\n+\n+    qts = qtest_init(ARM_MACHINE_ARGS);\n+\n+    qtest_writeb_attrs(qts, TEST_ADDR_ARM_NS, 0x11, NULL);\n+    val = qtest_readb_attrs(qts, TEST_ADDR_ARM_NS, NULL);\n+    g_assert_cmpuint(val, ==, 0x11);\n+\n+    qtest_writeb_attrs(qts, TEST_ADDR_ARM_NS + 0x1, 0x22, \"space=non-secure\");\n+    val = qtest_readb_attrs(qts, TEST_ADDR_ARM_NS + 0x1, \"space=non-secure\");\n+    g_assert_cmpuint(val, ==, 0x22);\n+\n+    qtest_writeb_attrs(qts, TEST_ADDR_ARM_S + 0x2, 0x33, \"secure\");\n+    val = qtest_readb_attrs(qts, TEST_ADDR_ARM_S + 0x2, \"secure\");\n+    g_assert_cmpuint(val, ==, 0x33);\n+\n+    assert_qtest_response(qts, \"ERR invalid attrs argument\",\n+                          \"readb 0x%\" PRIx64 \" invalid\\n\",\n+                          (uint64_t)(TEST_ADDR_ARM_NS + 0x2));\n+    assert_qtest_response(qts,\n+                          \"ERR invalid space value. Valid space: \"\n+                          \"secure/non-secure/root/realm\",\n+                          \"readb 0x%\" PRIx64 \" space=invalid\\n\",\n+                          (uint64_t)(TEST_ADDR_ARM_NS + 0x2));\n+    assert_qtest_response(qts, \"ERR too many arguments\",\n+                          \"writeb 0x%\" PRIx64 \" 0x44 secure extra\\n\",\n+                          (uint64_t)(TEST_ADDR_ARM_NS + 0x2));\n+\n+    assert_qtest_error_prefix(qts, \"writeb 0x%\" PRIx64 \" 0x44 space=realm\\n\",\n+                              (uint64_t)(TEST_ADDR_ARM_S + 0x3));\n+    assert_qtest_error_prefix(qts, \"readb 0x%\" PRIx64 \" space=realm\\n\",\n+                              (uint64_t)(TEST_ADDR_ARM_S + 0x3));\n+\n+    qtest_writeb_attrs(qts, TEST_ADDR_ARM_S + 0x4, 0x55, \"space=root\");\n+    val = qtest_readb_attrs(qts, TEST_ADDR_ARM_S + 0x4, \"space=root\");\n+    g_assert_cmpuint(val, ==, 0x55);\n+\n+    qtest_writeb_attrs(qts, TEST_ADDR_ARM_S + 0x5, 0x66, \"space=secure\");\n+    val = qtest_readb_attrs(qts, TEST_ADDR_ARM_S + 0x5, \"space=secure\");\n+    g_assert_cmpuint(val, ==, 0x66);\n+\n+    qtest_writeb(qts, TEST_ADDR_ARM_NS + 0x6, 0x77);\n+    val = qtest_readb(qts, TEST_ADDR_ARM_NS + 0x6);\n+    g_assert_cmpuint(val, ==, 0x77);\n+    val = qtest_readb_attrs(qts, TEST_ADDR_ARM_NS + 0x6, \"space=non-secure\");\n+    g_assert_cmpuint(val, ==, 0x77);\n+\n+    assert_qtest_error_prefix(qts,\n+                              \"writeb 0x%\" PRIx64 \" 0x77 space=non-secure\\n\",\n+                              (uint64_t)(TEST_ADDR_ARM_S + 0x7));\n+    assert_qtest_error_prefix(qts, \"readb 0x%\" PRIx64 \" space=non-secure\\n\",\n+                              (uint64_t)(TEST_ADDR_ARM_S + 0x7));\n+\n+    qtest_quit(qts);\n+}\n+\n+static void test_arm_bulk_attrs(void)\n+{\n+    QTestState *qts;\n+    uint8_t wbuf[16] = {\n+        0x00, 0x11, 0x22, 0x33,\n+        0x44, 0x55, 0x66, 0x77,\n+        0x88, 0x99, 0xaa, 0xbb,\n+        0xcc, 0xdd, 0xee, 0xff,\n+    };\n+    uint8_t rbuf[16];\n+    size_t i;\n+\n+    if (!qtest_has_machine(\"virt\")) {\n+        g_test_skip(\"virt machine not available\");\n+        return;\n+    }\n+\n+    qts = qtest_init(ARM_MACHINE_ARGS);\n+\n+    qtest_memwrite_attrs(qts, TEST_ADDR_ARM_NS + 0x100,\n+                         wbuf, sizeof(wbuf), NULL);\n+    qtest_memread_attrs(qts, TEST_ADDR_ARM_NS + 0x100,\n+                        rbuf, sizeof(rbuf), NULL);\n+    g_assert(memcmp(wbuf, rbuf, sizeof(wbuf)) == 0);\n+\n+    qtest_memwrite_attrs(qts, TEST_ADDR_ARM_NS + 0x200,\n+                         wbuf, sizeof(wbuf), \"space=non-secure\");\n+    qtest_memread_attrs(qts, TEST_ADDR_ARM_NS + 0x200,\n+                        rbuf, sizeof(rbuf), \"space=non-secure\");\n+    g_assert(memcmp(wbuf, rbuf, sizeof(wbuf)) == 0);\n+\n+    qtest_memwrite_attrs(qts, TEST_ADDR_ARM_S + 0x300,\n+                         wbuf, sizeof(wbuf), \"secure\");\n+    qtest_memread_attrs(qts, TEST_ADDR_ARM_S + 0x300,\n+                        rbuf, sizeof(rbuf), \"secure\");\n+    g_assert(memcmp(wbuf, rbuf, sizeof(wbuf)) == 0);\n+\n+    qtest_memset_attrs(qts, TEST_ADDR_ARM_S + 0x400,\n+                       0xa5, sizeof(rbuf), \"space=root\");\n+    qtest_memread_attrs(qts, TEST_ADDR_ARM_S + 0x400,\n+                        rbuf, sizeof(rbuf), \"space=root\");\n+    for (i = 0; i < sizeof(rbuf); i++) {\n+        g_assert_cmpuint(rbuf[i], ==, 0xa5);\n+    }\n+\n+    qtest_bufwrite_attrs(qts, TEST_ADDR_ARM_NS + 0x500,\n+                         wbuf, sizeof(wbuf), \"space=non-secure\");\n+    qtest_bufread_attrs(qts, TEST_ADDR_ARM_NS + 0x500,\n+                        rbuf, sizeof(rbuf), \"space=non-secure\");\n+    g_assert(memcmp(wbuf, rbuf, sizeof(wbuf)) == 0);\n+\n+    qtest_bufwrite_attrs(qts, TEST_ADDR_ARM_S + 0x600,\n+                         wbuf, sizeof(wbuf), \"secure\");\n+    qtest_bufread_attrs(qts, TEST_ADDR_ARM_S + 0x600,\n+                        rbuf, sizeof(rbuf), \"secure\");\n+    g_assert(memcmp(wbuf, rbuf, sizeof(wbuf)) == 0);\n+\n+    qtest_memwrite(qts, TEST_ADDR_ARM_NS + 0x700, wbuf, 4);\n+    qtest_memread(qts, TEST_ADDR_ARM_NS + 0x700, rbuf, 4);\n+    g_assert(memcmp(wbuf, rbuf, 4) == 0);\n+\n+    qtest_memset(qts, TEST_ADDR_ARM_NS + 0x710, 0xa5, 4);\n+    qtest_memread(qts, TEST_ADDR_ARM_NS + 0x710, rbuf, 4);\n+    for (i = 0; i < 4; i++) {\n+        g_assert_cmpuint(rbuf[i], ==, 0xa5);\n+    }\n+\n+    qtest_bufwrite(qts, TEST_ADDR_ARM_NS + 0x720, wbuf, 4);\n+    qtest_bufread(qts, TEST_ADDR_ARM_NS + 0x720, rbuf, 4);\n+    g_assert(memcmp(wbuf, rbuf, 4) == 0);\n+\n+    assert_qtest_error_prefix(qts, \"write 0x%\" PRIx64 \" 0x%zx 0x00112233 \"\n+                              \"space=non-secure\\n\",\n+                              (uint64_t)(TEST_ADDR_ARM_S + 0x730),\n+                              (size_t)4);\n+    assert_qtest_error_prefix(qts, \"read 0x%\" PRIx64 \" 0x%zx \"\n+                              \"space=non-secure\\n\",\n+                              (uint64_t)(TEST_ADDR_ARM_S + 0x730), (size_t)4);\n+    assert_qtest_error_prefix(qts, \"memset 0x%\" PRIx64 \" 0x%zx 0xa5 \"\n+                              \"space=non-secure\\n\",\n+                              (uint64_t)(TEST_ADDR_ARM_S + 0x740),\n+                              (size_t)4);\n+    assert_qtest_error_prefix(qts, \"b64write 0x%\" PRIx64 \" 0x%zx AQIDBA== \"\n+                              \"space=non-secure\\n\",\n+                              (uint64_t)(TEST_ADDR_ARM_S + 0x750),\n+                              (size_t)4);\n+    assert_qtest_error_prefix(qts, \"b64read 0x%\" PRIx64 \" 0x%zx \"\n+                              \"space=non-secure\\n\",\n+                              (uint64_t)(TEST_ADDR_ARM_S + 0x750), (size_t)4);\n+    assert_qtest_response(qts, \"ERR too many arguments\",\n+                          \"write 0x%\" PRIx64 \" 0x%zx 0x00112233 secure \"\n+                          \"extra\\n\",\n+                          (uint64_t)(TEST_ADDR_ARM_NS + 0x760),\n+                          (size_t)4);\n+\n+    qtest_quit(qts);\n+}\n+\n+static void test_arm_single_shortcuts_attrs(void)\n+{\n+    uint8_t val;\n+    uint8_t wbuf[4] = { 0x10, 0x20, 0x30, 0x40 };\n+    uint8_t rbuf[4];\n+\n+    if (!qtest_has_machine(\"virt\")) {\n+        g_test_skip(\"virt machine not available\");\n+        return;\n+    }\n+\n+    qtest_start(ARM_MACHINE_ARGS);\n+\n+    writeb_attrs(TEST_ADDR_ARM_S + 0x700, 0x5a, \"secure\");\n+    val = readb_attrs(TEST_ADDR_ARM_S + 0x700, \"secure\");\n+    g_assert_cmpuint(val, ==, 0x5a);\n+\n+    writel_attrs(TEST_ADDR_ARM_S + 0x704,\n+                 0xa5a5a5a5, \"space=root\");\n+    g_assert_cmphex(readl_attrs(TEST_ADDR_ARM_S + 0x704, \"space=root\"), ==,\n+                    0xa5a5a5a5U);\n+\n+    memwrite_attrs(TEST_ADDR_ARM_NS + 0x708,\n+                   wbuf, sizeof(wbuf), \"space=non-secure\");\n+    memread_attrs(TEST_ADDR_ARM_NS + 0x708,\n+                  rbuf, sizeof(rbuf), \"space=non-secure\");\n+    g_assert(memcmp(wbuf, rbuf, sizeof(wbuf)) == 0);\n+\n+    qtest_end();\n+}\n+\n+static void test_x86_scalar_attrs(void)\n+{\n+    QTestState *qts;\n+    uint8_t val;\n+\n+    if (!qtest_has_machine(\"q35\")) {\n+        g_test_skip(\"q35 machine not available\");\n+        return;\n+    }\n+\n+    qts = qtest_init(X86_MACHINE_ARGS);\n+\n+    qtest_writeb_attrs(qts, TEST_ADDR_X86, 0x11, NULL);\n+    val = qtest_readb_attrs(qts, TEST_ADDR_X86, NULL);\n+    g_assert_cmpuint(val, ==, 0x11);\n+    val = qtest_readb_attrs(qts, TEST_ADDR_X86, \"secure\");\n+    g_assert_cmpuint(val, ==, 0x11);\n+\n+    qtest_writeb_attrs(qts, TEST_ADDR_X86 + 0x1, 0x22, \"secure\");\n+    val = qtest_readb_attrs(qts, TEST_ADDR_X86 + 0x1, \"secure\");\n+    g_assert_cmpuint(val, ==, 0x22);\n+    val = qtest_readb_attrs(qts, TEST_ADDR_X86 + 0x1, NULL);\n+    g_assert_cmpuint(val, ==, 0x22);\n+    assert_qtest_response(qts, \"ERR space=<...> is Arm-specific\",\n+                          \"readb 0x%\" PRIx64 \" space=secure\\n\",\n+                          (uint64_t)(TEST_ADDR_X86 + 0x2));\n+\n+    qtest_quit(qts);\n+}\n+\n+static void test_x86_bulk_attrs(void)\n+{\n+    QTestState *qts;\n+    uint8_t wbuf[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };\n+    uint8_t rbuf[8];\n+    size_t i;\n+\n+    if (!qtest_has_machine(\"q35\")) {\n+        g_test_skip(\"q35 machine not available\");\n+        return;\n+    }\n+\n+    qts = qtest_init(X86_MACHINE_ARGS);\n+\n+    qtest_memwrite_attrs(qts, TEST_ADDR_X86 + 0x100, wbuf, sizeof(wbuf), NULL);\n+    qtest_memread_attrs(qts, TEST_ADDR_X86 + 0x100,\n+                        rbuf, sizeof(rbuf), \"secure\");\n+    g_assert(memcmp(wbuf, rbuf, sizeof(wbuf)) == 0);\n+\n+    qtest_memwrite_attrs(qts, TEST_ADDR_X86 + 0x180,\n+                         wbuf, sizeof(wbuf), \"secure\");\n+    qtest_memread_attrs(qts, TEST_ADDR_X86 + 0x180,\n+                        rbuf, sizeof(rbuf), NULL);\n+    g_assert(memcmp(wbuf, rbuf, sizeof(wbuf)) == 0);\n+\n+    qtest_memset_attrs(qts, TEST_ADDR_X86 + 0x200,\n+                       0x3c, sizeof(rbuf), \"secure\");\n+    qtest_memread_attrs(qts, TEST_ADDR_X86 + 0x200,\n+                        rbuf, sizeof(rbuf), NULL);\n+    for (i = 0; i < sizeof(rbuf); i++) {\n+        g_assert_cmpuint(rbuf[i], ==, 0x3c);\n+    }\n+\n+    qtest_bufwrite_attrs(qts, TEST_ADDR_X86 + 0x280,\n+                         wbuf, sizeof(wbuf), NULL);\n+    qtest_bufread_attrs(qts, TEST_ADDR_X86 + 0x280,\n+                        rbuf, sizeof(rbuf), \"secure\");\n+    g_assert(memcmp(wbuf, rbuf, sizeof(wbuf)) == 0);\n+    assert_qtest_response(qts, \"ERR too many arguments\",\n+                          \"read 0x%\" PRIx64 \" 0x%zx secure extra\\n\",\n+                          (uint64_t)(TEST_ADDR_X86 + 0x300),\n+                          sizeof(rbuf));\n+\n+    qtest_quit(qts);\n+}\n+\n+int main(int argc, char **argv)\n+{\n+    g_test_init(&argc, &argv, NULL);\n+\n+    qtest_add_func(\"/qtest/arm/attrs/scalar\", test_arm_scalar_attrs);\n+    qtest_add_func(\"/qtest/arm/attrs/bulk\", test_arm_bulk_attrs);\n+    qtest_add_func(\"/qtest/arm/attrs/single_shortcuts\",\n+                   test_arm_single_shortcuts_attrs);\n+    qtest_add_func(\"/qtest/x86/attrs/scalar\", test_x86_scalar_attrs);\n+    qtest_add_func(\"/qtest/x86/attrs/bulk\", test_x86_bulk_attrs);\n+\n+    return g_test_run();\n+}\n",
    "prefixes": [
        "3/4"
    ]
}