xref: /linux/tools/testing/selftests/arm64/signal/testcases/gcs_exception_fault.c (revision 7f71507851fc7764b36a3221839607d3a45c2025)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2023 ARM Limited
4  */
5 
6 #include <errno.h>
7 #include <signal.h>
8 #include <unistd.h>
9 
10 #include <sys/mman.h>
11 #include <sys/prctl.h>
12 
13 #include "test_signals_utils.h"
14 #include "testcases.h"
15 
16 /*
17  * We should get this from asm/siginfo.h but the testsuite is being
18  * clever with redefining siginfo_t.
19  */
20 #ifndef SEGV_CPERR
21 #define SEGV_CPERR 10
22 #endif
23 
24 static inline void gcsss1(uint64_t Xt)
25 {
26 	asm volatile (
27 		"sys #3, C7, C7, #2, %0\n"
28 		:
29 		: "rZ" (Xt)
30 		: "memory");
31 }
32 
33 static int gcs_op_fault_trigger(struct tdescr *td)
34 {
35 	/*
36 	 * The slot below our current GCS should be in a valid GCS but
37 	 * must not have a valid cap in it.
38 	 */
39 	gcsss1(get_gcspr_el0() - 8);
40 
41 	return 0;
42 }
43 
44 static int gcs_op_fault_signal(struct tdescr *td, siginfo_t *si,
45 				  ucontext_t *uc)
46 {
47 	ASSERT_GOOD_CONTEXT(uc);
48 
49 	return 1;
50 }
51 
52 struct tdescr tde = {
53 	.name = "Invalid GCS operation",
54 	.descr = "An invalid GCS operation generates the expected signal",
55 	.feats_required = FEAT_GCS,
56 	.timeout = 3,
57 	.sig_ok = SIGSEGV,
58 	.sig_ok_code = SEGV_CPERR,
59 	.sanity_disabled = true,
60 	.trigger = gcs_op_fault_trigger,
61 	.run = gcs_op_fault_signal,
62 };
63