root/tools/testing/selftests/powerpc/tm/tm-sigreturn.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. handler
  2. tm_sigreturn
  3. main

   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 }

/* [<][>][^][v][top][bottom][index][help] */