Skip to content

Commit

Permalink
selftests/x86: Consolidate redundant signal helper functions
Browse files Browse the repository at this point in the history
The x86 selftests frequently register and clean up signal handlers, but
the sethandler() and clearhandler() functions have been redundantly
copied across multiple .c files.

Move these functions to helpers.h to enable reuse across tests,
eliminating around 250 lines of duplicate code.

Converge the error handling by using ksft_exit_fail_msg(), which is
functionally equivalent with err() within the selftest framework.

This change is a prerequisite for the upcoming xstate selftest, which
requires signal handling for registering and cleaning up handlers.

Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20250226010731.2456-2-chang.seok.bae@intel.com
  • Loading branch information
Chang S. Bae authored and Ingo Molnar committed Feb 26, 2025
1 parent ac3144f commit dbd6b64
Show file tree
Hide file tree
Showing 18 changed files with 51 additions and 315 deletions.
25 changes: 1 addition & 24 deletions tools/testing/selftests/x86/amx.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <sys/uio.h>

#include "../kselftest.h" /* For __cpuid_count() */
#include "helpers.h"

#ifndef __x86_64__
# error This test is 64-bit only
Expand Down Expand Up @@ -61,30 +62,6 @@ static inline void xrstor(struct xsave_buffer *xbuf, uint64_t rfbm)
/* err() exits and will not return */
#define fatal_error(msg, ...) err(1, "[FAIL]\t" msg, ##__VA_ARGS__)

static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
int flags)
{
struct sigaction sa;

memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO | flags;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
fatal_error("sigaction");
}

static void clearhandler(int sig)
{
struct sigaction sa;

memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
fatal_error("sigaction");
}

#define XFEATURE_XTILECFG 17
#define XFEATURE_XTILEDATA 18
#define XFEATURE_MASK_XTILECFG (1 << XFEATURE_XTILECFG)
Expand Down
14 changes: 1 addition & 13 deletions tools/testing/selftests/x86/corrupt_xstate_header.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <sys/wait.h>

#include "../kselftest.h" /* For __cpuid_count() */
#include "helpers.h"

static inline int xsave_enabled(void)
{
Expand All @@ -29,19 +30,6 @@ static inline int xsave_enabled(void)
return ecx & (1U << 27);
}

static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
int flags)
{
struct sigaction sa;

memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO | flags;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
err(1, "sigaction");
}

static void sigusr1(int sig, siginfo_t *info, void *uc_void)
{
ucontext_t *uc = uc_void;
Expand Down
24 changes: 2 additions & 22 deletions tools/testing/selftests/x86/entry_from_vm86.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,11 @@
#include <errno.h>
#include <sys/vm86.h>

#include "helpers.h"

static unsigned long load_addr = 0x10000;
static int nerrs = 0;

static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
int flags)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO | flags;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
err(1, "sigaction");
}

static void clearhandler(int sig)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
err(1, "sigaction");
}

static sig_atomic_t got_signal;

static void sighandler(int sig, siginfo_t *info, void *ctx_void)
Expand Down
24 changes: 2 additions & 22 deletions tools/testing/selftests/x86/fsgsbase.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include <sys/wait.h>
#include <setjmp.h>

#include "helpers.h"

#ifndef __x86_64__
# error This test is 64-bit only
#endif
Expand All @@ -39,28 +41,6 @@ static unsigned short *shared_scratch;

static int nerrs;

static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
int flags)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO | flags;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
err(1, "sigaction");
}

static void clearhandler(int sig)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
err(1, "sigaction");
}

static void sigsegv(int sig, siginfo_t *si, void *ctx_void)
{
ucontext_t *ctx = (ucontext_t*)ctx_void;
Expand Down
28 changes: 28 additions & 0 deletions tools/testing/selftests/x86/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
#ifndef __SELFTESTS_X86_HELPERS_H
#define __SELFTESTS_X86_HELPERS_H

#include <signal.h>
#include <string.h>

#include <asm/processor-flags.h>

#include "../kselftest.h"

static inline unsigned long get_eflags(void)
{
#ifdef __x86_64__
Expand All @@ -22,4 +27,27 @@ static inline void set_eflags(unsigned long eflags)
#endif
}

static inline void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), int flags)
{
struct sigaction sa;

memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO | flags;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
ksft_exit_fail_msg("sigaction failed");
}

