Skip to content

Commit 6a428d6

Browse files
jgoulywilldeacon
authored andcommitted
kselftest/arm64: Add test case for POR_EL0 signal frame records
Ensure that we get signal context for POR_EL0 if and only if POE is present on the system. Copied from the TPIDR2 test. Signed-off-by: Joey Gouly <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Will Deacon <[email protected]> Cc: Mark Brown <[email protected]> Cc: Shuah Khan <[email protected]> Reviewed-by: Mark Brown <[email protected]> Acked-by: Shuah Khan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent d3c6e5b commit 6a428d6

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

tools/testing/selftests/arm64/signal/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
mangle_*
33
fake_sigreturn_*
44
fpmr_*
5+
poe_*
56
sme_*
67
ssve_*
78
sve_*
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (C) 2023 Arm Limited
4+
*
5+
* Verify that the POR_EL0 register context in signal frames is set up as
6+
* expected.
7+
*/
8+
9+
#include <signal.h>
10+
#include <ucontext.h>
11+
#include <sys/auxv.h>
12+
#include <sys/prctl.h>
13+
#include <unistd.h>
14+
#include <asm/sigcontext.h>
15+
16+
#include "test_signals_utils.h"
17+
#include "testcases.h"
18+
19+
static union {
20+
ucontext_t uc;
21+
char buf[1024 * 128];
22+
} context;
23+
24+
#define SYS_POR_EL0 "S3_3_C10_C2_4"
25+
26+
static uint64_t get_por_el0(void)
27+
{
28+
uint64_t val;
29+
30+
asm volatile(
31+
"mrs %0, " SYS_POR_EL0 "\n"
32+
: "=r"(val)
33+
:
34+
: );
35+
36+
return val;
37+
}
38+
39+
int poe_present(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
40+
{
41+
struct _aarch64_ctx *head = GET_BUF_RESV_HEAD(context);
42+
struct poe_context *poe_ctx;
43+
size_t offset;
44+
bool in_sigframe;
45+
bool have_poe;
46+
__u64 orig_poe;
47+
48+
have_poe = getauxval(AT_HWCAP2) & HWCAP2_POE;
49+
if (have_poe)
50+
orig_poe = get_por_el0();
51+
52+
if (!get_current_context(td, &context.uc, sizeof(context)))
53+
return 1;
54+
55+
poe_ctx = (struct poe_context *)
56+
get_header(head, POE_MAGIC, td->live_sz, &offset);
57+
58+
in_sigframe = poe_ctx != NULL;
59+
60+
fprintf(stderr, "POR_EL0 sigframe %s on system %s POE\n",
61+
in_sigframe ? "present" : "absent",
62+
have_poe ? "with" : "without");
63+
64+
td->pass = (in_sigframe == have_poe);
65+
66+
/*
67+
* Check that the value we read back was the one present at
68+
* the time that the signal was triggered.
69+
*/
70+
if (have_poe && poe_ctx) {
71+
if (poe_ctx->por_el0 != orig_poe) {
72+
fprintf(stderr, "POR_EL0 in frame is %llx, was %llx\n",
73+
poe_ctx->por_el0, orig_poe);
74+
td->pass = false;
75+
}
76+
}
77+
78+
return 0;
79+
}
80+
81+
struct tdescr tde = {
82+
.name = "POR_EL0",
83+
.descr = "Validate that POR_EL0 is present as expected",
84+
.timeout = 3,
85+
.run = poe_present,
86+
};

0 commit comments

Comments
 (0)