-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
kselftest: arm64: mangle_pstate_invalid_compat_toggle and common utils
Add some arm64/signal specific boilerplate and utility code to help further testcases' development. Introduce also one simple testcase mangle_pstate_invalid_compat_toggle and some related helpers: it is a simple mangle testcase which messes with the ucontext_t from within the signal handler, trying to toggle PSTATE state bits to switch the system between 32bit/64bit execution state. Expects SIGSEGV on test PASS. Reviewed-by: Dave Martin <Dave.Martin@arm.com> Signed-off-by: Cristian Marussi <cristian.marussi@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
- Loading branch information
Cristian Marussi
authored and
Catalin Marinas
committed
Nov 8, 2019
1 parent
313a4db
commit f96bf43
Showing
11 changed files
with
800 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
mangle_* | ||
fake_sigreturn_* | ||
!*.[ch] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# SPDX-License-Identifier: GPL-2.0 | ||
# Copyright (C) 2019 ARM Limited | ||
|
||
# Additional include paths needed by kselftest.h and local headers | ||
CFLAGS += -D_GNU_SOURCE -std=gnu99 -I. | ||
|
||
SRCS := $(filter-out testcases/testcases.c,$(wildcard testcases/*.c)) | ||
PROGS := $(patsubst %.c,%,$(SRCS)) | ||
|
||
# Generated binaries to be installed by top KSFT script | ||
TEST_GEN_PROGS := $(notdir $(PROGS)) | ||
|
||
# Get Kernel headers installed and use them. | ||
KSFT_KHDR_INSTALL := 1 | ||
|
||
# Including KSFT lib.mk here will also mangle the TEST_GEN_PROGS list | ||
# to account for any OUTPUT target-dirs optionally provided by | ||
# the toplevel makefile | ||
include ../../lib.mk | ||
|
||
$(TEST_GEN_PROGS): $(PROGS) | ||
cp $(PROGS) $(OUTPUT)/ | ||
|
||
clean: | ||
$(CLEAN) | ||
rm -f $(PROGS) | ||
|
||
# Common test-unit targets to build common-layout test-cases executables | ||
# Needs secondary expansion to properly include the testcase c-file in pre-reqs | ||
.SECONDEXPANSION: | ||
$(PROGS): test_signals.c test_signals_utils.c testcases/testcases.c $$@.c test_signals.h test_signals_utils.h testcases/testcases.h | ||
$(CC) $(CFLAGS) $^ -o $@ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
KSelfTest arm64/signal/ | ||
======================= | ||
|
||
Signals Tests | ||
+++++++++++++ | ||
|
||
- Tests are built around a common main compilation unit: such shared main | ||
enforces a standard sequence of operations needed to perform a single | ||
signal-test (setup/trigger/run/result/cleanup) | ||
|
||
- The above mentioned ops are configurable on a test-by-test basis: each test | ||
is described (and configured) using the descriptor signals.h::struct tdescr | ||
|
||
- Each signal testcase is compiled into its own executable: a separate | ||
executable is used for each test since many tests complete successfully | ||
by receiving some kind of fatal signal from the Kernel, so it's safer | ||
to run each test unit in its own standalone process, so as to start each | ||
test from a clean slate. | ||
|
||
- New tests can be simply defined in testcases/ dir providing a proper struct | ||
tdescr overriding all the defaults we wish to change (as of now providing a | ||
custom run method is mandatory though) | ||
|
||
- Signals' test-cases hereafter defined belong currently to two | ||
principal families: | ||
|
||
- 'mangle_' tests: a real signal (SIGUSR1) is raised and used as a trigger | ||
and then the test case code modifies the signal frame from inside the | ||
signal handler itself. | ||
|
||
- 'fake_sigreturn_' tests: a brand new custom artificial sigframe structure | ||
is placed on the stack and a sigreturn syscall is called to simulate a | ||
real signal return. This kind of tests does not use a trigger usually and | ||
they are just fired using some simple included assembly trampoline code. | ||
|
||
- Most of these tests are successfully passing if the process gets killed by | ||
some fatal signal: usually SIGSEGV or SIGBUS. Since while writing this | ||
kind of tests it is extremely easy in fact to end-up injecting other | ||
unrelated SEGV bugs in the testcases, it becomes extremely tricky to | ||
be really sure that the tests are really addressing what they are meant | ||
to address and they are not instead falling apart due to unplanned bugs | ||
in the test code. | ||
In order to alleviate the misery of the life of such test-developer, a few | ||
helpers are provided: | ||
|
||
- a couple of ASSERT_BAD/GOOD_CONTEXT() macros to easily parse a ucontext_t | ||
and verify if it is indeed GOOD or BAD (depending on what we were | ||
expecting), using the same logic/perspective as in the arm64 Kernel signals | ||
routines. | ||
|
||
- a sanity mechanism to be used in 'fake_sigreturn_'-alike tests: enabled by | ||
default it takes care to verify that the test-execution had at least | ||
successfully progressed up to the stage of triggering the fake sigreturn | ||
call. | ||
|
||
In both cases test results are expected in terms of: | ||
- some fatal signal sent by the Kernel to the test process | ||
or | ||
- analyzing some final regs state |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (C) 2019 ARM Limited | ||
* | ||
* Generic test wrapper for arm64 signal tests. | ||
* | ||
* Each test provides its own tde struct tdescr descriptor to link with | ||
* this wrapper. Framework provides common helpers. | ||
*/ | ||
#include <kselftest.h> | ||
|
||
#include "test_signals.h" | ||
#include "test_signals_utils.h" | ||
|
||
struct tdescr *current; | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
current = &tde; | ||
|
||
ksft_print_msg("%s :: %s\n", current->name, current->descr); | ||
if (test_setup(current)) { | ||
test_run(current); | ||
test_result(current); | ||
test_cleanup(current); | ||
} | ||
|
||
return current->pass ? KSFT_PASS : KSFT_FAIL; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* Copyright (C) 2019 ARM Limited */ | ||
|
||
#ifndef __TEST_SIGNALS_H__ | ||
#define __TEST_SIGNALS_H__ | ||
|
||
#include <signal.h> | ||
#include <stdbool.h> | ||
#include <ucontext.h> | ||
|
||
/* | ||
* Using ARCH specific and sanitized Kernel headers installed by KSFT | ||
* framework since we asked for it by setting flag KSFT_KHDR_INSTALL | ||
* in our Makefile. | ||
*/ | ||
#include <asm/ptrace.h> | ||
#include <asm/hwcap.h> | ||
|
||
#define __stringify_1(x...) #x | ||
#define __stringify(x...) __stringify_1(x) | ||
|
||
#define get_regval(regname, out) \ | ||
{ \ | ||
asm volatile("mrs %0, " __stringify(regname) \ | ||
: "=r" (out) \ | ||
: \ | ||
: "memory"); \ | ||
} | ||
|
||
/* | ||
* Feature flags used in tdescr.feats_required to specify | ||
* any feature by the test | ||
*/ | ||
enum { | ||
FSSBS_BIT, | ||
FMAX_END | ||
}; | ||
|
||
#define FEAT_SSBS (1UL << FSSBS_BIT) | ||
|
||
/* | ||
* A descriptor used to describe and configure a test case. | ||
* Fields with a non-trivial meaning are described inline in the following. | ||
*/ | ||
struct tdescr { | ||
/* KEEP THIS FIELD FIRST for easier lookup from assembly */ | ||
void *token; | ||
/* when disabled token based sanity checking is skipped in handler */ | ||
bool sanity_disabled; | ||
/* just a name for the test-case; manadatory field */ | ||
char *name; | ||
char *descr; | ||
unsigned long feats_required; | ||
/* bitmask of effectively supported feats: populated at run-time */ | ||
unsigned long feats_supported; | ||
bool initialized; | ||
unsigned int minsigstksz; | ||
/* signum used as a test trigger. Zero if no trigger-signal is used */ | ||
int sig_trig; | ||
/* | ||
* signum considered as a successful test completion. | ||
* Zero when no signal is expected on success | ||
*/ | ||
int sig_ok; | ||
/* signum expected on unsupported CPU features. */ | ||
int sig_unsupp; | ||
/* a timeout in second for test completion */ | ||
unsigned int timeout; | ||
bool triggered; | ||
bool pass; | ||
/* optional sa_flags for the installed handler */ | ||
int sa_flags; | ||
ucontext_t saved_uc; | ||
/* optional test private data */ | ||
void *priv; | ||
|
||
/* a custom setup function to be called before test starts */ | ||
int (*setup)(struct tdescr *td); | ||
/* a custom cleanup function called before test exits */ | ||
void (*cleanup)(struct tdescr *td); | ||
/* an optional function to be used as a trigger for test starting */ | ||
int (*trigger)(struct tdescr *td); | ||
/* | ||
* the actual test-core: invoked differently depending on the | ||
* presence of the trigger function above; this is mandatory | ||
*/ | ||
int (*run)(struct tdescr *td, siginfo_t *si, ucontext_t *uc); | ||
/* an optional function for custom results' processing */ | ||
void (*check_result)(struct tdescr *td); | ||
}; | ||
|
||
extern struct tdescr tde; | ||
#endif |
Oops, something went wrong.