static inline void clearhandler(int sig)
{
struct sigaction sa;

memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
ksft_exit_fail_msg("sigaction failed");
}

#endif /* __SELFTESTS_X86_HELPERS_H */
25 changes: 2 additions & 23 deletions tools/testing/selftests/x86/ioperm.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,9 @@
#include <sched.h>
#include <sys/io.h>

static int nerrs = 0;

static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
int flags)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO | flags;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
err(1, "sigaction");

}
#include "helpers.h"

static void clearhandler(int sig)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
err(1, "sigaction");
}
static int nerrs = 0;

static jmp_buf jmpbuf;

Expand Down
25 changes: 2 additions & 23 deletions tools/testing/selftests/x86/iopl.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,9 @@
#include <sched.h>
#include <sys/io.h>

static int nerrs = 0;

static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
int flags)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO | flags;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
err(1, "sigaction");

}
#include "helpers.h"

static void clearhandler(int sig)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
err(1, "sigaction");
}
static int nerrs = 0;

static jmp_buf jmpbuf;

Expand Down
18 changes: 4 additions & 14 deletions tools/testing/selftests/x86/ldt_gdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include <asm/prctl.h>
#include <sys/prctl.h>

#include "helpers.h"

#define AR_ACCESSED (1<<8)

#define AR_TYPE_RODATA (0 * (1<<9))
Expand Down Expand Up @@ -506,20 +508,6 @@ static void fix_sa_restorer(int sig)
}
#endif

static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
int flags)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO | flags;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
err(1, "sigaction");

fix_sa_restorer(sig);
}

static jmp_buf jmpbuf;

static void sigsegv(int sig, siginfo_t *info, void *ctx_void)
Expand Down Expand Up @@ -549,9 +537,11 @@ static void do_multicpu_tests(void)
}

sethandler(SIGSEGV, sigsegv, 0);
fix_sa_restorer(SIGSEGV);
#ifdef __i386__
/* True 32-bit kernels send SIGILL instead of SIGSEGV on IRET faults. */
sethandler(SIGILL, sigsegv, 0);
fix_sa_restorer(SIGILL);
#endif

printf("[RUN]\tCross-CPU LDT invalidation\n");
Expand Down
14 changes: 1 addition & 13 deletions tools/testing/selftests/x86/mov_ss_trap.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#include <setjmp.h>
#include <sys/prctl.h>

#define X86_EFLAGS_RF (1UL << 16)
#include "helpers.h"

#if __x86_64__
# define REG_IP REG_RIP
Expand Down Expand Up @@ -94,18 +94,6 @@ static void enable_watchpoint(void)
}
}

static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
int flags)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO | flags;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
err(1, "sigaction");
}

static char const * const signames[] = {
[SIGSEGV] = "SIGSEGV",
[SIGBUS] = "SIBGUS",
Expand Down
24 changes: 2 additions & 22 deletions tools/testing/selftests/x86/ptrace_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <asm/ptrace-abi.h>
#include <sys/auxv.h>

#include "helpers.h"

/* Bitness-agnostic defines for user_regs_struct fields. */
#ifdef __x86_64__
# define user_syscall_nr orig_rax
Expand Down Expand Up @@ -93,18 +95,6 @@ static siginfo_t wait_trap(pid_t chld)
return si;
}

static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
int flags)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO | flags;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
err(1, "sigaction");
}

static void setsigign(int sig, int flags)
{
struct sigaction sa;
Expand All @@ -116,16 +106,6 @@ static void setsigign(int sig, int flags)
err(1, "sigaction");
}

static void clearhandler(int sig)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
err(1, "sigaction");
}

#ifdef __x86_64__
# define REG_BP REG_RBP
#else
Expand Down
Loading

0 comments on commit dbd6b64

Please sign in to comment.