89 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright 2015, Cyril Bur, IBM Corp.4 *5 * This test attempts to see if the FPU registers change across a syscall (fork).6 */7 8#include <stdio.h>9#include <unistd.h>10#include <sys/syscall.h>11#include <sys/time.h>12#include <sys/types.h>13#include <sys/wait.h>14#include <stdlib.h>15 16#include "utils.h"17#include "fpu.h"18 19extern int test_fpu(double *darray, pid_t *pid);20 21double darray[32];22 23int syscall_fpu(void)24{25 pid_t fork_pid;26 int i;27 int ret;28 int child_ret;29 30 randomise_darray(darray, ARRAY_SIZE(darray));31 32 for (i = 0; i < 1000; i++) {33 /* test_fpu will fork() */34 ret = test_fpu(darray, &fork_pid);35 if (fork_pid == -1)36 return -1;37 if (fork_pid == 0)38 exit(ret);39 waitpid(fork_pid, &child_ret, 0);40 if (ret || child_ret)41 return 1;42 }43 44 return 0;45}46 47int test_syscall_fpu(void)48{49 /*50 * Setup an environment with much context switching51 */52 pid_t pid2;53 pid_t pid = fork();54 int ret;55 int child_ret;56 FAIL_IF(pid == -1);57 58 pid2 = fork();59 /* Can't FAIL_IF(pid2 == -1); because already forked once */60 if (pid2 == -1) {61 /*62 * Couldn't fork, ensure test is a fail63 */64 child_ret = ret = 1;65 } else {66 ret = syscall_fpu();67 if (pid2)68 waitpid(pid2, &child_ret, 0);69 else70 exit(ret);71 }72 73 ret |= child_ret;74 75 if (pid)76 waitpid(pid, &child_ret, 0);77 else78 exit(ret);79 80 FAIL_IF(ret || child_ret);81 return 0;82}83 84int main(int argc, char *argv[])85{86 return test_harness(test_syscall_fpu, "syscall_fpu");87 88}89