diff --git a/README.adoc b/README.adoc index ec0c170..af229db 100644 --- a/README.adoc +++ b/README.adoc @@ -18804,6 +18804,10 @@ so we conclude that: Therefore, a WFE in userland is treated much like a busy loop by the Linux kernel: the kernel does not seem to try and explicitly make up room for other processes as would happen on a futex. +The following test checks that SEV events don't wake up a futexes, running forever in case of success. In <>, this is crucial to prevent deadlocks: + +* link:userland/arch/aarch64/inline_asm/futex_sev.cpp[] + ====== ARMv8 spinlock pattern http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka16277.html diff --git a/path_properties.py b/path_properties.py index 7eacec9..dd91257 100644 --- a/path_properties.py +++ b/path_properties.py @@ -525,6 +525,7 @@ path_properties_tuples = ( }, { 'freestanding': freestanding_properties, + 'futex_sev.cpp': {'more_than_1s': True}, 'sve_addvl.c': {'arm_sve': True}, 'wfe_sev.c': { # gem5 bug, WFE not waking up on syscall emulation, diff --git a/userland/arch/aarch64/inline_asm/futex_sev.cpp b/userland/arch/aarch64/inline_asm/futex_sev.cpp new file mode 100644 index 0000000..e220f72 --- /dev/null +++ b/userland/arch/aarch64/inline_asm/futex_sev.cpp @@ -0,0 +1,35 @@ +// https://cirosantilli.com/linux-kernel-module-cheat#wfe-from-userland + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#include +#include +#include + +#include + +std::atomic_ulong done; +int futex = 1; + +void myfunc() { + lkmc_futex(&futex, FUTEX_WAIT, futex, NULL, NULL, 0); + done.store(futex); +} + +int main(int argc, char **argv) { + bool do_sev = true; + if (argc > 1) { + do_sev = (argv[1][0] != '0'); + } + done.store(0); + std::thread thread; + thread = std::thread(myfunc); + while (!done.load()) { + if (do_sev) { + __asm__ __volatile__ ("sev"); + } + } + thread.join(); +}