linux/tools/testing/selftests/powerpc/tm/tm-sigreturn.c
<<
>>
Prefs
   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
  27void 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
  52int 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
  90int main(void)
  91{
  92        return test_harness(tm_sigreturn, "tm_sigreturn");
  93}
  94