fpu_syscall.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  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. #include <stdio.h>
  8. #include <unistd.h>
  9. #include <sys/syscall.h>
  10. #include <sys/time.h>
  11. #include <sys/types.h>
  12. #include <sys/wait.h>
  13. #include <stdlib.h>
  14. #include "utils.h"
  15. #include "fpu.h"
  16. extern int test_fpu(double *darray, pid_t *pid);
  17. double darray[32];
  18. int syscall_fpu(void)
  19. {
  20. pid_t fork_pid;
  21. int i;
  22. int ret;
  23. int child_ret;
  24. randomise_darray(darray, ARRAY_SIZE(darray));
  25. for (i = 0; i < 1000; i++) {
  26. /* test_fpu will fork() */
  27. ret = test_fpu(darray, &fork_pid);
  28. if (fork_pid == -1)
  29. return -1;
  30. if (fork_pid == 0)
  31. exit(ret);
  32. waitpid(fork_pid, &child_ret, 0);
  33. if (ret || child_ret)
  34. return 1;
  35. }
  36. return 0;
  37. }
  38. int test_syscall_fpu(void)
  39. {
  40. /*
  41. * Setup an environment with much context switching
  42. */
  43. pid_t pid2;
  44. pid_t pid = fork();
  45. int ret;
  46. int child_ret;
  47. FAIL_IF(pid == -1);
  48. pid2 = fork();
  49. /* Can't FAIL_IF(pid2 == -1); because already forked once */
  50. if (pid2 == -1) {
  51. /*
  52. * Couldn't fork, ensure test is a fail
  53. */
  54. child_ret = ret = 1;
  55. } else {
  56. ret = syscall_fpu();
  57. if (pid2)
  58. waitpid(pid2, &child_ret, 0);
  59. else
  60. exit(ret);
  61. }
  62. ret |= child_ret;
  63. if (pid)
  64. waitpid(pid, &child_ret, 0);
  65. else
  66. exit(ret);
  67. FAIL_IF(ret || child_ret);
  68. return 0;
  69. }
  70. int main(int argc, char *argv[])
  71. {
  72. return test_harness(test_syscall_fpu, "syscall_fpu");
  73. }