Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 
0003 /*
0004  * Copyright 2015, Laurent Dufour, IBM Corp.
0005  *
0006  * Test the kernel's signal returning code to check reclaim is done if the
0007  * sigreturn() is called while in a transaction (suspended since active is
0008  * already dropped trough the system call path).
0009  *
0010  * The kernel must discard the transaction when entering sigreturn, since
0011  * restoring the potential TM SPRS from the signal frame is requiring to not be
0012  * in a transaction.
0013  */
0014 
0015 #include <signal.h>
0016 #include <stdio.h>
0017 #include <stdlib.h>
0018 #include <string.h>
0019 #include <sys/types.h>
0020 #include <sys/wait.h>
0021 #include <unistd.h>
0022 
0023 #include "tm.h"
0024 #include "utils.h"
0025 
0026 
0027 void handler(int sig)
0028 {
0029     uint64_t ret;
0030 
0031     asm __volatile__(
0032         "li             3,1             ;"
0033         "tbegin.                        ;"
0034         "beq            1f              ;"
0035         "li             3,0             ;"
0036         "tsuspend.                      ;"
0037         "1:                             ;"
0038         "std%X[ret]     3, %[ret]       ;"
0039         : [ret] "=m"(ret)
0040         :
0041         : "memory", "3", "cr0");
0042 
0043     if (ret)
0044         exit(1);
0045 
0046     /*
0047      * We return from the signal handle while in a suspended transaction
0048      */
0049 }
0050 
0051 
0052 int tm_sigreturn(void)
0053 {
0054     struct sigaction sa;
0055     uint64_t ret = 0;
0056 
0057     SKIP_IF(!have_htm());
0058     SKIP_IF(htm_is_synthetic());
0059     SKIP_IF(!is_ppc64le());
0060 
0061     memset(&sa, 0, sizeof(sa));
0062     sa.sa_handler = handler;
0063     sigemptyset(&sa.sa_mask);
0064 
0065     if (sigaction(SIGSEGV, &sa, NULL))
0066         exit(1);
0067 
0068     asm __volatile__(
0069         "tbegin.                        ;"
0070         "beq            1f              ;"
0071         "li             3,0             ;"
0072         "std            3,0(3)          ;" /* trigger SEGV */
0073         "li             3,1             ;"
0074         "std%X[ret]     3,%[ret]        ;"
0075         "tend.                          ;"
0076         "b              2f              ;"
0077         "1:                             ;"
0078         "li             3,2             ;"
0079         "std%X[ret]     3,%[ret]        ;"
0080         "2:                             ;"
0081         : [ret] "=m"(ret)
0082         :
0083         : "memory", "3", "cr0");
0084 
0085     if (ret != 2)
0086         exit(1);
0087 
0088     exit(0);
0089 }
0090 
0091 int main(void)
0092 {
0093     return test_harness(tm_sigreturn, "tm_sigreturn");
0094 }