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(htm_is_synthetic());
  59        SKIP_IF(!is_ppc64le());
  60
  61        memset(&sa, 0, sizeof(sa));
  62        sa.sa_handler = handler;
  63        sigemptyset(&sa.sa_mask);
  64
  65        if (sigaction(SIGSEGV, &sa, NULL))
  66                exit(1);
  67
  68        asm __volatile__(
  69                "tbegin.                        ;"
  70                "beq            1f              ;"
  71                "li             3,0             ;"
  72                "std            3,0(3)          ;" /* trigger SEGV */
  73                "li             3,1             ;"
  74                "std%X[ret]     3,%[ret]        ;"
  75                "tend.                          ;"
  76                "b              2f              ;"
  77                "1:                             ;"
  78                "li             3,2             ;"
  79                "std%X[ret]     3,%[ret]        ;"
  80                "2:                             ;"
  81                : [ret] "=m"(ret)
  82                :
  83                : "memory", "3", "cr0");
  84
  85        if (ret != 2)
  86                exit(1);
  87
  88        exit(0);
  89}
  90
  91int main(void)
  92{
  93        return test_harness(tm_sigreturn, "tm_sigreturn");
  94}
  95