// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2015, Laurent Dufour, IBM Corp.
*
* Test the kernel's signal returning code to check reclaim is done if the
* sigreturn() is called while in a transaction (suspended since active is
* already dropped trough the system call path).
*
* The kernel must discard the transaction when entering sigreturn, since
* restoring the potential TM SPRS from the signal frame is requiring to not be
* in a transaction.
*/
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include "tm.h"
#include "utils.h"
void handler(int sig)
{
uint64_t ret;
asm __volatile__(
"li 3,1 ;"
"tbegin. ;"
"beq 1f ;"
"li 3,0 ;"
"tsuspend. ;"
"1: ;"
"std%X[ret] 3, %[ret] ;"
: [ret] "=m"(ret)
:
: "memory", "3", "cr0");
if (ret)
exit(1);
/*
* We return from the signal handle while in a suspended transaction
*/
}
int tm_sigreturn(void)
{
struct sigaction sa;
uint64_t ret = 0;
SKIP_IF(!have_htm());
SKIP_IF(htm_is_synthetic());
SKIP_IF(!is_ppc64le());
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGSEGV, &sa, NULL))
exit(1);
asm __volatile__(
"tbegin. ;"
"beq 1f ;"
"li 3,0 ;"
"std 3,0(3) ;" /* trigger SEGV */
"li 3,1 ;"
"std%X[ret] 3,%[ret] ;"
"tend. ;"
"b 2f ;"
"1: ;"
"li 3,2 ;"
"std%X[ret] 3,%[ret] ;"
"2: ;"
: [ret] "=m"(ret)
:
: "memory", "3", "cr0");
if (ret != 2)
exit(1);
exit(0);
}
int main(void)
{
return test_harness(tm_sigreturn, "tm_sigreturn");
}