Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2217952/?format=api
{ "id": 2217952, "url": "http://patchwork.ozlabs.org/api/patches/2217952/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260331040659.401397-5-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-5-tangtao1634@phytium.com.cn>", "list_archive_url": null, "date": "2026-03-31T04:06:59", "name": "[4/4,NOT-MERGE] tests/qtest: add q35 SMM-only x86 attrs coverage", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "51c458f2ee8ae629a3c9e318c60a110674c7f4e7", "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-5-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/2217952/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2217952/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 4flF472kg1z1yGT\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 31 Mar 2026 15:09:11 +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 1w7QOT-000133-9m; Tue, 31 Mar 2026 00:07:57 -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 1w7QOL-0000zZ-Qa; Tue, 31 Mar 2026 00:07:50 -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 1w7QOI-0002Gy-EZ; Tue, 31 Mar 2026 00:07:49 -0400", "from prodtpl.icoremail.net (unknown [10.12.1.20])\n by hzbj-icmmx-7 (Coremail) with SMTP id AQAAfwB3fpqNSMtp8YjBCA--.55S2;\n Tue, 31 Mar 2026 12:07:41 +0800 (CST)", "from phytium.com.cn (unknown [218.76.62.144])\n by mail (Coremail) with SMTP id AQAAf8DwSJR6SMtpYqQHAA--.18366S7;\n Tue, 31 Mar 2026 12:07:39 +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 4/4] [NOT-MERGE] tests/qtest: add q35 SMM-only x86 attrs\n coverage", "Date": "Tue, 31 Mar 2026 12:06:59 +0800", "Message-Id": "<20260331040659.401397-5-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--.18366S7", "X-CM-SenderInfo": "pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQALBWnKzfEBswABsj", "X-Coremail-Antispam": "1Uk129KBjvJXoW3Ar43Gw43WF4rCF1DCryUKFg_yoWDGr1fpF\n y5CFnIkF4ay3WxZa1DJa17G3WF9Fs3Ca4UurWUGwnYka18CF9FyryqkFyvqrnrJrW0vw1r\n Z3WDJFsrG3Z8taDanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj\n DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU\n UUUUU", "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": "Add a q35-only test path for x86 secure attrs by introducing an optional\ntest-only RAM region that is mapped only into the SMM address space.\n\nThe new qtest-x86-attrs-test enables this region with\n`-global mch.x-smm-test-ram=on` and verifies that accesses with the\n`secure` attribute reach the SMM-only region, while default accesses do\nnot. This provides the x86 cross-verification that qtest-attrs-test does\nnot cover, where normal RAM is visible from both the default and SMM\naddress spaces.\n\nThis is a NOT-MERGE commit.\n\nSigned-off-by: Tao Tang <tangtao1634@phytium.com.cn>\n---\n hw/pci-host/q35.c | 26 +++++\n include/hw/pci-host/q35.h | 8 ++\n tests/qtest/meson.build | 1 +\n tests/qtest/qtest-x86-attrs-test.c | 170 +++++++++++++++++++++++++++++\n 4 files changed, 205 insertions(+)\n create mode 100644 tests/qtest/qtest-x86-attrs-test.c", "diff": "diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c\nindex e85e4227b3..5b222847b3 100644\n--- a/hw/pci-host/q35.c\n+++ b/hw/pci-host/q35.c\n@@ -566,12 +566,19 @@ static void mch_realize(PCIDevice *d, Error **errp)\n int i;\n MCHPCIState *mch = MCH_PCI_DEVICE(d);\n \n+ ERRP_GUARD();\n+\n if (mch->ext_tseg_mbytes > MCH_HOST_BRIDGE_EXT_TSEG_MBYTES_MAX) {\n error_setg(errp, \"invalid extended-tseg-mbytes value: %\" PRIu16,\n mch->ext_tseg_mbytes);\n return;\n }\n \n+ if (mch->enable_smm_test_ram && !mch->has_smm_ranges) {\n+ error_setg(errp, \"x-smm-test-ram requires SMM support\");\n+ return;\n+ }\n+\n /* setup pci memory mapping */\n pc_pci_as_mapping_init(mch->system_memory, mch->pci_address_space);\n \n@@ -653,6 +660,23 @@ static void mch_realize(PCIDevice *d, Error **errp)\n memory_region_add_subregion(&mch->smram, MCH_HOST_BRIDGE_SMBASE_ADDR,\n &mch->smbase_window);\n \n+ if (mch->enable_smm_test_ram) {\n+ /*\n+ * This is a QEMU-specific, test-only region. It is mapped only into\n+ * mch->smram so qtest can verify that x86 secure attrs select the SMM\n+ * address space rather than the default one.\n+ */\n+ memory_region_init_ram(&mch->smm_test_ram, OBJECT(mch),\n+ \"smm-test-ram\",\n+ MCH_HOST_BRIDGE_SMM_TEST_RAM_SIZE, errp);\n+ if (*errp) {\n+ return;\n+ }\n+ memory_region_add_subregion(&mch->smram,\n+ MCH_HOST_BRIDGE_SMM_TEST_RAM_BASE,\n+ &mch->smm_test_ram);\n+ }\n+\n object_property_add_const_link(qdev_get_machine(), \"smram\",\n OBJECT(&mch->smram));\n }\n@@ -661,6 +685,8 @@ static const Property mch_props[] = {\n DEFINE_PROP_UINT16(\"extended-tseg-mbytes\", MCHPCIState, ext_tseg_mbytes,\n 64),\n DEFINE_PROP_BOOL(\"smbase-smram\", MCHPCIState, has_smram_at_smbase, true),\n+ DEFINE_PROP_BOOL(\"x-smm-test-ram\", MCHPCIState, enable_smm_test_ram,\n+ false),\n };\n \n static void mch_class_init(ObjectClass *klass, const void *data)\ndiff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h\nindex ddafc3f2e3..1ca26f0e63 100644\n--- a/include/hw/pci-host/q35.h\n+++ b/include/hw/pci-host/q35.h\n@@ -49,8 +49,10 @@ struct MCHPCIState {\n MemoryRegion smram, low_smram, high_smram;\n MemoryRegion tseg_blackhole, tseg_window;\n MemoryRegion smbase_blackhole, smbase_window;\n+ MemoryRegion smm_test_ram;\n bool has_smram_at_smbase;\n bool has_smm_ranges;\n+ bool enable_smm_test_ram;\n Range pci_hole;\n uint64_t below_4g_mem_size;\n uint64_t above_4g_mem_size;\n@@ -99,6 +101,12 @@ struct Q35PCIHost {\n #define MCH_HOST_BRIDGE_PCIEXBAR_SIZE 8 /* 64bit register */\n #define MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT 0xb0000000\n #define MCH_HOST_BRIDGE_PCIEXBAR_MAX (0x10000000) /* 256M */\n+/*\n+ * Optional qtest-only RAM window used to expose an address that exists only\n+ * in the SMM address space, so x86 secure attrs can be cross-checked.\n+ */\n+#define MCH_HOST_BRIDGE_SMM_TEST_RAM_BASE 0xfef00000\n+#define MCH_HOST_BRIDGE_SMM_TEST_RAM_SIZE (64 * KiB)\n #define MCH_HOST_BRIDGE_PCIEXBAR_ADMSK Q35_MASK(64, 35, 28)\n #define MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK ((uint64_t)(1 << 26))\n #define MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK ((uint64_t)(1 << 25))\ndiff --git a/tests/qtest/meson.build b/tests/qtest/meson.build\nindex 87aa104d23..fcdd95bf7f 100644\n--- a/tests/qtest/meson.build\n+++ b/tests/qtest/meson.build\n@@ -116,6 +116,7 @@ qtests_i386 = \\\n 'cpu-plug-test',\n 'migration-test',\n 'qtest-attrs-test',\n+ 'qtest-x86-attrs-test',\n ]\n \n if dbus_display and config_all_devices.has_key('CONFIG_VGA')\ndiff --git a/tests/qtest/qtest-x86-attrs-test.c b/tests/qtest/qtest-x86-attrs-test.c\nnew file mode 100644\nindex 0000000000..068ee8b7d3\n--- /dev/null\n+++ b/tests/qtest/qtest-x86-attrs-test.c\n@@ -0,0 +1,170 @@\n+/*\n+ * QTest for x86 memory access with transaction attributes\n+ *\n+ * Verify q35 SMM address-space access with the secure attribute.\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 \"qemu/cutils.h\"\n+#include \"libqtest.h\"\n+\n+#define TEST_ADDR_OFFSET_NS 0x1000ULL\n+#define TEST_X86_BASE 0x0ULL\n+#define TEST_X86_SMM_BASE 0xfef00000ULL\n+\n+#define TEST_ADDR_X86 (TEST_X86_BASE + TEST_ADDR_OFFSET_NS)\n+\n+#define X86_MACHINE_ARGS \"-machine q35,smm=on -m 1G -accel tcg \" \\\n+ \"-global mch.x-smm-test-ram=on\"\n+\n+static void assert_default_scalar_read_isolated(QTestState *qts, uint64_t addr,\n+ char **before,\n+ uint8_t secure_value)\n+{\n+ g_auto(GStrv) after = NULL;\n+ uint64_t value;\n+ int ret;\n+\n+ after = qtest_raw_cmd(qts, \"readb 0x%\" PRIx64 \"\\n\", addr);\n+\n+ if (g_strcmp0(before[0], \"ERR\") == 0) {\n+ g_assert_cmpstr(after[0], ==, \"ERR\");\n+ return;\n+ }\n+\n+ g_assert_cmpstr(before[0], ==, \"OK\");\n+ g_assert_nonnull(before[1]);\n+ g_assert_cmpstr(after[0], ==, \"OK\");\n+ g_assert_nonnull(after[1]);\n+ g_assert_cmpstr(after[1], ==, before[1]);\n+\n+ ret = qemu_strtou64(after[1], NULL, 0, &value);\n+ g_assert_cmpint(ret, ==, 0);\n+ g_assert_cmpuint(value, !=, secure_value);\n+}\n+\n+static void assert_default_bulk_read_isolated(QTestState *qts, uint64_t addr,\n+ char **before,\n+ const uint8_t *expected,\n+ size_t len)\n+{\n+ g_auto(GStrv) after = NULL;\n+ g_autofree gchar *expected_b64 = NULL;\n+\n+ expected_b64 = g_base64_encode(expected, len);\n+ after = qtest_raw_cmd(qts, \"b64read 0x%\" PRIx64 \" 0x%zx\\n\", addr, len);\n+\n+ if (g_strcmp0(before[0], \"ERR\") == 0) {\n+ g_assert_cmpstr(after[0], ==, \"ERR\");\n+ return;\n+ }\n+\n+ g_assert_cmpstr(before[0], ==, \"OK\");\n+ g_assert_nonnull(before[1]);\n+ g_assert_cmpstr(after[0], ==, \"OK\");\n+ g_assert_nonnull(after[1]);\n+ g_assert_cmpstr(after[1], ==, before[1]);\n+ g_assert_cmpstr(after[1], !=, expected_b64);\n+}\n+\n+static void test_x86_scalar_attrs(void)\n+{\n+ QTestState *qts;\n+ g_auto(GStrv) before = NULL;\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+\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+\n+ before = qtest_raw_cmd(qts, \"readb 0x%\" PRIx64 \"\\n\",\n+ (uint64_t)(TEST_X86_SMM_BASE + 0x2));\n+ qtest_writeb_attrs(qts, TEST_X86_SMM_BASE + 0x2, 0x33, \"secure\");\n+ val = qtest_readb_attrs(qts, TEST_X86_SMM_BASE + 0x2, \"secure\");\n+ g_assert_cmpuint(val, ==, 0x33);\n+ assert_default_scalar_read_isolated(qts, TEST_X86_SMM_BASE + 0x2,\n+ before, 0x33);\n+\n+ qtest_quit(qts);\n+}\n+\n+static void test_x86_bulk_attrs(void)\n+{\n+ QTestState *qts;\n+ g_auto(GStrv) before = NULL;\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, rbuf, sizeof(rbuf), NULL);\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), \"secure\");\n+ g_assert(memcmp(wbuf, rbuf, sizeof(wbuf)) == 0);\n+\n+ before = qtest_raw_cmd(qts, \"b64read 0x%\" PRIx64 \" 0x%zx\\n\",\n+ (uint64_t)(TEST_X86_SMM_BASE + 0x100),\n+ sizeof(wbuf));\n+ qtest_memwrite_attrs(qts, TEST_X86_SMM_BASE + 0x100,\n+ wbuf, sizeof(wbuf), \"secure\");\n+ qtest_memread_attrs(qts, TEST_X86_SMM_BASE + 0x100,\n+ rbuf, sizeof(rbuf), \"secure\");\n+ g_assert(memcmp(wbuf, rbuf, sizeof(wbuf)) == 0);\n+ assert_default_bulk_read_isolated(qts, TEST_X86_SMM_BASE + 0x100, before,\n+ wbuf, sizeof(wbuf));\n+\n+ qtest_memset_attrs(qts, TEST_X86_SMM_BASE + 0x120,\n+ 0x5a, sizeof(rbuf), \"secure\");\n+ qtest_memread_attrs(qts, TEST_X86_SMM_BASE + 0x120,\n+ rbuf, sizeof(rbuf), \"secure\");\n+ for (i = 0; i < sizeof(rbuf); i++) {\n+ g_assert_cmpuint(rbuf[i], ==, 0x5a);\n+ }\n+\n+ qtest_bufwrite_attrs(qts, TEST_X86_SMM_BASE + 0x200,\n+ wbuf, sizeof(wbuf), \"secure\");\n+ qtest_bufread_attrs(qts, TEST_X86_SMM_BASE + 0x200,\n+ rbuf, sizeof(rbuf), \"secure\");\n+ g_assert(memcmp(wbuf, rbuf, sizeof(wbuf)) == 0);\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/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": [ "4/4", "NOT-MERGE" ] }