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.
4 // Copyright 2015-2023 Arm Ltd
6 #include <asm/unistd.h>
23 #define SA_NODEFER 1073741824
25 #define ucontext_regs 184
27 #define PR_SET_SHADOW_STACK_STATUS 75
28 # define PR_SHADOW_STACK_ENABLE (1UL << 0)
30 #define GCSPR_EL0 S3_3_C2_C5_1
34 .type \name, @function
40 // Print a single character x0 to stdout
45 mov x0, #1 // STDOUT_FILENO
56 // Print a NUL-terminated string starting at address x0 to stdout
67 1: mov w0, #1 // STDOUT_FILENO
75 // Utility macro to print a literal string
78 .pushsection .rodata.str1.1, "aMS", @progbits, 1
79 .L__puts_literal\@: .string "\string"
82 ldr x0, =.L__puts_literal\@
86 // Print an unsigned decimal number x0 to stdout
90 str x30, [sp, #-32]! // Result can't be > 20 digits
93 strb w2, [x1, #-1]! // Write the NUL terminator
96 0: udiv x3, x0, x2 // div-mod loop to generate the digits
105 mov w0, #'0' // Print "0" for 0, not ""
116 // Print an unsigned decimal number x0 to stdout, followed by a newline
129 // Fill x1 bytes starting at x0 with 0.
135 // fall through to memfill
137 // Trivial memory fill: fill x1 bytes starting at address x0 with byte w2
156 str x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!
168 str w6, [x1, #sa_flags]
169 str x5, [x1, #sa_handler]
172 mov x8, #__NR_rt_sigaction
177 puts "sigaction failure\n"
180 1: ldr x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)
185 function tickle_handler
186 // Perhaps collect GCSPR_EL0 here in future?
190 function terminate_handler
194 puts "Terminated by signal "
204 function segv_handler
205 // stash the siginfo_t *
208 // Disable GCS, we don't want additional faults logging things
209 mov x0, PR_SET_SHADOW_STACK_STATUS
218 puts "Got SIGSEGV code "
220 ldr x21, [x20, #si_code]
224 // GCS faults should have si_code SEGV_CPERR
228 puts " (GCS violation)"
238 stp x29, x30, [sp, #-16]!
247 ldp x29, x30, [sp], #16
249 // Do a syscall immediately prior to returning to try to provoke
250 // scheduling and migration at a point where coherency issues
259 // Generate and use two copies so we're changing the GCS contents
266 mov x0, PR_SET_SHADOW_STACK_STATUS
267 mov x1, PR_SHADOW_STACK_ENABLE
275 puts "Failed to enable GCS\n"
280 adr x1, terminate_handler
285 adr x1, tickle_handler
287 orr w2, w2, #SA_NODEFER
293 orr w2, w2, #SA_NODEFER
299 // Small recursion depth so we're frequently flipping between
300 // the two recursors and changing what's on the stack