Linux Kernel Selftest development
 help / color / mirror / Atom feed
From: Ackerley Tng <ackerleytng@google.com>
To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com,
	 brauner@kernel.org, chao.p.peng@linux.intel.com,
	david@kernel.org,  ira.weiny@intel.com, jmattson@google.com,
	jroedel@suse.de,  jthoughton@google.com, michael.roth@amd.com,
	oupton@kernel.org,  pankaj.gupta@amd.com, qperret@google.com,
	rick.p.edgecombe@intel.com,  rientjes@google.com,
	shivankg@amd.com, steven.price@arm.com, tabba@google.com,
	 willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com,
	 forkloop@google.com, pratyush@kernel.org,
	suzuki.poulose@arm.com,  aneesh.kumar@kernel.org,
	Paolo Bonzini <pbonzini@redhat.com>,
	 Sean Christopherson <seanjc@google.com>,
	Thomas Gleixner <tglx@kernel.org>, Ingo Molnar <mingo@redhat.com>,
	 Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	x86@kernel.org,  "H. Peter Anvin" <hpa@zytor.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	 Masami Hiramatsu <mhiramat@kernel.org>,
	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
	 Jonathan Corbet <corbet@lwn.net>,
	Shuah Khan <skhan@linuxfoundation.org>,
	 Shuah Khan <shuah@kernel.org>,
	Vishal Annapurve <vannapurve@google.com>,
	Jason Gunthorpe <jgg@ziepe.ca>,
	 Vlastimil Babka <vbabka@kernel.org>
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	 linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org,
	 linux-kselftest@vger.kernel.org,
	Ackerley Tng <ackerleytng@google.com>
Subject: [PATCH RFC v3 33/43] KVM: selftests: Make TEST_EXPECT_SIGBUS thread-safe
Date: Fri, 13 Mar 2026 06:13:12 +0000	[thread overview]
Message-ID: <20260313-gmem-inplace-conversion-v3-33-5fc12a70ec89@google.com> (raw)
In-Reply-To: <20260313-gmem-inplace-conversion-v3-0-5fc12a70ec89@google.com>

The TEST_EXPECT_SIGBUS macro is not thread-safe as it uses a global
sigjmp_buf and installs a global SIGBUS signal handler. If multiple threads
execute the macro concurrently, they will race on installing the signal
handler and stomp on other threads' jump buffers, leading to incorrect test
behavior.

Make TEST_EXPECT_SIGBUS thread-safe with the following changes:

Share the KVM tests' global signal handler. sigaction() applies to all
threads; without sharing a global signal handler, one thread may have
removed the signal handler that another thread added, hence leading to
unexpected signals.

The alternative of layering signal handlers was considered, but calling
sigaction() within TEST_EXPECT_SIGBUS() necessarily creates a race. To
avoid adding new setup and teardown routines to do sigaction() and keep
usage of TEST_EXPECT_SIGBUS() simple, share the KVM tests' global signal
handler.

Opportunistically rename report_unexpected_signal to
catchall_signal_handler.

To continue to only expect SIGBUS within specific regions of code, use a
thread-specific variable, expecting_sigbus, to replace installing and
removing signal handlers.

Make the execution environment for the thread, sigjmp_buf, a
thread-specific variable.

As part of TEST_EXPECT_SIGBUS(), assert the prerequisite for this setup,
that the current signal handler is the catchall_signal_handler.

Signed-off-by: Ackerley Tng <ackerleytng@google.com>
---
 tools/testing/selftests/kvm/include/test_util.h | 30 +++++++++++++------------
 tools/testing/selftests/kvm/lib/kvm_util.c      | 18 ++++++++++-----
 tools/testing/selftests/kvm/lib/test_util.c     |  7 ------
 3 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/test_util.h b/tools/testing/selftests/kvm/include/test_util.h
index 2871a42928471..63e57d189f5fd 100644
--- a/tools/testing/selftests/kvm/include/test_util.h
+++ b/tools/testing/selftests/kvm/include/test_util.h
@@ -80,21 +80,23 @@ do {									\
 	__builtin_unreachable(); \
 } while (0)
 
-extern sigjmp_buf expect_sigbus_jmpbuf;
-void expect_sigbus_handler(int signum);
+extern __thread sigjmp_buf expect_sigbus_jmpbuf;
+extern __thread bool expecting_sigbus;
+extern void catchall_signal_handler(int signum);
 
-#define TEST_EXPECT_SIGBUS(action)						\
-do {										\
-	struct sigaction sa_old, sa_new = {					\
-		.sa_handler = expect_sigbus_handler,				\
-	};									\
-										\
-	sigaction(SIGBUS, &sa_new, &sa_old);					\
-	if (sigsetjmp(expect_sigbus_jmpbuf, 1) == 0) {				\
-		action;								\
-		TEST_FAIL("'%s' should have triggered SIGBUS", #action);	\
-	}									\
-	sigaction(SIGBUS, &sa_old, NULL);					\
+#define TEST_EXPECT_SIGBUS(action)					\
+do {									\
+	struct sigaction sa = {};					\
+									\
+	TEST_ASSERT_EQ(sigaction(SIGBUS, NULL, &sa), 0);		\
+	TEST_ASSERT_EQ(sa.sa_handler, &catchall_signal_handler);	\
+									\
+	expecting_sigbus = true;					\
+	if (sigsetjmp(expect_sigbus_jmpbuf, 1) == 0) {			\
+		action;							\
+		TEST_FAIL("'%s' should have triggered SIGBUS", #action);\
+	}								\
+	expecting_sigbus = false;					\
 } while (0)
 
 size_t parse_size(const char *size);
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 6f7d3adb25d0a..f4aa762f050aa 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -2347,13 +2347,20 @@ __weak void kvm_selftest_arch_init(void)
 {
 }
 
-static void report_unexpected_signal(int signum)
+__thread sigjmp_buf expect_sigbus_jmpbuf;
+__thread bool expecting_sigbus;
+
+void catchall_signal_handler(int signum)
 {
+	switch (signum) {
+	case SIGBUS: {
+		if (expecting_sigbus)
+			siglongjmp(expect_sigbus_jmpbuf, 1);
+
+		TEST_FAIL("Unexpected SIGBUS (%d)\n", signum);
+	}
 #define KVM_CASE_SIGNUM(sig)					\
 	case sig: TEST_FAIL("Unexpected " #sig " (%d)\n", signum)
-
-	switch (signum) {
-	KVM_CASE_SIGNUM(SIGBUS);
 	KVM_CASE_SIGNUM(SIGSEGV);
 	KVM_CASE_SIGNUM(SIGILL);
 	KVM_CASE_SIGNUM(SIGFPE);
@@ -2365,12 +2372,13 @@ static void report_unexpected_signal(int signum)
 void __attribute((constructor)) kvm_selftest_init(void)
 {
 	struct sigaction sig_sa = {
-		.sa_handler = report_unexpected_signal,
+		.sa_handler = catchall_signal_handler,
 	};
 
 	/* Tell stdout not to buffer its content. */
 	setbuf(stdout, NULL);
 
+	expecting_sigbus = false;
 	sigaction(SIGBUS, &sig_sa, NULL);
 	sigaction(SIGSEGV, &sig_sa, NULL);
 	sigaction(SIGILL, &sig_sa, NULL);
diff --git a/tools/testing/selftests/kvm/lib/test_util.c b/tools/testing/selftests/kvm/lib/test_util.c
index 8a1848586a857..03eb99af9b8de 100644
--- a/tools/testing/selftests/kvm/lib/test_util.c
+++ b/tools/testing/selftests/kvm/lib/test_util.c
@@ -18,13 +18,6 @@
 
 #include "test_util.h"
 
-sigjmp_buf expect_sigbus_jmpbuf;
-
-void __attribute__((used)) expect_sigbus_handler(int signum)
-{
-	siglongjmp(expect_sigbus_jmpbuf, 1);
-}
-
 /*
  * Random number generator that is usable from guest code. This is the
  * Park-Miller LCG using standard constants.

-- 
2.53.0.851.ga537e3e6e9-goog


  parent reply	other threads:[~2026-03-13  6:13 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-13  6:12 [PATCH RFC v3 00/43] guest_memfd: In-place conversion support Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 01/43] KVM: guest_memfd: Introduce per-gmem attributes, use to guard user mappings Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 02/43] KVM: Rename KVM_GENERIC_MEMORY_ATTRIBUTES to KVM_VM_MEMORY_ATTRIBUTES Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 03/43] KVM: Enumerate support for PRIVATE memory iff kvm_arch_has_private_mem is defined Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 04/43] KVM: Stub in ability to disable per-VM memory attribute tracking Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 05/43] KVM: guest_memfd: Wire up kvm_get_memory_attributes() to per-gmem attributes Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 06/43] KVM: guest_memfd: Update kvm_gmem_populate() to use gmem attributes Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 07/43] KVM: Introduce KVM_SET_MEMORY_ATTRIBUTES2 Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 08/43] KVM: guest_memfd: Enable INIT_SHARED on guest_memfd for x86 Coco VMs Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 09/43] KVM: guest_memfd: Add support for KVM_SET_MEMORY_ATTRIBUTES2 Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 10/43] KVM: guest_memfd: Handle lru_add fbatch refcounts during conversion safety check Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 11/43] KVM: Move KVM_VM_MEMORY_ATTRIBUTES config definition to x86 Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 12/43] KVM: Let userspace disable per-VM mem attributes, enable per-gmem attributes Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 13/43] KVM: selftests: Create gmem fd before "regular" fd when adding memslot Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 14/43] KVM: selftests: Rename guest_memfd{,_offset} to gmem_{fd,offset} Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 15/43] KVM: selftests: Add support for mmap() on guest_memfd in core library Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 16/43] KVM: selftests: Add selftests global for guest memory attributes capability Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 17/43] KVM: selftests: Update framework to use KVM_SET_MEMORY_ATTRIBUTES2 Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 18/43] KVM: selftests: Add helpers for calling ioctls on guest_memfd Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 19/43] KVM: selftests: Test using guest_memfd for guest private memory Ackerley Tng
2026-03-13  6:12 ` [PATCH RFC v3 20/43] KVM: selftests: Test basic single-page conversion flow Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 21/43] KVM: selftests: Test conversion flow when INIT_SHARED Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 22/43] KVM: selftests: Test indexing in guest_memfd Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 23/43] KVM: selftests: Test conversion before allocation Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 24/43] KVM: selftests: Convert with allocated folios in different layouts Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 25/43] KVM: selftests: Test precision of conversion Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 26/43] KVM: selftests: Test that truncation does not change shared/private status Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 27/43] KVM: selftests: Test that shared/private status is consistent across processes Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 28/43] KVM: selftests: Test conversion with elevated page refcount Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 29/43] KVM: selftests: Reset shared memory after hole-punching Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 30/43] KVM: selftests: Provide function to look up guest_memfd details from gpa Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 31/43] KVM: selftests: Provide common function to set memory attributes Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 32/43] KVM: selftests: Check fd/flags provided to mmap() when setting up memslot Ackerley Tng
2026-03-13  6:13 ` Ackerley Tng [this message]
2026-03-13  6:13 ` [PATCH RFC v3 34/43] KVM: selftests: Update private_mem_conversions_test to mmap() guest_memfd Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 35/43] KVM: selftests: Add script to exercise private_mem_conversions_test Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 36/43] KVM: selftests: Update pre-fault test to work with per-guest_memfd attributes Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 37/43] KVM: selftests: Update private memory exits test work with per-gmem attributes Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 38/43] KVM: guest_memfd: Introduce default handlers for content modes Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 39/43] KVM: guest_memfd: Apply content modes while setting memory attributes Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 40/43] KVM: x86: Add support for applying content modes Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 41/43] KVM: x86: Support content mode ZERO for TDX Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 42/43] KVM: selftests: Allow flags to be specified in set_memory_attributes functions Ackerley Tng
2026-03-13  6:13 ` [PATCH RFC v3 43/43] KVM: selftests: Update tests to use flag-enabled library functions Ackerley Tng
2026-03-13 15:45 ` [PATCH RFC v3 00/43] guest_memfd: In-place conversion support Sean Christopherson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260313-gmem-inplace-conversion-v3-33-5fc12a70ec89@google.com \
    --to=ackerleytng@google.com \
    --cc=aik@amd.com \
    --cc=andrew.jones@linux.dev \
    --cc=aneesh.kumar@kernel.org \
    --cc=binbin.wu@linux.intel.com \
    --cc=bp@alien8.de \
    --cc=brauner@kernel.org \
    --cc=chao.p.peng@linux.intel.com \
    --cc=corbet@lwn.net \
    --cc=dave.hansen@linux.intel.com \
    --cc=david@kernel.org \
    --cc=forkloop@google.com \
    --cc=hpa@zytor.com \
    --cc=ira.weiny@intel.com \
    --cc=jgg@ziepe.ca \
    --cc=jmattson@google.com \
    --cc=jroedel@suse.de \
    --cc=jthoughton@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=mhiramat@kernel.org \
    --cc=michael.roth@amd.com \
    --cc=mingo@redhat.com \
    --cc=oupton@kernel.org \
    --cc=pankaj.gupta@amd.com \
    --cc=pbonzini@redhat.com \
    --cc=pratyush@kernel.org \
    --cc=qperret@google.com \
    --cc=rick.p.edgecombe@intel.com \
    --cc=rientjes@google.com \
    --cc=rostedt@goodmis.org \
    --cc=seanjc@google.com \
    --cc=shivankg@amd.com \
    --cc=shuah@kernel.org \
    --cc=skhan@linuxfoundation.org \
    --cc=steven.price@arm.com \
    --cc=suzuki.poulose@arm.com \
    --cc=tabba@google.com \
    --cc=tglx@kernel.org \
    --cc=vannapurve@google.com \
    --cc=vbabka@kernel.org \
    --cc=willy@infradead.org \
    --cc=wyihan@google.com \
    --cc=x86@kernel.org \
    --cc=yan.y.zhao@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox