mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2025-12-10 00:17:18 +00:00
Transactional Memory was removed from the architecture in ISA v3.1. For threads running in P8/P9 compatibility mode on P10 a synthetic TM implementation is provided. In this implementation, tbegin. always sets cr0 eq meaning the abort handler is always called. This is not an issue as users of TM are expected to have a fallback non transactional way to make forward progress in the abort handler. The TEXASR indicates if a transaction failure is due to a synthetic implementation. Some of the TM self tests need a non-degenerate TM implementation for their testing to be meaningful so check for a synthetic implementation and skip the test if so. Signed-off-by: Jordan Niethe <jniethe5@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20210729041317.366612-2-jniethe5@gmail.com
107 lines
2.4 KiB
C
107 lines
2.4 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Copyright 2015, Sam Bobroff, IBM Corp.
|
|
*
|
|
* Test the kernel's system call code to ensure that a system call
|
|
* made from within an active HTM transaction is aborted with the
|
|
* correct failure code.
|
|
* Conversely, ensure that a system call made from within a
|
|
* suspended transaction can succeed.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <sys/syscall.h>
|
|
#include <asm/tm.h>
|
|
#include <sys/time.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "utils.h"
|
|
#include "tm.h"
|
|
|
|
extern int getppid_tm_active(void);
|
|
extern int getppid_tm_suspended(void);
|
|
|
|
unsigned retries = 0;
|
|
|
|
#define TEST_DURATION 10 /* seconds */
|
|
|
|
pid_t getppid_tm(bool suspend)
|
|
{
|
|
int i;
|
|
pid_t pid;
|
|
|
|
for (i = 0; i < TM_RETRIES; i++) {
|
|
if (suspend)
|
|
pid = getppid_tm_suspended();
|
|
else
|
|
pid = getppid_tm_active();
|
|
|
|
if (pid >= 0)
|
|
return pid;
|
|
|
|
if (failure_is_persistent()) {
|
|
if (failure_is_syscall())
|
|
return -1;
|
|
|
|
printf("Unexpected persistent transaction failure.\n");
|
|
printf("TEXASR 0x%016lx, TFIAR 0x%016lx.\n",
|
|
__builtin_get_texasr(), __builtin_get_tfiar());
|
|
exit(-1);
|
|
}
|
|
|
|
retries++;
|
|
}
|
|
|
|
printf("Exceeded limit of %d temporary transaction failures.\n", TM_RETRIES);
|
|
printf("TEXASR 0x%016lx, TFIAR 0x%016lx.\n",
|
|
__builtin_get_texasr(), __builtin_get_tfiar());
|
|
|
|
exit(-1);
|
|
}
|
|
|
|
int tm_syscall(void)
|
|
{
|
|
unsigned count = 0;
|
|
struct timeval end, now;
|
|
|
|
SKIP_IF(!have_htm_nosc());
|
|
SKIP_IF(htm_is_synthetic());
|
|
|
|
setbuf(stdout, NULL);
|
|
|
|
printf("Testing transactional syscalls for %d seconds...\n", TEST_DURATION);
|
|
|
|
gettimeofday(&end, NULL);
|
|
now.tv_sec = TEST_DURATION;
|
|
now.tv_usec = 0;
|
|
timeradd(&end, &now, &end);
|
|
|
|
for (count = 0; timercmp(&now, &end, <); count++) {
|
|
/*
|
|
* Test a syscall within a suspended transaction and verify
|
|
* that it succeeds.
|
|
*/
|
|
FAIL_IF(getppid_tm(true) == -1); /* Should succeed. */
|
|
|
|
/*
|
|
* Test a syscall within an active transaction and verify that
|
|
* it fails with the correct failure code.
|
|
*/
|
|
FAIL_IF(getppid_tm(false) != -1); /* Should fail... */
|
|
FAIL_IF(!failure_is_persistent()); /* ...persistently... */
|
|
FAIL_IF(!failure_is_syscall()); /* ...with code syscall. */
|
|
gettimeofday(&now, 0);
|
|
}
|
|
|
|
printf("%d active and suspended transactions behaved correctly.\n", count);
|
|
printf("(There were %d transaction retries.)\n", retries);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
return test_harness(tm_syscall, "tm_syscall");
|
|
}
|