1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright 2015, Michael Neuling, IBM Corp. 4 * 5 * Test the kernel's signal delievery code to ensure that we don't 6 * trelaim twice in the kernel signal delivery code. This can happen 7 * if we trigger a signal when in a transaction and the stack pointer 8 * is bogus. 9 * 10 * This test case registers a SEGV handler, sets the stack pointer 11 * (r1) to NULL, starts a transaction and then generates a SEGV. The 12 * SEGV should be handled but we exit here as the stack pointer is 13 * invalid and hance we can't sigreturn. We only need to check that 14 * this flow doesn't crash the kernel. 15 */ 16 17 #include <unistd.h> 18 #include <sys/types.h> 19 #include <sys/wait.h> 20 #include <stdlib.h> 21 #include <stdio.h> 22 #include <signal.h> 23 24 #include "utils.h" 25 #include "tm.h" 26 27 void signal_segv(int signum) 28 { 29 /* This should never actually run since stack is foobar */ 30 exit(1); 31 } 32 33 int tm_signal_stack() 34 { 35 int pid; 36 37 SKIP_IF(!have_htm()); 38 SKIP_IF(htm_is_synthetic()); 39 40 pid = fork(); 41 if (pid < 0) 42 exit(1); 43 44 if (pid) { /* Parent */ 45 /* 46 * It's likely the whole machine will crash here so if 47 * the child ever exits, we are good. 48 */ 49 wait(NULL); 50 return 0; 51 } 52 53 /* 54 * The flow here is: 55 * 1) register a signal handler (so signal delievery occurs) 56 * 2) make stack pointer (r1) = NULL 57 * 3) start transaction 58 * 4) cause segv 59 */ 60 if (signal(SIGSEGV, signal_segv) == SIG_ERR) 61 exit(1); 62 asm volatile("li 1, 0 ;" /* stack ptr == NULL */ 63 "1:" 64 "tbegin.;" 65 "beq 1b ;" /* retry forever */ 66 "tsuspend.;" 67 "ld 2, 0(1) ;" /* trigger segv" */ 68 : : : "memory"); 69 70 /* This should never get here due to above segv */ 71 return 1; 72 } 73 74 int main(void) 75 { 76 return test_harness(tm_signal_stack, "tm_signal_stack"); 77 } 78