Home | History | Annotate | Download | only in math
      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 VMX registers change across a syscall (fork).
     10  */
     11 
     12 #include <altivec.h>
     13 #include <stdio.h>
     14 #include <unistd.h>
     15 #include <sys/syscall.h>
     16 #include <sys/time.h>
     17 #include <stdlib.h>
     18 #include <sys/types.h>
     19 #include <sys/wait.h>
     20 #include "utils.h"
     21 
     22 vector int varray[] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10,11,12},
     23 	{13,14,15,16},{17,18,19,20},{21,22,23,24},
     24 	{25,26,27,28},{29,30,31,32},{33,34,35,36},
     25 	{37,38,39,40},{41,42,43,44},{45,46,47,48}};
     26 
     27 extern int test_vmx(vector int *varray, pid_t *pid);
     28 
     29 int vmx_syscall(void)
     30 {
     31 	pid_t fork_pid;
     32 	int i;
     33 	int ret;
     34 	int child_ret;
     35 	for (i = 0; i < 1000; i++) {
     36 		/* test_vmx will fork() */
     37 		ret = test_vmx(varray, &fork_pid);
     38 		if (fork_pid == -1)
     39 			return -1;
     40 		if (fork_pid == 0)
     41 			exit(ret);
     42 		waitpid(fork_pid, &child_ret, 0);
     43 		if (ret || child_ret)
     44 			return 1;
     45 	}
     46 
     47 	return 0;
     48 }
     49 
     50 int test_vmx_syscall(void)
     51 {
     52 	/*
     53 	 * Setup an environment with much context switching
     54 	 */
     55 	pid_t pid2;
     56 	pid_t pid = fork();
     57 	int ret;
     58 	int child_ret;
     59 	FAIL_IF(pid == -1);
     60 
     61 	pid2 = fork();
     62 	ret = vmx_syscall();
     63 	/* Can't FAIL_IF(pid2 == -1); because we've already forked */
     64 	if (pid2 == -1) {
     65 		/*
     66 		 * Couldn't fork, ensure child_ret is set and is a fail
     67 		 */
     68 		ret = child_ret = 1;
     69 	} else {
     70 		if (pid2)
     71 			waitpid(pid2, &child_ret, 0);
     72 		else
     73 			exit(ret);
     74 	}
     75 
     76 	ret |= child_ret;
     77 
     78 	if (pid)
     79 		waitpid(pid, &child_ret, 0);
     80 	else
     81 		exit(ret);
     82 
     83 	FAIL_IF(ret || child_ret);
     84 	return 0;
     85 }
     86 
     87 int main(int argc, char *argv[])
     88 {
     89 	return test_harness(test_vmx_syscall, "vmx_syscall");
     90 
     91 }
     92