// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright 2015, Cyril Bur, IBM Corp. * * This test attempts to see if the FPU registers change across a syscall (fork). */ #include #include #include #include #include #include #include #include "utils.h" #include "fpu.h" extern int test_fpu(double *darray, pid_t *pid); double darray[32]; int syscall_fpu(void) { pid_t fork_pid; int i; int ret; int child_ret; randomise_darray(darray, ARRAY_SIZE(darray)); for (i = 0; i < 1000; i++) { /* test_fpu will fork() */ ret = test_fpu(darray, &fork_pid); if (fork_pid == -1) return -1; if (fork_pid == 0) exit(ret); waitpid(fork_pid, &child_ret, 0); if (ret || child_ret) return 1; } return 0; } int test_syscall_fpu(void) { /* * Setup an environment with much context switching */ pid_t pid2; pid_t pid = fork(); int ret; int child_ret; FAIL_IF(pid == -1); pid2 = fork(); /* Can't FAIL_IF(pid2 == -1); because already forked once */ if (pid2 == -1) { /* * Couldn't fork, ensure test is a fail */ child_ret = ret = 1; } else { ret = syscall_fpu(); if (pid2) waitpid(pid2, &child_ret, 0); else exit(ret); } ret |= child_ret; if (pid) waitpid(pid, &child_ret, 0); else exit(ret); FAIL_IF(ret || child_ret); return 0; } int main(int argc, char *argv[]) { return test_harness(test_syscall_fpu, "syscall_fpu"); }