-
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: Add a test case for TPIDR2 restore
Due to the fact that TPIDR2 is intended to be managed by libc we don't currently test modifying it via the signal context since that might disrupt libc's usage of it and cause instability. We can however test the opposite case with less risk, modifying TPIDR2 in a signal handler and making sure that the original value is restored after returning from the signal handler. Add a test which does this. Signed-off-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20230621-arm64-fix-tpidr2-signal-restore-v2-2-c8e8fcc10302@kernel.org Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
- Loading branch information
Mark Brown
authored and
Catalin Marinas
committed
Jun 23, 2023
1 parent
616cb2f
commit f7a5d72
Showing
2 changed files
with
87 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ fake_sigreturn_* | |
sme_* | ||
ssve_* | ||
sve_* | ||
tpidr2_siginfo | ||
tpidr2_* | ||
za_* | ||
zt_* | ||
!*.[ch] |
86 changes: 86 additions & 0 deletions
86
tools/testing/selftests/arm64/signal/testcases/tpidr2_restore.c
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,86 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (C) 2023 ARM Limited | ||
* | ||
* Verify that the TPIDR2 register context in signal frames is restored. | ||
*/ | ||
|
||
#include <signal.h> | ||
#include <ucontext.h> | ||
#include <sys/auxv.h> | ||
#include <sys/prctl.h> | ||
#include <unistd.h> | ||
#include <asm/sigcontext.h> | ||
|
||
#include "test_signals_utils.h" | ||
#include "testcases.h" | ||
|
||
#define SYS_TPIDR2 "S3_3_C13_C0_5" | ||
|
||
static uint64_t get_tpidr2(void) | ||
{ | ||
uint64_t val; | ||
|
||
asm volatile ( | ||
"mrs %0, " SYS_TPIDR2 "\n" | ||
: "=r"(val) | ||
: | ||
: "cc"); | ||
|
||
return val; | ||
} | ||
|
||
static void set_tpidr2(uint64_t val) | ||
{ | ||
asm volatile ( | ||
"msr " SYS_TPIDR2 ", %0\n" | ||
: | ||
: "r"(val) | ||
: "cc"); | ||
} | ||
|
||
|
||
static uint64_t initial_tpidr2; | ||
|
||
static bool save_tpidr2(struct tdescr *td) | ||
{ | ||
initial_tpidr2 = get_tpidr2(); | ||
fprintf(stderr, "Initial TPIDR2: %lx\n", initial_tpidr2); | ||
|
||
return true; | ||
} | ||
|
||
static int modify_tpidr2(struct tdescr *td, siginfo_t *si, ucontext_t *uc) | ||
{ | ||
uint64_t my_tpidr2 = get_tpidr2(); | ||
|
||
my_tpidr2++; | ||
fprintf(stderr, "Setting TPIDR2 to %lx\n", my_tpidr2); | ||
set_tpidr2(my_tpidr2); | ||
|
||
return 0; | ||
} | ||
|
||
static void check_tpidr2(struct tdescr *td) | ||
{ | ||
uint64_t tpidr2 = get_tpidr2(); | ||
|
||
td->pass = tpidr2 == initial_tpidr2; | ||
|
||
if (td->pass) | ||
fprintf(stderr, "TPIDR2 restored\n"); | ||
else | ||
fprintf(stderr, "TPIDR2 was %lx but is now %lx\n", | ||
initial_tpidr2, tpidr2); | ||
} | ||
|
||
struct tdescr tde = { | ||
.name = "TPIDR2 restore", | ||
.descr = "Validate that TPIDR2 is restored from the sigframe", | ||
.feats_required = FEAT_SME, | ||
.timeout = 3, | ||
.sig_trig = SIGUSR1, | ||
.init = save_tpidr2, | ||
.run = modify_tpidr2, | ||
.check_result = check_tpidr2, | ||
}; |