Skip to content

Commit 7bcebad

Browse files
brooniectmarinas
authored andcommitted
kselftest/arm64: Add basic FPMR test
Verify that a FPMR frame is generated on systems that support FPMR and not generated otherwise. Signed-off-by: Mark Brown <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent f4dcccd commit 7bcebad

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22
mangle_*
33
fake_sigreturn_*
4+
fpmr_*
45
sme_*
56
ssve_*
67
sve_*
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (C) 2023 ARM Limited
4+
*
5+
* Verify that the FPMR 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_FPMR "S3_3_C4_C4_2"
25+
26+
static uint64_t get_fpmr(void)
27+
{
28+
uint64_t val;
29+
30+
asm volatile (
31+
"mrs %0, " SYS_FPMR "\n"
32+
: "=r"(val)
33+
:
34+
: "cc");
35+
36+
return val;
37+
}
38+
39+
int fpmr_present(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
40+
{
41+
struct _aarch64_ctx *head = GET_BUF_RESV_HEAD(context);
42+
struct fpmr_context *fpmr_ctx;
43+
size_t offset;
44+
bool in_sigframe;
45+
bool have_fpmr;
46+
__u64 orig_fpmr;
47+
48+
have_fpmr = getauxval(AT_HWCAP2) & HWCAP2_FPMR;
49+
if (have_fpmr)
50+
orig_fpmr = get_fpmr();
51+
52+
if (!get_current_context(td, &context.uc, sizeof(context)))
53+
return 1;
54+
55+
fpmr_ctx = (struct fpmr_context *)
56+
get_header(head, FPMR_MAGIC, td->live_sz, &offset);
57+
58+
in_sigframe = fpmr_ctx != NULL;
59+
60+
fprintf(stderr, "FPMR sigframe %s on system %s FPMR\n",
61+
in_sigframe ? "present" : "absent",
62+
have_fpmr ? "with" : "without");
63+
64+
td->pass = (in_sigframe == have_fpmr);
65+
66+
if (have_fpmr && fpmr_ctx) {
67+
if (fpmr_ctx->fpmr != orig_fpmr) {
68+
fprintf(stderr, "FPMR in frame is %llx, was %llx\n",
69+
fpmr_ctx->fpmr, orig_fpmr);
70+
td->pass = false;
71+
}
72+
}
73+
74+
return 0;
75+
}
76+
77+
struct tdescr tde = {
78+
.name = "FPMR",
79+
.descr = "Validate that FPMR is present as expected",
80+
.timeout = 3,
81+
.run = fpmr_present,
82+
};

0 commit comments

Comments
 (0)