Commit e5d00aaa authored by Michael Ellerman's avatar Michael Ellerman

selftests/powerpc: Check all FPRs in fpu_preempt

There's a selftest that checks FPRs aren't corrupted by preemption, or
just process scheduling. However it only checks the non-volatile FPRs,
meaning corruption of the volatile FPRs could go undetected.

The check_fpu function it calls is used by several other tests, so for
now add a new routine to check all the FPRs. Increase the size of the
array of FPRs to 32, and initialise them all with random values.
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/20231128132748.1990179-2-mpe@ellerman.id.au
parent 9dbd5927
...@@ -66,6 +66,40 @@ FUNC_START(check_fpu) ...@@ -66,6 +66,40 @@ FUNC_START(check_fpu)
li r3,0 # Success!!! li r3,0 # Success!!!
1: blr 1: blr
// int check_all_fprs(double darray[32])
FUNC_START(check_all_fprs)
PUSH_BASIC_STACK(8)
mr r4, r3 // r4 = darray
li r3, 1 // prepare for failure
stfd f31, STACK_FRAME_LOCAL(0, 0)(sp) // backup f31
// Check regs f0-f30, using f31 as scratch
.set i, 0
.rept 31
lfd f31, (8 * i)(r4) // load expected value
fcmpu cr0, i, f31 // compare
bne cr0, 1f // bail if mismatch
.set i, i + 1
.endr
lfd f31, STACK_FRAME_LOCAL(0, 0)(sp) // reload f31
stfd f30, STACK_FRAME_LOCAL(0, 0)(sp) // backup f30
lfd f30, (8 * 31)(r4) // load expected value of f31
fcmpu cr0, f30, f31 // compare
bne cr0, 1f // bail if mismatch
lfd f30, STACK_FRAME_LOCAL(0, 0)(sp) // reload f30
// Success
li r3, 0
1: POP_BASIC_STACK(8)
blr
FUNC_END(check_all_fprs)
FUNC_START(test_fpu) FUNC_START(test_fpu)
# r3 holds pointer to where to put the result of fork # r3 holds pointer to where to put the result of fork
# r4 holds pointer to the pid # r4 holds pointer to the pid
...@@ -104,8 +138,8 @@ FUNC_START(preempt_fpu) ...@@ -104,8 +138,8 @@ FUNC_START(preempt_fpu)
std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting
std r5,STACK_FRAME_PARAM(2)(sp) # int *running std r5,STACK_FRAME_PARAM(2)(sp) # int *running
bl load_fpu // Load FPRs with expected values
nop OP_REGS lfd, 8, 0, 31, r3
sync sync
# Atomic DEC # Atomic DEC
...@@ -116,8 +150,7 @@ FUNC_START(preempt_fpu) ...@@ -116,8 +150,7 @@ FUNC_START(preempt_fpu)
bne- 1b bne- 1b
2: ld r3,STACK_FRAME_PARAM(0)(sp) 2: ld r3,STACK_FRAME_PARAM(0)(sp)
bl check_fpu bl check_all_fprs
nop
cmpdi r3,0 cmpdi r3,0
bne 3f bne 3f
ld r4,STACK_FRAME_PARAM(2)(sp) ld r4,STACK_FRAME_PARAM(2)(sp)
......
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
/* /*
* Copyright 2015, Cyril Bur, IBM Corp. * Copyright 2015, Cyril Bur, IBM Corp.
* Copyright 2023, Michael Ellerman, IBM Corp.
* *
* This test attempts to see if the FPU registers change across preemption. * This test attempts to see if the FPU registers change across preemption.
* Two things should be noted here a) The check_fpu function in asm only checks * There is no way to be sure preemption happened so this test just uses many
* the non volatile registers as it is reused from the syscall test b) There is * threads and a long wait. As such, a successful test doesn't mean much but
* no way to be sure preemption happened so this test just uses many threads * a failure is bad.
* and a long wait. As such, a successful test doesn't mean much but a failure
* is bad.
*/ */
#include <stdio.h> #include <stdio.h>
...@@ -30,9 +29,7 @@ ...@@ -30,9 +29,7 @@
#define THREAD_FACTOR 8 #define THREAD_FACTOR 8
__thread double darray[] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, __thread double darray[32];
1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0,
2.1};
int threads_starting; int threads_starting;
int running; int running;
...@@ -45,7 +42,7 @@ void *preempt_fpu_c(void *p) ...@@ -45,7 +42,7 @@ void *preempt_fpu_c(void *p)
int i; int i;
srand(pthread_self()); srand(pthread_self());
for (i = 0; i < 21; i++) for (i = 0; i < ARRAY_SIZE(darray); i++)
darray[i] = rand(); darray[i] = rand();
rc = preempt_fpu(darray, &threads_starting, &running); rc = preempt_fpu(darray, &threads_starting, &running);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment