File Index
Files and directories
Sign in
FILE

gcs-stress-thread.S

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/arm64/gcs/gcs-stress-thread.S GAS
  1// Program that loops for ever doing lots of recursions and system calls,
  2// intended to be used as part of a stress test for GCS context switching.
  3//
  4// Copyright 2015-2023 Arm Ltd
  5
  6#include <asm/unistd.h>
  7
  8#define sa_sz 32
  9#define sa_flags 8
 10#define sa_handler 0
 11#define sa_mask_sz 8
 12
 13#define si_code 8
 14
 15#define SIGINT 2
 16#define SIGABRT 6
 17#define SIGUSR1 10
 18#define SIGSEGV 11
 19#define SIGUSR2 12
 20#define SIGTERM 15
 21#define SEGV_CPERR 10
 22
 23#define SA_NODEFER 1073741824
 24#define SA_SIGINFO 4
 25#define ucontext_regs 184
 26
 27#define PR_SET_SHADOW_STACK_STATUS      75
 28# define PR_SHADOW_STACK_ENABLE         (1UL << 0)
 29
 30#define	GCSPR_EL0 S3_3_C2_C5_1
 31
 32.macro function name
 33	.macro endfunction
 34		.type \name, @function
 35		.purgem endfunction
 36	.endm
 37\name:
 38.endm
 39
 40// Print a single character x0 to stdout
 41// Clobbers x0-x2,x8
 42function putc
 43	str	x0, [sp, #-16]!
 44
 45	mov	x0, #1			// STDOUT_FILENO
 46	mov	x1, sp
 47	mov	x2, #1
 48	mov	x8, #__NR_write
 49	svc	#0
 50
 51	add	sp, sp, #16
 52	ret
 53endfunction
 54.globl	putc
 55
 56// Print a NUL-terminated string starting at address x0 to stdout
 57// Clobbers x0-x3,x8
 58function puts
 59	mov	x1, x0
 60
 61	mov	x2, #0
 620:	ldrb	w3, [x0], #1
 63	cbz	w3, 1f
 64	add	x2, x2, #1
 65	b	0b
 66
 671:	mov	w0, #1			// STDOUT_FILENO
 68	mov	x8, #__NR_write
 69	svc	#0
 70
 71	ret
 72endfunction
 73.globl	puts
 74
 75// Utility macro to print a literal string
 76// Clobbers x0-x4,x8
 77.macro puts string
 78	.pushsection .rodata.str1.1, "aMS", @progbits, 1
 79.L__puts_literal\@: .string "\string"
 80	.popsection
 81
 82	ldr	x0, =.L__puts_literal\@
 83	bl	puts
 84.endm
 85
 86// Print an unsigned decimal number x0 to stdout
 87// Clobbers x0-x4,x8
 88function putdec
 89	mov	x1, sp
 90	str	x30, [sp, #-32]!	// Result can't be > 20 digits
 91
 92	mov	x2, #0
 93	strb	w2, [x1, #-1]!		// Write the NUL terminator
 94
 95	mov	x2, #10
 960:	udiv	x3, x0, x2		// div-mod loop to generate the digits
 97	msub	x0, x3, x2, x0
 98	add	w0, w0, #'0'
 99	strb	w0, [x1, #-1]!
100	mov	x0, x3
101	cbnz	x3, 0b
102
103	ldrb	w0, [x1]
104	cbnz	w0, 1f
105	mov	w0, #'0'		// Print "0" for 0, not ""
106	strb	w0, [x1, #-1]!
107
1081:	mov	x0, x1
109	bl	puts
110
111	ldr	x30, [sp], #32
112	ret
113endfunction
114.globl	putdec
115
116// Print an unsigned decimal number x0 to stdout, followed by a newline
117// Clobbers x0-x5,x8
118function putdecn
119	mov	x5, x30
120
121	bl	putdec
122	mov	x0, #'\n'
123	bl	putc
124
125	ret	x5
126endfunction
127.globl	putdecn
128
129// Fill x1 bytes starting at x0 with 0.
130// Clobbers x1, x2.
131function memclr
132	mov	w2, #0
133endfunction
134.globl	memclr
135	// fall through to memfill
136
137// Trivial memory fill: fill x1 bytes starting at address x0 with byte w2
138// Clobbers x1
139function memfill
140	cmp	x1, #0
141	b.eq	1f
142
1430:	strb	w2, [x0], #1
144	subs	x1, x1, #1
145	b.ne	0b
146
1471:	ret
148endfunction
149.globl	memfill
150
151// w0: signal number
152// x1: sa_action
153// w2: sa_flags
154// Clobbers x0-x6,x8
155function setsignal
156	str	x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!
157
158	mov	w4, w0
159	mov	x5, x1
160	mov	w6, w2
161
162	add	x0, sp, #16
163	mov	x1, #sa_sz
164	bl	memclr
165
166	mov	w0, w4
167	add	x1, sp, #16
168	str	w6, [x1, #sa_flags]
169	str	x5, [x1, #sa_handler]
170	mov	x2, #0
171	mov	x3, #sa_mask_sz
172	mov	x8, #__NR_rt_sigaction
173	svc	#0
174
175	cbz	w0, 1f
176
177	puts	"sigaction failure\n"
178	b	abort
179
1801:	ldr	x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)
181	ret
182endfunction
183
184
185function tickle_handler
186	// Perhaps collect GCSPR_EL0 here in future?
187	ret
188endfunction
189
190function terminate_handler
191	mov	w21, w0
192	mov	x20, x2
193
194	puts	"Terminated by signal "
195	mov	w0, w21
196	bl	putdec
197	puts	", no error\n"
198
199	mov	x0, #0
200	mov	x8, #__NR_exit
201	svc	#0
202endfunction
203
204function segv_handler
205	// stash the siginfo_t *
206	mov	x20, x1
207
208	// Disable GCS, we don't want additional faults logging things
209	mov	x0, PR_SET_SHADOW_STACK_STATUS
210	mov	x1, xzr
211	mov	x2, xzr
212	mov	x3, xzr
213	mov	x4, xzr
214	mov	x5, xzr
215	mov	x8, #__NR_prctl
216	svc	#0
217
218	puts	"Got SIGSEGV code "
219
220	ldr	x21, [x20, #si_code]
221	mov	x0, x21
222	bl	putdec
223
224	// GCS faults should have si_code SEGV_CPERR
225	cmp	x21, #SEGV_CPERR
226	bne	1f
227
228	puts	" (GCS violation)"
2291:
230	mov	x0, '\n'
231	bl	putc
232	b	abort
233endfunction
234
235// Recurse x20 times
236.macro recurse id
237function recurse\id
238	stp	x29, x30, [sp, #-16]!
239	mov	x29, sp
240
241	cmp	x20, 0
242	beq	1f
243	sub	x20, x20, 1
244	bl	recurse\id
245
2461:
247	ldp	x29, x30, [sp], #16
248
249	// Do a syscall immediately prior to returning to try to provoke
250	// scheduling and migration at a point where coherency issues
251	// might trigger.
252	mov	x8, #__NR_getpid
253	svc	#0
254
255	ret
256endfunction
257.endm
258
259// Generate and use two copies so we're changing the GCS contents
260recurse 1
261recurse 2
262
263.globl _start
264function _start
265	// Run with GCS
266	mov	x0, PR_SET_SHADOW_STACK_STATUS
267	mov	x1, PR_SHADOW_STACK_ENABLE
268	mov	x2, xzr
269	mov	x3, xzr
270	mov	x4, xzr
271	mov	x5, xzr
272	mov	x8, #__NR_prctl
273	svc	#0
274	cbz	x0, 1f
275	puts	"Failed to enable GCS\n"
276	b	abort
2771:
278
279	mov	w0, #SIGTERM
280	adr	x1, terminate_handler
281	mov	w2, #SA_SIGINFO
282	bl	setsignal
283
284	mov	w0, #SIGUSR1
285	adr	x1, tickle_handler
286	mov	w2, #SA_SIGINFO
287	orr	w2, w2, #SA_NODEFER
288	bl	setsignal
289
290	mov	w0, #SIGSEGV
291	adr	x1, segv_handler
292	mov	w2, #SA_SIGINFO
293	orr	w2, w2, #SA_NODEFER
294	bl	setsignal
295
296	puts	"Running\n"
297
298loop:
299	// Small recursion depth so we're frequently flipping between
300	// the two recursors and changing what's on the stack
301	mov	x20, #5
302	bl	recurse1
303	mov	x20, #5
304	bl	recurse2
305	b	loop
306endfunction
307
308abort:
309	mov	x0, #255
310	mov	x8, #__NR_exit
311	svc	#0
~/ Read-only file preview.