[{"id":3683464,"web_url":"http://patchwork.ozlabs.org/comment/3683464/","msgid":"<20260428132657.GA591628@e124191.cambridge.arm.com>","list_archive_url":null,"date":"2026-04-28T13:26:57","subject":"Re: [kvm-unit-tests PATCH] arm: add wfx test case","submitter":{"id":81056,"url":"http://patchwork.ozlabs.org/api/people/81056/","name":"Joey Gouly","email":"joey.gouly@arm.com"},"content":"Hi,\n\nFew small comments.\n\nOn Mon, Apr 27, 2026 at 02:00:45PM +0100, Alex Bennée wrote:\n> This is based on a similar test case I wrote for QEMU's tcg tests although\n> obviously able to take advantage of kvm-unit-tests additional plumbing for\n> dealing with the GIC and IRQs.\n> \n> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>\n> ---\n>  arm/Makefile.arm64        |   1 +\n>  lib/arm64/asm/processor.h |   7 ++\n>  lib/arm64/asm/sysreg.h    |   3 +\n>  arm/wfx.c                 | 137 ++++++++++++++++++++++++++++++++++++++\n>  arm/unittests.cfg         |   5 ++\n>  5 files changed, 153 insertions(+)\n>  create mode 100644 arm/wfx.c\n> \n> diff --git a/arm/Makefile.arm64 b/arm/Makefile.arm64\n> index a40c830d..52b3f35d 100644\n> --- a/arm/Makefile.arm64\n> +++ b/arm/Makefile.arm64\n> @@ -64,6 +64,7 @@ tests += $(TEST_DIR)/cache.$(exe)\n>  tests += $(TEST_DIR)/debug.$(exe)\n>  tests += $(TEST_DIR)/fpu.$(exe)\n>  tests += $(TEST_DIR)/mte.$(exe)\n> +tests += $(TEST_DIR)/wfx.$(exe)\n>  \n>  include $(SRCDIR)/$(TEST_DIR)/Makefile.common\n>  \n> diff --git a/lib/arm64/asm/processor.h b/lib/arm64/asm/processor.h\n> index 32ddc1b3..2104036d 100644\n> --- a/lib/arm64/asm/processor.h\n> +++ b/lib/arm64/asm/processor.h\n> @@ -173,5 +173,12 @@ static inline bool system_supports_rndr(void)\n>  \treturn ((id_aa64isar0_el1 >> ID_AA64ISAR0_EL1_RNDR_SHIFT) & 0xf) != 0;\n>  }\n>  \n> +static inline bool system_supports_wfxt(void)\n> +{\n> +\tu64 id_aa64isar2_el1 = read_sysreg_s(ID_AA64ISAR2_EL1);\n> +\n> +\treturn ((id_aa64isar2_el1 >> ID_AA64ISAR2_EL1_WFxT_SHIFT) & 0xf) != 0;\n> +}\n> +\n>  #endif /* !__ASSEMBLER__ */\n>  #endif /* _ASMARM64_PROCESSOR_H_ */\n> diff --git a/lib/arm64/asm/sysreg.h b/lib/arm64/asm/sysreg.h\n> index f2d05018..cb96a649 100644\n> --- a/lib/arm64/asm/sysreg.h\n> +++ b/lib/arm64/asm/sysreg.h\n> @@ -77,6 +77,9 @@ asm(\n>  #define ID_AA64ISAR0_EL1_RNDR_SHIFT\t60\n>  #define ID_AA64PFR1_EL1_MTE_SHIFT\t8\n>  \n> +#define ID_AA64ISAR2_EL1\t\tsys_reg(3, 0, 0, 6, 2)\n> +#define ID_AA64ISAR2_EL1_WFxT_SHIFT\t0\n> +\n>  #define ID_AA64MMFR0_EL1_FGT_SHIFT\t56\n>  #define ID_AA64MMFR0_EL1_FGT_FGT2\t0x2\n>  \n> diff --git a/arm/wfx.c b/arm/wfx.c\n> new file mode 100644\n> index 00000000..912e50e6\n> --- /dev/null\n> +++ b/arm/wfx.c\n> @@ -0,0 +1,137 @@\n> +/*\n> + * WFX Instructions Test (WFI, WFE, WFIT, WFET)\n> + *\n> + * Copyright (c) 2026 Linaro Ltd\n> + *\n> + * SPDX-License-Identifier: GPL-2.0-or-later\n> + */\n> +\n> +#include <libcflat.h>\n> +#include <asm/processor.h>\n> +#include <asm/gic.h>\n> +#include <asm/timer.h>\n> +#include <asm/io.h>\n> +\n> +#define TIMEOUT 200000\n\nInstead of a hardcoded TIMEOUT, what about something similar to arm/timer.c:\n\n\tu64 time_10ms = read_sysreg(cntfrq_el0) / 100;\n\n> +\n> +#define sev() asm volatile(\"sev\" : : : \"memory\")\n> +#define sevl() asm volatile(\"sevl\" : : : \"memory\")\n> +#define wfi() asm volatile(\"wfi\" : : : \"memory\")\n> +#define wfe() asm volatile(\"wfe\" : : : \"memory\")\n> +\n> +#define wfit(reg) \\\n> +\tasm volatile(\".arch armv8.7-a\\n\\twfit %0\" : : \"r\" (reg) : \"memory\")\n> +#define wfet(reg) \\\n> +\tasm volatile(\".arch armv8.7-a\\n\\twfet %0\" : : \"r\" (reg) : \"memory\")\n> +\n> +static void timer_handler(struct pt_regs *regs)\n> +{\n> +\t/* Disable timer to stop IRQ from re-firing */\n> +\twrite_sysreg(0, cntv_ctl_el0);\n> +}\n> +\n> +static bool check_elapsed(uint64_t start, uint64_t threshold, const char *test, bool more)\n> +{\n> +\tuint64_t end = read_sysreg(cntvct_el0);\n> +\tuint64_t elapsed = end - start;\n> +\tbool pass = more ? elapsed >= threshold : elapsed <= threshold;\n> +\n> +\treport(pass, \"%s (%ld ticks)\", test, elapsed);\n> +\n> +\tif (!pass) {\n> +\t\treport_info(\"%s %s\", test, more ? \"woke too early\" : \"slept despite SEV\");\n> +\t}\n> +\treturn pass;\n> +}\n> +\n> +static void test_wfi(void)\n> +{\n> +\tuint64_t start;\n> +\n> +\treport_info(\"Testing WFI...\");\n> +\n> +\tstart = read_sysreg(cntvct_el0);\n> +\twrite_sysreg(TIMEOUT, cntv_tval_el0);\n> +\twrite_sysreg(1, cntv_ctl_el0); /* Enable timer, no mask */\n> +\tisb();\n> +\n> +\tlocal_irq_enable();\n> +\twfi();\n> +\tlocal_irq_disable();\n> +\n> +\tcheck_elapsed(start, TIMEOUT, \"WFI\", true);\n> +}\n> +\n> +static void test_wfe(void)\n> +{\n> +\tuint64_t start;\n> +\n\nI think a comment here would be good, just to say it's testing that a wfe\ndoesn't sleep for a 'long' period with no pending events, or something like\nthat?\n\n> +\treport_info(\"Testing WFE/SEV...\");\n> +\tsev();\n> +\tstart = read_sysreg(cntvct_el0);\n> +\twfe();\n> +\tcheck_elapsed(start, TIMEOUT, \"WFE/SEV\", false);\n> +\n> +\treport_info(\"Testing WFE/SEVL...\");\n> +\tsevl();\n> +\tstart = read_sysreg(cntvct_el0);\n> +\twfe();\n> +\tcheck_elapsed(start, TIMEOUT, \"WFE/SEVL\", false);\n> +}\n> +\n> +static void test_wfit(void)\n> +{\n> +\tuint64_t start, timeout;\n> +\n> +\treport_info(\"Testing WFIT...\");\n> +\tstart = read_sysreg(cntvct_el0);\n> +\ttimeout = start + TIMEOUT;\n> +\twfit(timeout);\n> +\tcheck_elapsed(start, TIMEOUT, \"WFIT\", true);\n> +}\n> +\n> +static void test_wfet(void)\n> +{\n> +\tuint64_t start, timeout;\n> +\n> +\treport_info(\"Testing WFET...\");\n> +\t/* Ensure no pending events */\n> +\tsev();\n\nCould this just be sevl here? Not that it really matters.\n\n> +\twfe();\n> +\n> +\tstart = read_sysreg(cntvct_el0);\n> +\ttimeout = start + TIMEOUT;\n> +\twfet(timeout);\n> +\tcheck_elapsed(start, TIMEOUT, \"WFET\", true);\n> +}\n> +\n> +int main(void)\n> +{\n> +\n> +\tif (gic_init() < 0) {\n> +\t\treport_abort(\"GIC init failed\");\n> +\t\treturn 1;\n> +\t}\n> +\n> +\t/* Install timer handler for WFI wake-up */\n> +\tinstall_irq_handler(EL1H_IRQ, timer_handler);\n> +\tgic_enable_defaults();\n> +\n> +\t/* Enable Virtual Timer PPI */\n> +\tgic_irq_set_clr_enable(27, true);\n\nInstead of hardcoding 27 here, you can use:\n\n\tu32 irq = current_level() == CurrentEL_EL1 ? TIMER_VTIMER_IRQ : TIMER_HVTIMER_IRQ;                                                                     \n\tgic_irq_set_clr_enable(irq, true);\n\nWhich also allows the test to run at EL2.\n\n> +\n> +\treport_prefix_push(\"WFx\");\n> +\ttest_wfi();\n> +\ttest_wfe();\n> +\treport_prefix_pop();\n> +\n> +\tif (system_supports_wfxt()) {\n> +\t\treport_prefix_push(\"WFxT\");\n> +\t\ttest_wfit();\n> +\t\ttest_wfet();\n> +\t} else {\n> +\t\treport_skip(\"WFxT instructions not supported\");\n> +\t}\n> +\n> +\treturn report_summary();\n> +}\n> diff --git a/arm/unittests.cfg b/arm/unittests.cfg\n> index 12fc4468..7adf96f2 100644\n> --- a/arm/unittests.cfg\n> +++ b/arm/unittests.cfg\n> @@ -339,3 +339,8 @@ groups = mte\n>  test_args = asymm\n>  qemu_params = -machine mte=on\n>  arch = arm64\n> +\n> +[wfx]\n> +file = wfx.flat\n> +groups = wfx\n> +arch = arm64\n\nThanks,\nJoey","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=fail reason=\"signature verification failed\" (1024-bit key;\n unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256\n header.s=foss header.b=cMe7uZnX;\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=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from lists1p.gnu.org (lists1p.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 4g4hLG2rqyz1xrS\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 28 Apr 2026 23:36:54 +1000 (AEST)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wHibb-0005Zw-Pd; Tue, 28 Apr 2026 09:36:03 -0400","from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <joey.gouly@arm.com>)\n id 1wHiT1-0002zw-Th\n for qemu-devel@nongnu.org; Tue, 28 Apr 2026 09:27:11 -0400","from foss.arm.com ([217.140.110.172])\n by eggs.gnu.org with esmtp (Exim 4.90_1)\n (envelope-from <joey.gouly@arm.com>) id 1wHiSz-0006tT-Jo\n for qemu-devel@nongnu.org; Tue, 28 Apr 2026 09:27:11 -0400","from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14])\n by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E2C0B497;\n Tue, 28 Apr 2026 06:27:00 -0700 (PDT)","from e124191.cambridge.arm.com (e124191.cambridge.arm.com\n [10.1.197.45])\n by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 0B23B3F62B;\n Tue, 28 Apr 2026 06:27:04 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss;\n t=1777382826; bh=IyapETfcrA5bdzogS0BMgrPXC9c/KLCTS2PzVSSlXMo=;\n h=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n b=cMe7uZnXRS3E8eiaXBZbf/31/9iUxv+ImqQ6FjohOPE8MehQgU634Hpr6XSuDjIpo\n igQNg12C5u3+RpzYi2ngwf9eqHo5924XcBQ1KN36+NNo3TPokhBaVJEBqBumQzpe0i\n U/xwFwL5j/3UvcdUvyenH7P8iTzIyRS4oF2HdjvE=","Date":"Tue, 28 Apr 2026 14:26:57 +0100","From":"Joey Gouly <joey.gouly@arm.com>","To":"Alex =?utf-8?q?Benn=C3=A9e?= <alex.bennee@linaro.org>","Cc":"qemu-devel@nongnu.org, Andrew Jones <andrew.jones@linux.dev>,\n Alexandru Elisei <alexandru.elisei@arm.com>,\n Eric Auger <eric.auger@redhat.com>,\n \"open list:ARM\" <kvmarm@lists.linux.dev>,\n \"open list:Default mailing list\" <kvm@vger.kernel.org>","Subject":"Re: [kvm-unit-tests PATCH] arm: add wfx test case","Message-ID":"<20260428132657.GA591628@e124191.cambridge.arm.com>","References":"<20260427130045.3669851-1-alex.bennee@linaro.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20260427130045.3669851-1-alex.bennee@linaro.org>","Received-SPF":"pass client-ip=217.140.110.172;\n envelope-from=joey.gouly@arm.com;\n helo=foss.arm.com","X-Spam_score_int":"-43","X-Spam_score":"-4.4","X-Spam_bar":"----","X-Spam_report":"(-4.4 / 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_MED=-2.3, SPF_HELO_PASS=-0.001,\n SPF_PASS=-0.001 autolearn=ham autolearn_force=no","X-Spam_action":"no action","X-Mailman-Approved-At":"Tue, 28 Apr 2026 09:36:02 -0400","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"}},{"id":3683528,"web_url":"http://patchwork.ozlabs.org/comment/3683528/","msgid":"<87h5ovdtge.fsf@draig.linaro.org>","list_archive_url":null,"date":"2026-04-28T14:56:33","subject":"Re: [kvm-unit-tests PATCH] arm: add wfx test case","submitter":{"id":39532,"url":"http://patchwork.ozlabs.org/api/people/39532/","name":"Alex Bennée","email":"alex.bennee@linaro.org"},"content":"Joey Gouly <joey.gouly@arm.com> writes:\n\n> Hi,\n>\n> Few small comments.\n>\n> On Mon, Apr 27, 2026 at 02:00:45PM +0100, Alex Bennée wrote:\n>> This is based on a similar test case I wrote for QEMU's tcg tests although\n>> obviously able to take advantage of kvm-unit-tests additional plumbing for\n>> dealing with the GIC and IRQs.\n>> \n>> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>\n>> ---\n>>  arm/Makefile.arm64        |   1 +\n>>  lib/arm64/asm/processor.h |   7 ++\n>>  lib/arm64/asm/sysreg.h    |   3 +\n>>  arm/wfx.c                 | 137 ++++++++++++++++++++++++++++++++++++++\n>>  arm/unittests.cfg         |   5 ++\n>>  5 files changed, 153 insertions(+)\n>>  create mode 100644 arm/wfx.c\n>> \n>> diff --git a/arm/Makefile.arm64 b/arm/Makefile.arm64\n>> index a40c830d..52b3f35d 100644\n>> --- a/arm/Makefile.arm64\n>> +++ b/arm/Makefile.arm64\n>> @@ -64,6 +64,7 @@ tests += $(TEST_DIR)/cache.$(exe)\n>>  tests += $(TEST_DIR)/debug.$(exe)\n>>  tests += $(TEST_DIR)/fpu.$(exe)\n>>  tests += $(TEST_DIR)/mte.$(exe)\n>> +tests += $(TEST_DIR)/wfx.$(exe)\n>>  \n>>  include $(SRCDIR)/$(TEST_DIR)/Makefile.common\n>>  \n>> diff --git a/lib/arm64/asm/processor.h b/lib/arm64/asm/processor.h\n>> index 32ddc1b3..2104036d 100644\n>> --- a/lib/arm64/asm/processor.h\n>> +++ b/lib/arm64/asm/processor.h\n>> @@ -173,5 +173,12 @@ static inline bool system_supports_rndr(void)\n>>  \treturn ((id_aa64isar0_el1 >> ID_AA64ISAR0_EL1_RNDR_SHIFT) & 0xf) != 0;\n>>  }\n>>  \n>> +static inline bool system_supports_wfxt(void)\n>> +{\n>> +\tu64 id_aa64isar2_el1 = read_sysreg_s(ID_AA64ISAR2_EL1);\n>> +\n>> +\treturn ((id_aa64isar2_el1 >> ID_AA64ISAR2_EL1_WFxT_SHIFT) & 0xf) != 0;\n>> +}\n>> +\n>>  #endif /* !__ASSEMBLER__ */\n>>  #endif /* _ASMARM64_PROCESSOR_H_ */\n>> diff --git a/lib/arm64/asm/sysreg.h b/lib/arm64/asm/sysreg.h\n>> index f2d05018..cb96a649 100644\n>> --- a/lib/arm64/asm/sysreg.h\n>> +++ b/lib/arm64/asm/sysreg.h\n>> @@ -77,6 +77,9 @@ asm(\n>>  #define ID_AA64ISAR0_EL1_RNDR_SHIFT\t60\n>>  #define ID_AA64PFR1_EL1_MTE_SHIFT\t8\n>>  \n>> +#define ID_AA64ISAR2_EL1\t\tsys_reg(3, 0, 0, 6, 2)\n>> +#define ID_AA64ISAR2_EL1_WFxT_SHIFT\t0\n>> +\n>>  #define ID_AA64MMFR0_EL1_FGT_SHIFT\t56\n>>  #define ID_AA64MMFR0_EL1_FGT_FGT2\t0x2\n>>  \n>> diff --git a/arm/wfx.c b/arm/wfx.c\n>> new file mode 100644\n>> index 00000000..912e50e6\n>> --- /dev/null\n>> +++ b/arm/wfx.c\n>> @@ -0,0 +1,137 @@\n>> +/*\n>> + * WFX Instructions Test (WFI, WFE, WFIT, WFET)\n>> + *\n>> + * Copyright (c) 2026 Linaro Ltd\n>> + *\n>> + * SPDX-License-Identifier: GPL-2.0-or-later\n>> + */\n>> +\n>> +#include <libcflat.h>\n>> +#include <asm/processor.h>\n>> +#include <asm/gic.h>\n>> +#include <asm/timer.h>\n>> +#include <asm/io.h>\n>> +\n>> +#define TIMEOUT 200000\n>\n> Instead of a hardcoded TIMEOUT, what about something similar to arm/timer.c:\n>\n> \tu64 time_10ms = read_sysreg(cntfrq_el0) / 100;\n\nok\n\n>\n>> +\n>> +#define sev() asm volatile(\"sev\" : : : \"memory\")\n>> +#define sevl() asm volatile(\"sevl\" : : : \"memory\")\n>> +#define wfi() asm volatile(\"wfi\" : : : \"memory\")\n>> +#define wfe() asm volatile(\"wfe\" : : : \"memory\")\n>> +\n>> +#define wfit(reg) \\\n>> +\tasm volatile(\".arch armv8.7-a\\n\\twfit %0\" : : \"r\" (reg) : \"memory\")\n>> +#define wfet(reg) \\\n>> +\tasm volatile(\".arch armv8.7-a\\n\\twfet %0\" : : \"r\" (reg) : \"memory\")\n>> +\n>> +static void timer_handler(struct pt_regs *regs)\n>> +{\n>> +\t/* Disable timer to stop IRQ from re-firing */\n>> +\twrite_sysreg(0, cntv_ctl_el0);\n>> +}\n>> +\n>> +static bool check_elapsed(uint64_t start, uint64_t threshold, const char *test, bool more)\n>> +{\n>> +\tuint64_t end = read_sysreg(cntvct_el0);\n>> +\tuint64_t elapsed = end - start;\n>> +\tbool pass = more ? elapsed >= threshold : elapsed <= threshold;\n>> +\n>> +\treport(pass, \"%s (%ld ticks)\", test, elapsed);\n>> +\n>> +\tif (!pass) {\n>> +\t\treport_info(\"%s %s\", test, more ? \"woke too early\" : \"slept despite SEV\");\n>> +\t}\n>> +\treturn pass;\n>> +}\n>> +\n>> +static void test_wfi(void)\n>> +{\n>> +\tuint64_t start;\n>> +\n>> +\treport_info(\"Testing WFI...\");\n>> +\n>> +\tstart = read_sysreg(cntvct_el0);\n>> +\twrite_sysreg(TIMEOUT, cntv_tval_el0);\n>> +\twrite_sysreg(1, cntv_ctl_el0); /* Enable timer, no mask */\n>> +\tisb();\n>> +\n>> +\tlocal_irq_enable();\n>> +\twfi();\n>> +\tlocal_irq_disable();\n>> +\n>> +\tcheck_elapsed(start, TIMEOUT, \"WFI\", true);\n>> +}\n>> +\n>> +static void test_wfe(void)\n>> +{\n>> +\tuint64_t start;\n>> +\n>\n> I think a comment here would be good, just to say it's testing that a wfe\n> doesn't sleep for a 'long' period with no pending events, or something like\n> that?\n\nok\n\n>\n>> +\treport_info(\"Testing WFE/SEV...\");\n>> +\tsev();\n>> +\tstart = read_sysreg(cntvct_el0);\n>> +\twfe();\n>> +\tcheck_elapsed(start, TIMEOUT, \"WFE/SEV\", false);\n>> +\n>> +\treport_info(\"Testing WFE/SEVL...\");\n>> +\tsevl();\n>> +\tstart = read_sysreg(cntvct_el0);\n>> +\twfe();\n>> +\tcheck_elapsed(start, TIMEOUT, \"WFE/SEVL\", false);\n>> +}\n>> +\n>> +static void test_wfit(void)\n>> +{\n>> +\tuint64_t start, timeout;\n>> +\n>> +\treport_info(\"Testing WFIT...\");\n>> +\tstart = read_sysreg(cntvct_el0);\n>> +\ttimeout = start + TIMEOUT;\n>> +\twfit(timeout);\n>> +\tcheck_elapsed(start, TIMEOUT, \"WFIT\", true);\n>> +}\n>> +\n>> +static void test_wfet(void)\n>> +{\n>> +\tuint64_t start, timeout;\n>> +\n>> +\treport_info(\"Testing WFET...\");\n>> +\t/* Ensure no pending events */\n>> +\tsev();\n>\n> Could this just be sevl here? Not that it really matters.\n\nit could be - ideally I would extend the test case to work with -smp so\nwe can properly exercise that code path as well.\n\n>\n>> +\twfe();\n>> +\n>> +\tstart = read_sysreg(cntvct_el0);\n>> +\ttimeout = start + TIMEOUT;\n>> +\twfet(timeout);\n>> +\tcheck_elapsed(start, TIMEOUT, \"WFET\", true);\n>> +}\n>> +\n>> +int main(void)\n>> +{\n>> +\n>> +\tif (gic_init() < 0) {\n>> +\t\treport_abort(\"GIC init failed\");\n>> +\t\treturn 1;\n>> +\t}\n>> +\n>> +\t/* Install timer handler for WFI wake-up */\n>> +\tinstall_irq_handler(EL1H_IRQ, timer_handler);\n>> +\tgic_enable_defaults();\n>> +\n>> +\t/* Enable Virtual Timer PPI */\n>> +\tgic_irq_set_clr_enable(27, true);\n>\n> Instead of hardcoding 27 here, you can use:\n>\n> \tu32 irq = current_level() == CurrentEL_EL1 ? TIMER_VTIMER_IRQ : TIMER_HVTIMER_IRQ;                                                                     \n> \tgic_irq_set_clr_enable(irq, true);\n>\n> Which also allows the test to run at EL2.\n\nsounds good.\n\n>\n>> +\n>> +\treport_prefix_push(\"WFx\");\n>> +\ttest_wfi();\n>> +\ttest_wfe();\n>> +\treport_prefix_pop();\n>> +\n>> +\tif (system_supports_wfxt()) {\n>> +\t\treport_prefix_push(\"WFxT\");\n>> +\t\ttest_wfit();\n>> +\t\ttest_wfet();\n>> +\t} else {\n>> +\t\treport_skip(\"WFxT instructions not supported\");\n>> +\t}\n>> +\n>> +\treturn report_summary();\n>> +}\n>> diff --git a/arm/unittests.cfg b/arm/unittests.cfg\n>> index 12fc4468..7adf96f2 100644\n>> --- a/arm/unittests.cfg\n>> +++ b/arm/unittests.cfg\n>> @@ -339,3 +339,8 @@ groups = mte\n>>  test_args = asymm\n>>  qemu_params = -machine mte=on\n>>  arch = arm64\n>> +\n>> +[wfx]\n>> +file = wfx.flat\n>> +groups = wfx\n>> +arch = arm64\n>\n> Thanks,\n> Joey","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=KviAAGiA;\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=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from lists1p.gnu.org (lists1p.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 4g4k7Q4Xdzz1yJH\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 29 Apr 2026 00:57:37 +1000 (AEST)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wHjrr-0008Gb-QR; Tue, 28 Apr 2026 10:56:56 -0400","from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <alex.bennee@linaro.org>)\n id 1wHjre-0008Ez-NL\n for qemu-devel@nongnu.org; Tue, 28 Apr 2026 10:56:45 -0400","from mail-wm1-x32e.google.com ([2a00:1450:4864:20::32e])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <alex.bennee@linaro.org>)\n id 1wHjra-0004zW-LX\n for qemu-devel@nongnu.org; Tue, 28 Apr 2026 10:56:40 -0400","by mail-wm1-x32e.google.com with SMTP id\n 5b1f17b1804b1-4891d7164ddso58881185e9.3\n for <qemu-devel@nongnu.org>; Tue, 28 Apr 2026 07:56:37 -0700 (PDT)","from draig.lan ([185.124.0.195]) by smtp.gmail.com with ESMTPSA id\n 5b1f17b1804b1-48a774c3ddfsm47637275e9.2.2026.04.28.07.56.34\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 28 Apr 2026 07:56:34 -0700 (PDT)","from draig (localhost [IPv6:::1])\n by draig.lan (Postfix) with ESMTP id 8317F5F7BC;\n Tue, 28 Apr 2026 15:56:33 +0100 (BST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=linaro.org; s=google; t=1777388195; x=1777992995; darn=nongnu.org;\n h=content-transfer-encoding:mime-version:message-id:date:user-agent\n :references:in-reply-to:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=FZI5euwIVJ9QjGGXPpUqegNn9IsxNW5sxSo5xHMvQY0=;\n b=KviAAGiAo3AEztu57FBIs5/I1SMg7xjAeXVHHw5w3Z/1sP7RjygaZRnOugXjtZD5cg\n 1yaQR9HNct4OiZ6VqGB9PukcR1dOdZUQd7p9E7mpOOluA78nUrlaAg2GXTJYyvGDx02b\n FluaR5r4Kp6n2mvlZzAtEBxRHXmDLKkWbk1KVTdzzeoVfIFLigevy6gH97yebKqOHhgc\n gvb1c2ddWNfki3yTwonpczJApKRkf7sbVB08UIGcdI1Q7ISfCsEJXr2S+ToNgpBruVPf\n jIdWxwgWsFzkZg5kT9jgt6ggB96eW4S72SG4r62JU9qWUVHB32dL3gawf1YW94vLLNwE\n SCWg==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777388195; x=1777992995;\n h=content-transfer-encoding:mime-version:message-id:date:user-agent\n :references:in-reply-to:subject:cc:to:from:x-gm-gg\n :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n bh=FZI5euwIVJ9QjGGXPpUqegNn9IsxNW5sxSo5xHMvQY0=;\n b=imlDa/3tDsHGkFXyEZZl6KAuR0pzb+P3NxnGjUoeOTXP8fapE+RmiU8bRUSOdmjhpj\n syPgQAt+heuY+cRzVesAVr0tx5rSvdDciOQyAvB+E6krV4yj5yIsnarlnTGtpsS039zs\n 1SYP84nzDfLFkARmz3HZx+V3hhxpETrncb00OuQM57hmX4IU9gAxG4H789TL0Osq3Y7y\n Q7cqT0ZsnJ1jfMVWHvVxg4tl5DbNfrwuaKzXZ0pgqagTXamb60WJM8F5XveYR5NS8N7S\n lD4cFhnQa/y+Q5HCmc+t5SmKo6BaBWylpUuPINsGCgf+zAI40YjcXZpNjYliTfeiaaF8\n PCmQ==","X-Gm-Message-State":"AOJu0YyYxNMMf4qQ0DwALbGrQSShIeVD1tSXJ8FBqoIF2t+TGoFLtucH\n mXNxc16ZEP2K7q7MXirQjPGkUQhtcG0qY5VvGSnDvDNuegHRfIkQnBFWSMDyyNTwabA=","X-Gm-Gg":"AeBDievxTy9mnl8Rz/myjMUv7wvPuvshaTfZE70mMR8/pb0kP+CusxCo5g6MqE+j7cH\n Lmz1z6X5C5HmYqMFbL4iGuwyfq+Lm5CvgmpROBNOhnk6/zA2+0rsgz/naHnDf/OyWTbOdzHUVOE\n vwjV+RtsbbWPiVJLeB3XdZGwcbIKYuPsoXcDVhZcjG40EpjKu7qdV80En5/TQOJ2UnI6cYufi41\n 2JC9WIWmvTvypWNgITg8GWzlNVuSmHh8ROHPNrTjeoC9LqVUxIarwwi3U/euSbkMoVknuG9Pxei\n n91Qn0xOtOtXbwbG2eNTROIoKOjwRRrZ5EGXXtPTJyLeBrbfKrJsSkYvXmL8BtNVyI/2+2jBhN3\n 7ITAY5h78EFQOPknCCy7KTbLSxI4CfrJZBBBzXI7ObXYsxVnZpMX6xsrc7y+JjCLNqwTyHjkWv9\n aFVVSk5Drhm9hkj+sNBv1Y5Ld3pOzX12B6lg==","X-Received":"by 2002:a05:600c:3f14:b0:488:af7f:775f with SMTP id\n 5b1f17b1804b1-48a7b535a0dmr61415e9.18.1777388195308;\n Tue, 28 Apr 2026 07:56:35 -0700 (PDT)","From":"=?utf-8?q?Alex_Benn=C3=A9e?= <alex.bennee@linaro.org>","To":"Joey Gouly <joey.gouly@arm.com>","Cc":"qemu-devel@nongnu.org,  Andrew Jones <andrew.jones@linux.dev>,\n Alexandru Elisei <alexandru.elisei@arm.com>,  Eric Auger\n <eric.auger@redhat.com>,  \"open list:ARM\" <kvmarm@lists.linux.dev>,  \"open\n list:Default mailing list\" <kvm@vger.kernel.org>","Subject":"Re: [kvm-unit-tests PATCH] arm: add wfx test case","In-Reply-To":"<20260428132657.GA591628@e124191.cambridge.arm.com> (Joey Gouly's\n message of \"Tue, 28 Apr 2026 14:26:57 +0100\")","References":"<20260427130045.3669851-1-alex.bennee@linaro.org>\n <20260428132657.GA591628@e124191.cambridge.arm.com>","User-Agent":"mu4e 1.14.1-pre3; emacs 30.1","Date":"Tue, 28 Apr 2026 15:56:33 +0100","Message-ID":"<87h5ovdtge.fsf@draig.linaro.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Transfer-Encoding":"quoted-printable","Received-SPF":"pass client-ip=2a00:1450:4864:20::32e;\n envelope-from=alex.bennee@linaro.org; helo=mail-wm1-x32e.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=ham 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"}},{"id":3685125,"web_url":"http://patchwork.ozlabs.org/comment/3685125/","msgid":"<afSnVJLe7HrB6ISS@raptor>","list_archive_url":null,"date":"2026-05-01T13:15:14","subject":"Re: [kvm-unit-tests PATCH] arm: add wfx test case","submitter":{"id":75988,"url":"http://patchwork.ozlabs.org/api/people/75988/","name":"Alexandru Elisei","email":"alexandru.elisei@arm.com"},"content":"Hi Alex,\n\nOn Mon, Apr 27, 2026 at 02:00:45PM +0100, Alex Bennée wrote:\n> This is based on a similar test case I wrote for QEMU's tcg tests although\n> obviously able to take advantage of kvm-unit-tests additional plumbing for\n> dealing with the GIC and IRQs.\n> \n> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>\n> ---\n>  arm/Makefile.arm64        |   1 +\n>  lib/arm64/asm/processor.h |   7 ++\n>  lib/arm64/asm/sysreg.h    |   3 +\n>  arm/wfx.c                 | 137 ++++++++++++++++++++++++++++++++++++++\n>  arm/unittests.cfg         |   5 ++\n>  5 files changed, 153 insertions(+)\n>  create mode 100644 arm/wfx.c\n> \n> diff --git a/arm/Makefile.arm64 b/arm/Makefile.arm64\n> index a40c830d..52b3f35d 100644\n> --- a/arm/Makefile.arm64\n> +++ b/arm/Makefile.arm64\n> @@ -64,6 +64,7 @@ tests += $(TEST_DIR)/cache.$(exe)\n>  tests += $(TEST_DIR)/debug.$(exe)\n>  tests += $(TEST_DIR)/fpu.$(exe)\n>  tests += $(TEST_DIR)/mte.$(exe)\n> +tests += $(TEST_DIR)/wfx.$(exe)\n>  \n>  include $(SRCDIR)/$(TEST_DIR)/Makefile.common\n>  \n> diff --git a/lib/arm64/asm/processor.h b/lib/arm64/asm/processor.h\n> index 32ddc1b3..2104036d 100644\n> --- a/lib/arm64/asm/processor.h\n> +++ b/lib/arm64/asm/processor.h\n> @@ -173,5 +173,12 @@ static inline bool system_supports_rndr(void)\n>  \treturn ((id_aa64isar0_el1 >> ID_AA64ISAR0_EL1_RNDR_SHIFT) & 0xf) != 0;\n>  }\n>  \n> +static inline bool system_supports_wfxt(void)\n> +{\n> +\tu64 id_aa64isar2_el1 = read_sysreg_s(ID_AA64ISAR2_EL1);\n> +\n> +\treturn ((id_aa64isar2_el1 >> ID_AA64ISAR2_EL1_WFxT_SHIFT) & 0xf) != 0;\n> +}\n> +\n>  #endif /* !__ASSEMBLER__ */\n>  #endif /* _ASMARM64_PROCESSOR_H_ */\n> diff --git a/lib/arm64/asm/sysreg.h b/lib/arm64/asm/sysreg.h\n> index f2d05018..cb96a649 100644\n> --- a/lib/arm64/asm/sysreg.h\n> +++ b/lib/arm64/asm/sysreg.h\n> @@ -77,6 +77,9 @@ asm(\n>  #define ID_AA64ISAR0_EL1_RNDR_SHIFT\t60\n>  #define ID_AA64PFR1_EL1_MTE_SHIFT\t8\n>  \n> +#define ID_AA64ISAR2_EL1\t\tsys_reg(3, 0, 0, 6, 2)\n> +#define ID_AA64ISAR2_EL1_WFxT_SHIFT\t0\n> +\n>  #define ID_AA64MMFR0_EL1_FGT_SHIFT\t56\n>  #define ID_AA64MMFR0_EL1_FGT_FGT2\t0x2\n>  \n> diff --git a/arm/wfx.c b/arm/wfx.c\n> new file mode 100644\n> index 00000000..912e50e6\n> --- /dev/null\n> +++ b/arm/wfx.c\n> @@ -0,0 +1,137 @@\n> +/*\n> + * WFX Instructions Test (WFI, WFE, WFIT, WFET)\n> + *\n> + * Copyright (c) 2026 Linaro Ltd\n> + *\n> + * SPDX-License-Identifier: GPL-2.0-or-later\n> + */\n> +\n> +#include <libcflat.h>\n> +#include <asm/processor.h>\n> +#include <asm/gic.h>\n> +#include <asm/timer.h>\n> +#include <asm/io.h>\n> +\n> +#define TIMEOUT 200000\n> +\n> +#define sev() asm volatile(\"sev\" : : : \"memory\")\n> +#define sevl() asm volatile(\"sevl\" : : : \"memory\")\n> +#define wfi() asm volatile(\"wfi\" : : : \"memory\")\n> +#define wfe() asm volatile(\"wfe\" : : : \"memory\")\n> +\n> +#define wfit(reg) \\\n> +\tasm volatile(\".arch armv8.7-a\\n\\twfit %0\" : : \"r\" (reg) : \"memory\")\n> +#define wfet(reg) \\\n> +\tasm volatile(\".arch armv8.7-a\\n\\twfet %0\" : : \"r\" (reg) : \"memory\")\n> +\n> +static void timer_handler(struct pt_regs *regs)\n> +{\n> +\t/* Disable timer to stop IRQ from re-firing */\n> +\twrite_sysreg(0, cntv_ctl_el0);\n> +}\n\nIt is customary for the interrupt handler to ack the interrupt at the GIC level.\n\n> +\n> +static bool check_elapsed(uint64_t start, uint64_t threshold, const char *test, bool more)\n> +{\n> +\tuint64_t end = read_sysreg(cntvct_el0);\n> +\tuint64_t elapsed = end - start;\n> +\tbool pass = more ? elapsed >= threshold : elapsed <= threshold;\n> +\n> +\treport(pass, \"%s (%ld ticks)\", test, elapsed);\n> +\n> +\tif (!pass) {\n> +\t\treport_info(\"%s %s\", test, more ? \"woke too early\" : \"slept despite SEV\");\n> +\t}\n> +\treturn pass;\n> +}\n> +\n> +static void test_wfi(void)\n> +{\n> +\tuint64_t start;\n> +\n> +\treport_info(\"Testing WFI...\");\n> +\n> +\tstart = read_sysreg(cntvct_el0);\n> +\twrite_sysreg(TIMEOUT, cntv_tval_el0);\n> +\twrite_sysreg(1, cntv_ctl_el0); /* Enable timer, no mask */\n> +\tisb();\n> +\n> +\tlocal_irq_enable();\n> +\twfi();\n\nConsider this scenario:\n\n\tlocal_irq_enable();\n\t// CPU takes the interrupt, handles it and returns.\n\twfi(); <- CPU now waits forever for an interrupt that will never come\n\nThe proper way to do it on baremetal would be:\n\n\tlocal_irq_disable();\n\t// Program timer to fire\n\twfi();\n\t// Timer fires, GIC asserts the interrupt, WFI completes\n\tlocal_irq_enable();\n\t// CPU handles the interrupt\n\tcheck_elapsed(..)\n\nBut this is not baremetal. KVM can decide not to trap WFI (look at\narch/arm64/kvm/arm.c::kvm_arch_vcpu_load() -> kvm_vpcu_should_clear_twi()). In\nthat case, the WFI might complete due a host interrupt, and check_elapsed() will\nfail because the timer hasn't yet fired.\n\n> +\tlocal_irq_disable();\n> +\n> +\tcheck_elapsed(start, TIMEOUT, \"WFI\", true);\n> +}\n> +\n> +static void test_wfe(void)\n> +{\n> +\tuint64_t start;\n> +\n> +\treport_info(\"Testing WFE/SEV...\");\n> +\tsev();\n> +\tstart = read_sysreg(cntvct_el0);\n> +\twfe();\n> +\tcheck_elapsed(start, TIMEOUT, \"WFE/SEV\", false);\n> +\n> +\treport_info(\"Testing WFE/SEVL...\");\n> +\tsevl();\n> +\tstart = read_sysreg(cntvct_el0);\n> +\twfe();\n> +\tcheck_elapsed(start, TIMEOUT, \"WFE/SEVL\", false);\n> +}\n\nI haven't thought about this too much, but it looks to me like the same\nsituation with WFI can happen with WFE\n\nAlso, kvm-unit-tests() makes use of WFE and SEV for multithreading, and the fact\nthat multithreaded tests work at all might be taken as proof enough that the two\ninstructions are correctly implemented.\n\nThanks,\nAlex\n\n> +\n> +static void test_wfit(void)\n> +{\n> +\tuint64_t start, timeout;\n> +\n> +\treport_info(\"Testing WFIT...\");\n> +\tstart = read_sysreg(cntvct_el0);\n> +\ttimeout = start + TIMEOUT;\n> +\twfit(timeout);\n> +\tcheck_elapsed(start, TIMEOUT, \"WFIT\", true);\n> +}\n> +\n> +static void test_wfet(void)\n> +{\n> +\tuint64_t start, timeout;\n> +\n> +\treport_info(\"Testing WFET...\");\n> +\t/* Ensure no pending events */\n> +\tsev();\n> +\twfe();\n> +\n> +\tstart = read_sysreg(cntvct_el0);\n> +\ttimeout = start + TIMEOUT;\n> +\twfet(timeout);\n> +\tcheck_elapsed(start, TIMEOUT, \"WFET\", true);\n> +}\n> +\n> +int main(void)\n> +{\n> +\n> +\tif (gic_init() < 0) {\n> +\t\treport_abort(\"GIC init failed\");\n> +\t\treturn 1;\n> +\t}\n> +\n> +\t/* Install timer handler for WFI wake-up */\n> +\tinstall_irq_handler(EL1H_IRQ, timer_handler);\n> +\tgic_enable_defaults();\n> +\n> +\t/* Enable Virtual Timer PPI */\n> +\tgic_irq_set_clr_enable(27, true);\n> +\n> +\treport_prefix_push(\"WFx\");\n> +\ttest_wfi();\n> +\ttest_wfe();\n> +\treport_prefix_pop();\n> +\n> +\tif (system_supports_wfxt()) {\n> +\t\treport_prefix_push(\"WFxT\");\n> +\t\ttest_wfit();\n> +\t\ttest_wfet();\n> +\t} else {\n> +\t\treport_skip(\"WFxT instructions not supported\");\n> +\t}\n> +\n> +\treturn report_summary();\n> +}\n> diff --git a/arm/unittests.cfg b/arm/unittests.cfg\n> index 12fc4468..7adf96f2 100644\n> --- a/arm/unittests.cfg\n> +++ b/arm/unittests.cfg\n> @@ -339,3 +339,8 @@ groups = mte\n>  test_args = asymm\n>  qemu_params = -machine mte=on\n>  arch = arm64\n> +\n> +[wfx]\n> +file = wfx.flat\n> +groups = wfx\n> +arch = arm64\n> -- \n> 2.47.3\n>","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=fail reason=\"signature verification failed\" (1024-bit key;\n unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256\n header.s=foss header.b=X0qfOId7;\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=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from lists1p.gnu.org (lists1p.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 4g6Wl4195qz1y04\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 01 May 2026 23:16:14 +1000 (AEST)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wIniQ-0001r2-CK; Fri, 01 May 2026 09:15:34 -0400","from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <alexandru.elisei@arm.com>)\n id 1wIniO-0001qX-Bt\n for qemu-devel@nongnu.org; Fri, 01 May 2026 09:15:32 -0400","from foss.arm.com ([217.140.110.172])\n by eggs.gnu.org with esmtp (Exim 4.90_1)\n (envelope-from <alexandru.elisei@arm.com>) id 1wIniM-0006vm-4g\n for qemu-devel@nongnu.org; Fri, 01 May 2026 09:15:32 -0400","from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14])\n by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 68229176A;\n Fri,  1 May 2026 06:15:21 -0700 (PDT)","from raptor (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19])\n by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id AC1E83F62B;\n Fri,  1 May 2026 06:15:25 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss;\n t=1777641326; bh=rtObenOdQ8wqhsp4Fy1heo+C47dsP6ZRiDQgq9YzCbc=;\n h=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n b=X0qfOId7Bi5ntpNSoWqPYR5zTb26315+ZlOu3XYlWZKlzACsSssvI/WEmYbJtg2ta\n DVX3+c4G0IOwtOZ0EXqgEQqb9mSrDxvxteyvXD3TlJg4sdRP2j8VMSPBMJ2lNPv9PS\n /mQWZHYkqYnC+0xEEtP8eUh0+1yI/Mbfyy7KLzTE=","Date":"Fri, 1 May 2026 14:15:14 +0100","From":"Alexandru Elisei <alexandru.elisei@arm.com>","To":"Alex =?utf-8?q?Benn=C3=A9e?= <alex.bennee@linaro.org>","Cc":"qemu-devel@nongnu.org, Andrew Jones <andrew.jones@linux.dev>,\n Eric Auger <eric.auger@redhat.com>,\n \"open list:ARM\" <kvmarm@lists.linux.dev>,\n \"open list:Default mailing list\" <kvm@vger.kernel.org>","Subject":"Re: [kvm-unit-tests PATCH] arm: add wfx test case","Message-ID":"<afSnVJLe7HrB6ISS@raptor>","References":"<20260427130045.3669851-1-alex.bennee@linaro.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20260427130045.3669851-1-alex.bennee@linaro.org>","Received-SPF":"pass client-ip=217.140.110.172;\n envelope-from=alexandru.elisei@arm.com; helo=foss.arm.com","X-Spam_score_int":"-43","X-Spam_score":"-4.4","X-Spam_bar":"----","X-Spam_report":"(-4.4 / 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_MED=-2.3, SPF_HELO_PASS=-0.001,\n SPF_PASS=-0.001 autolearn=ham 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"}},{"id":3685139,"web_url":"http://patchwork.ozlabs.org/comment/3685139/","msgid":"<87zf2jcisg.fsf@draig.linaro.org>","list_archive_url":null,"date":"2026-05-01T14:21:19","subject":"Re: [kvm-unit-tests PATCH] arm: add wfx test case","submitter":{"id":39532,"url":"http://patchwork.ozlabs.org/api/people/39532/","name":"Alex Bennée","email":"alex.bennee@linaro.org"},"content":"Alexandru Elisei <alexandru.elisei@arm.com> writes:\n\n> Hi Alex,\n>\n> On Mon, Apr 27, 2026 at 02:00:45PM +0100, Alex Bennée wrote:\n>> This is based on a similar test case I wrote for QEMU's tcg tests although\n>> obviously able to take advantage of kvm-unit-tests additional plumbing for\n>> dealing with the GIC and IRQs.\n>> \n>> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>\n>> ---\n>>  arm/Makefile.arm64        |   1 +\n>>  lib/arm64/asm/processor.h |   7 ++\n>>  lib/arm64/asm/sysreg.h    |   3 +\n>>  arm/wfx.c                 | 137 ++++++++++++++++++++++++++++++++++++++\n>>  arm/unittests.cfg         |   5 ++\n>>  5 files changed, 153 insertions(+)\n>>  create mode 100644 arm/wfx.c\n>> \n>> diff --git a/arm/Makefile.arm64 b/arm/Makefile.arm64\n>> index a40c830d..52b3f35d 100644\n>> --- a/arm/Makefile.arm64\n>> +++ b/arm/Makefile.arm64\n>> @@ -64,6 +64,7 @@ tests += $(TEST_DIR)/cache.$(exe)\n>>  tests += $(TEST_DIR)/debug.$(exe)\n>>  tests += $(TEST_DIR)/fpu.$(exe)\n>>  tests += $(TEST_DIR)/mte.$(exe)\n>> +tests += $(TEST_DIR)/wfx.$(exe)\n>>  \n>>  include $(SRCDIR)/$(TEST_DIR)/Makefile.common\n>>  \n>> diff --git a/lib/arm64/asm/processor.h b/lib/arm64/asm/processor.h\n>> index 32ddc1b3..2104036d 100644\n>> --- a/lib/arm64/asm/processor.h\n>> +++ b/lib/arm64/asm/processor.h\n>> @@ -173,5 +173,12 @@ static inline bool system_supports_rndr(void)\n>>  \treturn ((id_aa64isar0_el1 >> ID_AA64ISAR0_EL1_RNDR_SHIFT) & 0xf) != 0;\n>>  }\n>>  \n>> +static inline bool system_supports_wfxt(void)\n>> +{\n>> +\tu64 id_aa64isar2_el1 = read_sysreg_s(ID_AA64ISAR2_EL1);\n>> +\n>> +\treturn ((id_aa64isar2_el1 >> ID_AA64ISAR2_EL1_WFxT_SHIFT) & 0xf) != 0;\n>> +}\n>> +\n>>  #endif /* !__ASSEMBLER__ */\n>>  #endif /* _ASMARM64_PROCESSOR_H_ */\n>> diff --git a/lib/arm64/asm/sysreg.h b/lib/arm64/asm/sysreg.h\n>> index f2d05018..cb96a649 100644\n>> --- a/lib/arm64/asm/sysreg.h\n>> +++ b/lib/arm64/asm/sysreg.h\n>> @@ -77,6 +77,9 @@ asm(\n>>  #define ID_AA64ISAR0_EL1_RNDR_SHIFT\t60\n>>  #define ID_AA64PFR1_EL1_MTE_SHIFT\t8\n>>  \n>> +#define ID_AA64ISAR2_EL1\t\tsys_reg(3, 0, 0, 6, 2)\n>> +#define ID_AA64ISAR2_EL1_WFxT_SHIFT\t0\n>> +\n>>  #define ID_AA64MMFR0_EL1_FGT_SHIFT\t56\n>>  #define ID_AA64MMFR0_EL1_FGT_FGT2\t0x2\n>>  \n>> diff --git a/arm/wfx.c b/arm/wfx.c\n>> new file mode 100644\n>> index 00000000..912e50e6\n>> --- /dev/null\n>> +++ b/arm/wfx.c\n>> @@ -0,0 +1,137 @@\n>> +/*\n>> + * WFX Instructions Test (WFI, WFE, WFIT, WFET)\n>> + *\n>> + * Copyright (c) 2026 Linaro Ltd\n>> + *\n>> + * SPDX-License-Identifier: GPL-2.0-or-later\n>> + */\n>> +\n>> +#include <libcflat.h>\n>> +#include <asm/processor.h>\n>> +#include <asm/gic.h>\n>> +#include <asm/timer.h>\n>> +#include <asm/io.h>\n>> +\n>> +#define TIMEOUT 200000\n>> +\n>> +#define sev() asm volatile(\"sev\" : : : \"memory\")\n>> +#define sevl() asm volatile(\"sevl\" : : : \"memory\")\n>> +#define wfi() asm volatile(\"wfi\" : : : \"memory\")\n>> +#define wfe() asm volatile(\"wfe\" : : : \"memory\")\n>> +\n>> +#define wfit(reg) \\\n>> +\tasm volatile(\".arch armv8.7-a\\n\\twfit %0\" : : \"r\" (reg) : \"memory\")\n>> +#define wfet(reg) \\\n>> +\tasm volatile(\".arch armv8.7-a\\n\\twfet %0\" : : \"r\" (reg) : \"memory\")\n>> +\n>> +static void timer_handler(struct pt_regs *regs)\n>> +{\n>> +\t/* Disable timer to stop IRQ from re-firing */\n>> +\twrite_sysreg(0, cntv_ctl_el0);\n>> +}\n>\n> It is customary for the interrupt handler to ack the interrupt at the GIC level.\n>\n>> +\n>> +static bool check_elapsed(uint64_t start, uint64_t threshold, const char *test, bool more)\n>> +{\n>> +\tuint64_t end = read_sysreg(cntvct_el0);\n>> +\tuint64_t elapsed = end - start;\n>> +\tbool pass = more ? elapsed >= threshold : elapsed <= threshold;\n>> +\n>> +\treport(pass, \"%s (%ld ticks)\", test, elapsed);\n>> +\n>> +\tif (!pass) {\n>> +\t\treport_info(\"%s %s\", test, more ? \"woke too early\" : \"slept despite SEV\");\n>> +\t}\n>> +\treturn pass;\n>> +}\n>> +\n>> +static void test_wfi(void)\n>> +{\n>> +\tuint64_t start;\n>> +\n>> +\treport_info(\"Testing WFI...\");\n>> +\n>> +\tstart = read_sysreg(cntvct_el0);\n>> +\twrite_sysreg(TIMEOUT, cntv_tval_el0);\n>> +\twrite_sysreg(1, cntv_ctl_el0); /* Enable timer, no mask */\n>> +\tisb();\n>> +\n>> +\tlocal_irq_enable();\n>> +\twfi();\n>\n> Consider this scenario:\n>\n> \tlocal_irq_enable();\n> \t// CPU takes the interrupt, handles it and returns.\n> \twfi(); <- CPU now waits forever for an interrupt that will never come\n>\n> The proper way to do it on baremetal would be:\n>\n> \tlocal_irq_disable();\n> \t// Program timer to fire\n> \twfi();\n> \t// Timer fires, GIC asserts the interrupt, WFI completes\n> \tlocal_irq_enable();\n> \t// CPU handles the interrupt\n> \tcheck_elapsed(..)\n>\n> But this is not baremetal. KVM can decide not to trap WFI (look at\n> arch/arm64/kvm/arm.c::kvm_arch_vcpu_load() -> kvm_vpcu_should_clear_twi()). In\n> that case, the WFI might complete due a host interrupt, and check_elapsed() will\n> fail because the timer hasn't yet fired.\n>\n>> +\tlocal_irq_disable();\n>> +\n>> +\tcheck_elapsed(start, TIMEOUT, \"WFI\", true);\n>> +}\n>> +\n>> +static void test_wfe(void)\n>> +{\n>> +\tuint64_t start;\n>> +\n>> +\treport_info(\"Testing WFE/SEV...\");\n>> +\tsev();\n>> +\tstart = read_sysreg(cntvct_el0);\n>> +\twfe();\n>> +\tcheck_elapsed(start, TIMEOUT, \"WFE/SEV\", false);\n>> +\n>> +\treport_info(\"Testing WFE/SEVL...\");\n>> +\tsevl();\n>> +\tstart = read_sysreg(cntvct_el0);\n>> +\twfe();\n>> +\tcheck_elapsed(start, TIMEOUT, \"WFE/SEVL\", false);\n>> +}\n>\n> I haven't thought about this too much, but it looks to me like the same\n> situation with WFI can happen with WFE\n>\n> Also, kvm-unit-tests() makes use of WFE and SEV for multithreading, and the fact\n> that multithreaded tests work at all might be taken as proof enough that the two\n> instructions are correctly implemented.\n\nSo I'm using kvm-unit-test to exercise QEMU's TCG modelling of the\ninstructions, see:\n\n  Message-ID: <20260430104434.1482407-1-alex.bennee@linaro.org>\n  Date: Thu, 30 Apr 2026 11:44:27 +0100\n  Subject: [PATCH v4 0/7] target/arm: fully model WFxT instructions for A-profile\n\nSo while I'm confident the current modelling doesn't cause issues\n(because we basically treat it as a NOP) I wanted to check the various\nmodes behave as they should with the above patches.\n\nI can limit the test to TCG only if it is likely to fail under KVM.","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=tE4HVR6T;\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=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from lists1p.gnu.org (lists1p.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 4g6YC85z96z1y04\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 02 May 2026 00:22:11 +1000 (AEST)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wIokB-00082q-2e; Fri, 01 May 2026 10:21:27 -0400","from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <alex.bennee@linaro.org>)\n id 1wIokA-00082b-5f\n for qemu-devel@nongnu.org; Fri, 01 May 2026 10:21:26 -0400","from mail-wr1-x433.google.com ([2a00:1450:4864:20::433])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <alex.bennee@linaro.org>)\n id 1wIok7-0007Zs-N6\n for qemu-devel@nongnu.org; Fri, 01 May 2026 10:21:25 -0400","by mail-wr1-x433.google.com with SMTP id\n ffacd0b85a97d-43d7e23defbso1127057f8f.0\n for <qemu-devel@nongnu.org>; Fri, 01 May 2026 07:21:23 -0700 (PDT)","from draig.lan ([185.124.0.195]) by smtp.gmail.com with ESMTPSA id\n ffacd0b85a97d-44a986aa3a5sm5802041f8f.26.2026.05.01.07.21.20\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Fri, 01 May 2026 07:21:20 -0700 (PDT)","from draig (localhost [IPv6:::1])\n by draig.lan (Postfix) with ESMTP id 8A2A75F8FC;\n Fri, 01 May 2026 15:21:19 +0100 (BST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=linaro.org; s=google; t=1777645281; x=1778250081; darn=nongnu.org;\n h=content-transfer-encoding:mime-version:message-id:date:user-agent\n :references:in-reply-to:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=DBnnGCpYSonyRl/RZZsL4XC/Tyffyj/BGojejPAjpWk=;\n b=tE4HVR6TNGPD8f5NHWuAuCL2G2+tsQBmjjZNKngmWSOtItUVomdgmIgmcYpopky2Hz\n WD2QvJgSXhAs2Htf3slxJdMNBsF9PX+vflMrpNPzYkHiwmrTNEZaUcVkaTYSw1Jzcflf\n awNs/VMabxqkcjqhbmYAv/VzJWJdTgXWXAfQr7bm5Z9D/QPWoYXzwfSprcEJZRhr4ZKD\n mIepw9fETTaghkDgDpkknu31YTH9WHojP8wgRt3hlG5svWK9NvBlyI5QGSw0wJz91AUt\n Q/ON4ixb8bYJhPVu78/IURPc5h2xujBw39vFqR3C7xPTSoZMDpa2E7LE9Hetvb3uc9x9\n zKWQ==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777645281; x=1778250081;\n h=content-transfer-encoding:mime-version:message-id:date:user-agent\n :references:in-reply-to:subject:cc:to:from:x-gm-gg\n :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n bh=DBnnGCpYSonyRl/RZZsL4XC/Tyffyj/BGojejPAjpWk=;\n b=ZkWs1apVgJMhBq7c9eRW5pzj7BCCiprPrGT+9bRIMS1aNDngfVBCFrGJ/rhum+zoPG\n BCM+i33LcMWaYkKTEk84SwjqWxpxriSWWYPiKb/v0GAZtl7BlIvy70Sj96zlc5rY9epa\n buBZuFbNTLxb3p+FI0yAuaMoSiu5qvBZ+kFsBfsVZii+aS0Ei60bd0X7yXQ3NuoDHWRB\n yrnMBNi6pwLWc66Nu0Jj6ERsnSWtu4t1CAj4xOOtfXbXe+WRTAyhGUT0KEVGd2wgBAsq\n AV3ZXIM/xE0JdpeM2RZ5X7mMgGWBbEzzSUfH4j3PiaSWeqAVqPdyECACHNWaXZJKU9Ew\n 9qOw==","X-Gm-Message-State":"AOJu0YzmXlvZ1Hdht57o/K48Ps9rYqrjiTXS2f++7W0PHkPZTSdZnCqz\n K7xG50jlymPq6iSoWuNHp3U/MAsSbCNvQhKRkhscXPN+ixPQdAWWPAILpOlFtWF4acY=","X-Gm-Gg":"AeBDiest/cht+0alejtwTIsllKHFpNfirPoK3YMG5orp3FWK6LNfSp8eomlLpveV4qr\n wOHUIrZhedwdLuK0vM4fccSPvInSGo8nmz8r9CC37+m4+G4XdfTqOiUV4Dz7KMJUoQUuY5f87vL\n tfw3oxHl1TCudlMqOqPfAP+HNcSn//FynAs9e5EmT7ESLv45HsVfIBPD63zN5hxrKR599Z5+/G7\n NEjMgzoNdIptb2H6QvFwJqVegDb7LZ3UylRhC3Vp7ENvIkw2CTAPCfc6a0rcyOpPifaWenBfoqI\n cPgX2bNExSbqJHtT4kj41QJxp/NiAXZZQfyFM2Ria5F1/hMrxJpojvYX02mymhi88tsbB0KKSLq\n xZBk8n/of0robKWwV6AosIDFwqM8I37GZyQa3PxUy4fAwWYryi8uEtrErmEQTMEjkxbM895sBq7\n jjRxfXbPEoGRNysciHUwgvVQ6cvKjEhOqENw==","X-Received":"by 2002:a5d:5d83:0:b0:43f:e413:f6fd with SMTP id\n ffacd0b85a97d-44a83318609mr5106522f8f.0.1777645281205;\n Fri, 01 May 2026 07:21:21 -0700 (PDT)","From":"=?utf-8?q?Alex_Benn=C3=A9e?= <alex.bennee@linaro.org>","To":"Alexandru Elisei <alexandru.elisei@arm.com>","Cc":"qemu-devel@nongnu.org,  Andrew Jones <andrew.jones@linux.dev>,  Eric\n Auger <eric.auger@redhat.com>,  \"open list:ARM\" <kvmarm@lists.linux.dev>,\n \"open list:Default mailing list\" <kvm@vger.kernel.org>","Subject":"Re: [kvm-unit-tests PATCH] arm: add wfx test case","In-Reply-To":"<afSnVJLe7HrB6ISS@raptor> (Alexandru Elisei's message of \"Fri, 1\n May 2026 14:15:14 +0100\")","References":"<20260427130045.3669851-1-alex.bennee@linaro.org>\n <afSnVJLe7HrB6ISS@raptor>","User-Agent":"mu4e 1.14.1-pre3; emacs 30.1","Date":"Fri, 01 May 2026 15:21:19 +0100","Message-ID":"<87zf2jcisg.fsf@draig.linaro.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Transfer-Encoding":"quoted-printable","Received-SPF":"pass client-ip=2a00:1450:4864:20::433;\n envelope-from=alex.bennee@linaro.org; helo=mail-wr1-x433.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=ham 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"}}]