mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
selftests/rseq: Validate legacy behavior
The RSEQ legacy mode behavior requires that the ID fields in the rseq
region are unconditionally updated on every context switch and before
signal delivery even if not required by the ABI specification.
To ensure that this behavior is preserved for legacy users in the future,
add a test which validates that with a sleep() and a signal sent to self.
Provide a run script which prevents GLIBC from registering a RSEQ region,
so that the test can register it's own legacy sized region.
Fixes: 566d8015f7 ("rseq: Avoid CPU/MM CID updates when no event pending")
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Tested-by: Dmitry Vyukov <dvyukov@google.com>
Link: https://patch.msgid.link/20260428224427.764705536%40kernel.org
Cc: stable@vger.kernel.org
This commit is contained in:
parent
d97cb2ef0b
commit
fdf4eb6326
|
|
@ -22,9 +22,10 @@ TEST_GEN_PROGS_EXTENDED = librseq.so \
|
|||
param_test_compare_twice \
|
||||
param_test_mm_cid \
|
||||
param_test_mm_cid_compare_twice \
|
||||
syscall_errors_test
|
||||
syscall_errors_test \
|
||||
legacy_check
|
||||
|
||||
TEST_PROGS = run_param_test.sh run_syscall_errors_test.sh
|
||||
TEST_PROGS = run_param_test.sh run_syscall_errors_test.sh run_legacy_check.sh
|
||||
|
||||
TEST_FILES := settings
|
||||
|
||||
|
|
|
|||
65
tools/testing/selftests/rseq/legacy_check.c
Normal file
65
tools/testing/selftests/rseq/legacy_check.c
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "rseq.h"
|
||||
|
||||
#include "../kselftest_harness.h"
|
||||
|
||||
FIXTURE(legacy)
|
||||
{
|
||||
};
|
||||
|
||||
static int cpu_id_in_sigfn = -1;
|
||||
|
||||
static void sigfn(int sig)
|
||||
{
|
||||
struct rseq_abi *rs = rseq_get_abi();
|
||||
|
||||
cpu_id_in_sigfn = rs->cpu_id_start;
|
||||
}
|
||||
|
||||
FIXTURE_SETUP(legacy)
|
||||
{
|
||||
int res = __rseq_register_current_thread(true, true);
|
||||
|
||||
switch (res) {
|
||||
case -ENOSYS:
|
||||
SKIP(return, "RSEQ not enabled\n");
|
||||
case -EBUSY:
|
||||
SKIP(return, "GLIBC owns RSEQ. Disable GLIBC RSEQ registration\n");
|
||||
default:
|
||||
ASSERT_EQ(res, 0);
|
||||
}
|
||||
|
||||
ASSERT_NE(signal(SIGUSR1, sigfn), SIG_ERR);
|
||||
}
|
||||
|
||||
FIXTURE_TEARDOWN(legacy)
|
||||
{
|
||||
}
|
||||
|
||||
TEST_F(legacy, legacy_test)
|
||||
{
|
||||
struct rseq_abi *rs = rseq_get_abi();
|
||||
|
||||
ASSERT_NE(rs, NULL);
|
||||
|
||||
/* Overwrite rs::cpu_id_start */
|
||||
rs->cpu_id_start = -1;
|
||||
sleep(1);
|
||||
ASSERT_NE(rs->cpu_id_start, -1);
|
||||
|
||||
rs->cpu_id_start = -1;
|
||||
ASSERT_EQ(raise(SIGUSR1), 0);
|
||||
ASSERT_NE(rs->cpu_id_start, -1);
|
||||
ASSERT_NE(cpu_id_in_sigfn, -1);
|
||||
}
|
||||
|
||||
TEST_HARNESS_MAIN
|
||||
4
tools/testing/selftests/rseq/run_legacy_check.sh
Executable file
4
tools/testing/selftests/rseq/run_legacy_check.sh
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
GLIBC_TUNABLES="${GLIBC_TUNABLES:-}:glibc.pthread.rseq=0" ./legacy_check
|
||||
Loading…
Reference in New Issue
Block a user