From 942285428fefeef1758b7e25207b86fde3d58bb4 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 24 Sep 2025 08:42:37 -0700 Subject: [PATCH] tests/tcg/multiarch: Add tb-link test Signed-off-by: Richard Henderson (cherry picked from commit e13e1195db8af18e149065a59351ea85215645bb) (Mjt: resolve context conflict in tests/tcg/multiarch/Makefile.target) Signed-off-by: Michael Tokarev --- tests/tcg/multiarch/Makefile.target | 2 + tests/tcg/multiarch/tb-link.c | 67 +++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 tests/tcg/multiarch/tb-link.c diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target index 5f0fee1aadb..2fdec1f05f9 100644 --- a/tests/tcg/multiarch/Makefile.target +++ b/tests/tcg/multiarch/Makefile.target @@ -39,6 +39,8 @@ signals: LDFLAGS+=-lrt -lpthread munmap-pthread: CFLAGS+=-pthread munmap-pthread: LDFLAGS+=-pthread +tb-link: LDFLAGS+=-lpthread + # We define the runner for test-mmap after the individual # architectures have defined their supported pages sizes. If no # additional page sizes are defined we only run the default test. diff --git a/tests/tcg/multiarch/tb-link.c b/tests/tcg/multiarch/tb-link.c new file mode 100644 index 00000000000..4e40306fa18 --- /dev/null +++ b/tests/tcg/multiarch/tb-link.c @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Verify that a single TB spin-loop is properly invalidated, + * releasing the thread from the spin-loop. + */ + +#include +#include +#include +#include +#include +#include +#include + + +#ifdef __x86_64__ +#define READY 0x000047c6 /* movb $0,0(%rdi) */ +#define LOOP 0xfceb9090 /* 1: nop*2; jmp 1b */ +#define RETURN 0x909090c3 /* ret; nop*3 */ +#define NOP 0x90909090 /* nop*4 */ +#elif defined(__aarch64__) +#define READY 0x3900001f /* strb wzr,[x0] */ +#define LOOP 0x14000000 /* b . */ +#define RETURN 0xd65f03c0 /* ret */ +#define NOP 0xd503201f /* nop */ +#elif defined(__riscv) +#define READY 0x00050023 /* sb zero, (a0) */ +#define LOOP 0x0000006f /* jal zero, #0 */ +#define RETURN 0x00008067 /* jalr zero, ra, 0 */ +#define NOP 0x00000013 /* nop */ +#endif + + +int main() +{ +#ifdef READY + int tmp; + pthread_t thread_id; + bool hold = true; + uint32_t *buf; + + buf = mmap(NULL, 3 * sizeof(uint32_t), + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + assert(buf != MAP_FAILED); + + buf[0] = READY; + buf[1] = LOOP; + buf[2] = RETURN; + + alarm(2); + + tmp = pthread_create(&thread_id, NULL, (void *(*)(void *))buf, &hold); + assert(tmp == 0); + + while (hold) { + sched_yield(); + } + + buf[1] = NOP; + __builtin___clear_cache(&buf[1], &buf[2]); + + tmp = pthread_join(thread_id, NULL); + assert(tmp == 0); +#endif + return 0; +} -- 2.47.3