1 /* 2 * Copyright 2015, Cyril Bur, IBM Corp. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 * 9 * This test attempts to see if the FPU registers change across a syscall (fork). 10 */ 11 12 #include <stdio.h> 13 #include <unistd.h> 14 #include <sys/syscall.h> 15 #include <sys/time.h> 16 #include <sys/types.h> 17 #include <sys/wait.h> 18 #include <stdlib.h> 19 20 #include "utils.h" 21 22 extern int test_fpu(double *darray, pid_t *pid); 23 24 double darray[] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 25 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 26 2.1}; 27 28 int syscall_fpu(void) 29 { 30 pid_t fork_pid; 31 int i; 32 int ret; 33 int child_ret; 34 for (i = 0; i < 1000; i++) { 35 /* test_fpu will fork() */ 36 ret = test_fpu(darray, &fork_pid); 37 if (fork_pid == -1) 38 return -1; 39 if (fork_pid == 0) 40 exit(ret); 41 waitpid(fork_pid, &child_ret, 0); 42 if (ret || child_ret) 43 return 1; 44 } 45 46 return 0; 47 } 48 49 int test_syscall_fpu(void) 50 { 51 /* 52 * Setup an environment with much context switching 53 */ 54 pid_t pid2; 55 pid_t pid = fork(); 56 int ret; 57 int child_ret; 58 FAIL_IF(pid == -1); 59 60 pid2 = fork(); 61 /* Can't FAIL_IF(pid2 == -1); because already forked once */ 62 if (pid2 == -1) { 63 /* 64 * Couldn't fork, ensure test is a fail 65 */ 66 child_ret = ret = 1; 67 } else { 68 ret = syscall_fpu(); 69 if (pid2) 70 waitpid(pid2, &child_ret, 0); 71 else 72 exit(ret); 73 } 74 75 ret |= child_ret; 76 77 if (pid) 78 waitpid(pid, &child_ret, 0); 79 else 80 exit(ret); 81 82 FAIL_IF(ret || child_ret); 83 return 0; 84 } 85 86 int main(int argc, char *argv[]) 87 { 88 return test_harness(test_syscall_fpu, "syscall_fpu"); 89 90 } 91