forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
selftests/powerpc: Add TM signal with invalid stack test
Test the kernels signal generation code to ensure it can handle an invalid stack pointer when transactional. Signed-off-by: Michael Neuling <[email protected]> Tested-by: Anshuman Khandual <[email protected]> [mpe: Skip if we don't have TM] Signed-off-by: Michael Ellerman <[email protected]>
- Loading branch information
Showing
3 changed files
with
78 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
tm-resched-dscr | ||
tm-syscall | ||
tm-signal-msr-resv | ||
tm-signal-stack |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* Copyright 2015, Michael Neuling, IBM Corp. | ||
* Licensed under GPLv2. | ||
* | ||
* Test the kernel's signal delievery code to ensure that we don't | ||
* trelaim twice in the kernel signal delivery code. This can happen | ||
* if we trigger a signal when in a transaction and the stack pointer | ||
* is bogus. | ||
* | ||
* This test case registers a SEGV handler, sets the stack pointer | ||
* (r1) to NULL, starts a transaction and then generates a SEGV. The | ||
* SEGV should be handled but we exit here as the stack pointer is | ||
* invalid and hance we can't sigreturn. We only need to check that | ||
* this flow doesn't crash the kernel. | ||
*/ | ||
|
||
#include <unistd.h> | ||
#include <sys/types.h> | ||
#include <sys/wait.h> | ||
#include <stdlib.h> | ||
#include <stdio.h> | ||
#include <signal.h> | ||
|
||
#include "utils.h" | ||
#include "tm.h" | ||
|
||
void signal_segv(int signum) | ||
{ | ||
/* This should never actually run since stack is foobar */ | ||
exit(1); | ||
} | ||
|
||
int tm_signal_stack() | ||
{ | ||
int pid; | ||
|
||
SKIP_IF(!have_htm()); | ||
|
||
pid = fork(); | ||
if (pid < 0) | ||
exit(1); | ||
|
||
if (pid) { /* Parent */ | ||
/* | ||
* It's likely the whole machine will crash here so if | ||
* the child ever exits, we are good. | ||
*/ | ||
wait(NULL); | ||
return 0; | ||
} | ||
|
||
/* | ||
* The flow here is: | ||
* 1) register a signal handler (so signal delievery occurs) | ||
* 2) make stack pointer (r1) = NULL | ||
* 3) start transaction | ||
* 4) cause segv | ||
*/ | ||
if (signal(SIGSEGV, signal_segv) == SIG_ERR) | ||
exit(1); | ||
asm volatile("li 1, 0 ;" /* stack ptr == NULL */ | ||
"1:" | ||
".long 0x7C00051D ;" /* tbegin */ | ||
"beq 1b ;" /* retry forever */ | ||
".long 0x7C0005DD ; ;" /* tsuspend */ | ||
"ld 2, 0(1) ;" /* trigger segv" */ | ||
: : : "memory"); | ||
|
||
/* This should never get here due to above segv */ | ||
return 1; | ||
} | ||
|
||
int main(void) | ||
{ | ||
return test_harness(tm_signal_stack, "tm_signal_stack"); | ||
} |