selftests/powerpc: Add scv versions of the basic TM syscall tests

The basic TM vs syscall test code hard codes an sc instruction for the
system call, which fails to cover scv even when the userspace libc has
support for it.

Duplicate the tests with hard coded scv variants so both are tested
when possible.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
[mpe: Fix build on old toolchains by using .long for scv]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210903125707.1601269-2-npiggin@gmail.com
This commit is contained in:
Nicholas Piggin 2021-09-03 22:57:07 +10:00 committed by Michael Ellerman
parent b871895b14
commit 5379ef2a60
2 changed files with 65 additions and 8 deletions

View file

@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <ppc-asm.h>
#include <basic_asm.h>
#include <asm/unistd.h>
.text
@ -26,3 +26,38 @@ FUNC_START(getppid_tm_suspended)
1:
li r3, -1
blr
.macro scv level
.long (0x44000001 | (\level) << 5)
.endm
FUNC_START(getppid_scv_tm_active)
PUSH_BASIC_STACK(0)
tbegin.
beq 1f
li r0, __NR_getppid
scv 0
tend.
POP_BASIC_STACK(0)
blr
1:
li r3, -1
POP_BASIC_STACK(0)
blr
FUNC_START(getppid_scv_tm_suspended)
PUSH_BASIC_STACK(0)
tbegin.
beq 1f
li r0, __NR_getppid
tsuspend.
scv 0
tresume.
tend.
POP_BASIC_STACK(0)
blr
1:
li r3, -1
POP_BASIC_STACK(0)
blr

View file

@ -19,23 +19,36 @@
#include "utils.h"
#include "tm.h"
#ifndef PPC_FEATURE2_SCV
#define PPC_FEATURE2_SCV 0x00100000 /* scv syscall */
#endif
extern int getppid_tm_active(void);
extern int getppid_tm_suspended(void);
extern int getppid_scv_tm_active(void);
extern int getppid_scv_tm_suspended(void);
unsigned retries = 0;
#define TEST_DURATION 10 /* seconds */
pid_t getppid_tm(bool suspend)
pid_t getppid_tm(bool scv, 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 (suspend) {
if (scv)
pid = getppid_scv_tm_suspended();
else
pid = getppid_tm_suspended();
} else {
if (scv)
pid = getppid_scv_tm_active();
else
pid = getppid_tm_active();
}
if (pid >= 0)
return pid;
@ -82,15 +95,24 @@ int tm_syscall(void)
* Test a syscall within a suspended transaction and verify
* that it succeeds.
*/
FAIL_IF(getppid_tm(true) == -1); /* Should succeed. */
FAIL_IF(getppid_tm(false, 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(getppid_tm(false, false) != -1); /* Should fail... */
FAIL_IF(!failure_is_persistent()); /* ...persistently... */
FAIL_IF(!failure_is_syscall()); /* ...with code syscall. */
/* Now do it all again with scv if it is available. */
if (have_hwcap2(PPC_FEATURE2_SCV)) {
FAIL_IF(getppid_tm(true, true) == -1); /* Should succeed. */
FAIL_IF(getppid_tm(true, false) != -1); /* Should fail... */
FAIL_IF(!failure_is_persistent()); /* ...persistently... */
FAIL_IF(!failure_is_syscall()); /* ...with code syscall. */
}
gettimeofday(&now, 0);
}