1 /* 2 * Copyright 2015, Michael Neuling, IBM Corp. 3 * Licensed under GPLv2. 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 39 pid = fork(); 40 if (pid < 0) 41 exit(1); 42 43 if (pid) { /* Parent */ 44 /* 45 * It's likely the whole machine will crash here so if 46 * the child ever exits, we are good. 47 */ 48 wait(NULL); 49 return 0; 50 } 51 52 /* 53 * The flow here is: 54 * 1) register a signal handler (so signal delievery occurs) 55 * 2) make stack pointer (r1) = NULL 56 * 3) start transaction 57 * 4) cause segv 58 */ 59 if (signal(SIGSEGV, signal_segv) == SIG_ERR) 60 exit(1); 61 asm volatile("li 1, 0 ;" /* stack ptr == NULL */ 62 "1:" 63 "tbegin.;" 64 "beq 1b ;" /* retry forever */ 65 "tsuspend.;" 66 "ld 2, 0(1) ;" /* trigger segv" */ 67 : : : "memory"); 68 69 /* This should never get here due to above segv */ 70 return 1; 71 } 72 73 int main(void) 74 { 75 return test_harness(tm_signal_stack, "tm_signal_stack"); 76 } 77