Home | History | Annotate | Download | only in tm
      1 // SPDX-License-Identifier: GPL-2.0
      2 
      3 /*
      4  * Copyright 2015, Laurent Dufour, IBM Corp.
      5  *
      6  * Test the kernel's signal returning code to check reclaim is done if the
      7  * sigreturn() is called while in a transaction (suspended since active is
      8  * already dropped trough the system call path).
      9  *
     10  * The kernel must discard the transaction when entering sigreturn, since
     11  * restoring the potential TM SPRS from the signal frame is requiring to not be
     12  * in a transaction.
     13  */
     14 
     15 #include <signal.h>
     16 #include <stdio.h>
     17 #include <stdlib.h>
     18 #include <string.h>
     19 #include <sys/types.h>
     20 #include <sys/wait.h>
     21 #include <unistd.h>
     22 
     23 #include "tm.h"
     24 #include "utils.h"
     25 
     26 
     27 void handler(int sig)
     28 {
     29 	uint64_t ret;
     30 
     31 	asm __volatile__(
     32 		"li             3,1             ;"
     33 		"tbegin.                        ;"
     34 		"beq            1f              ;"
     35 		"li             3,0             ;"
     36 		"tsuspend.                      ;"
     37 		"1:                             ;"
     38 		"std%X[ret]     3, %[ret]       ;"
     39 		: [ret] "=m"(ret)
     40 		:
     41 		: "memory", "3", "cr0");
     42 
     43 	if (ret)
     44 		exit(1);
     45 
     46 	/*
     47 	 * We return from the signal handle while in a suspended transaction
     48 	 */
     49 }
     50 
     51 
     52 int tm_sigreturn(void)
     53 {
     54 	struct sigaction sa;
     55 	uint64_t ret = 0;
     56 
     57 	SKIP_IF(!have_htm());
     58 	SKIP_IF(!is_ppc64le());
     59 
     60 	memset(&sa, 0, sizeof(sa));
     61 	sa.sa_handler = handler;
     62 	sigemptyset(&sa.sa_mask);
     63 
     64 	if (sigaction(SIGSEGV, &sa, NULL))
     65 		exit(1);
     66 
     67 	asm __volatile__(
     68 		"tbegin.                        ;"
     69 		"beq            1f              ;"
     70 		"li             3,0             ;"
     71 		"std            3,0(3)          ;" /* trigger SEGV */
     72 		"li             3,1             ;"
     73 		"std%X[ret]     3,%[ret]        ;"
     74 		"tend.                          ;"
     75 		"b              2f              ;"
     76 		"1:                             ;"
     77 		"li             3,2             ;"
     78 		"std%X[ret]     3,%[ret]        ;"
     79 		"2:                             ;"
     80 		: [ret] "=m"(ret)
     81 		:
     82 		: "memory", "3", "cr0");
     83 
     84 	if (ret != 2)
     85 		exit(1);
     86 
     87 	exit(0);
     88 }
     89 
     90 int main(void)
     91 {
     92 	return test_harness(tm_sigreturn, "tm_sigreturn");
     93 }
     94