162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright 2016, Cyril Bur, IBM Corp.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Syscalls can be performed provided the transactions are suspended.
662306a36Sopenharmony_ci * The exec() class of syscall is unique as a new process is loaded.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * It makes little sense for after an exec() call for the previously
962306a36Sopenharmony_ci * suspended transaction to still exist.
1062306a36Sopenharmony_ci */
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#define _GNU_SOURCE
1362306a36Sopenharmony_ci#include <errno.h>
1462306a36Sopenharmony_ci#include <inttypes.h>
1562306a36Sopenharmony_ci#include <libgen.h>
1662306a36Sopenharmony_ci#include <pthread.h>
1762306a36Sopenharmony_ci#include <stdio.h>
1862306a36Sopenharmony_ci#include <stdlib.h>
1962306a36Sopenharmony_ci#include <string.h>
2062306a36Sopenharmony_ci#include <unistd.h>
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#include "utils.h"
2362306a36Sopenharmony_ci#include "tm.h"
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_cistatic char *path;
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic int test_exec(void)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	SKIP_IF(!have_htm());
3062306a36Sopenharmony_ci	SKIP_IF(htm_is_synthetic());
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	asm __volatile__(
3362306a36Sopenharmony_ci		"tbegin.;"
3462306a36Sopenharmony_ci		"blt    1f; "
3562306a36Sopenharmony_ci		"tsuspend.;"
3662306a36Sopenharmony_ci		"1: ;"
3762306a36Sopenharmony_ci		: : : "memory");
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	execl(path, "tm-exec", "--child", NULL);
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	/* Shouldn't get here */
4262306a36Sopenharmony_ci	perror("execl() failed");
4362306a36Sopenharmony_ci	return 1;
4462306a36Sopenharmony_ci}
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic int after_exec(void)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	asm __volatile__(
4962306a36Sopenharmony_ci		"tbegin.;"
5062306a36Sopenharmony_ci		"blt    1f;"
5162306a36Sopenharmony_ci		"tsuspend.;"
5262306a36Sopenharmony_ci		"1: ;"
5362306a36Sopenharmony_ci		: : : "memory");
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	FAIL_IF(failure_is_nesting());
5662306a36Sopenharmony_ci	return 0;
5762306a36Sopenharmony_ci}
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ciint main(int argc, char *argv[])
6062306a36Sopenharmony_ci{
6162306a36Sopenharmony_ci	path = argv[0];
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	if (argc > 1 && strcmp(argv[1], "--child") == 0)
6462306a36Sopenharmony_ci		return after_exec();
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci	return test_harness(test_exec, "tm_exec");
6762306a36Sopenharmony_ci}
68