test_fpu.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /* This testcase operates with the test_fpu kernel driver.
  3. * It modifies the FPU control register in user mode and calls the kernel
  4. * module to perform floating point operations in the kernel. The control
  5. * register value should be independent between kernel and user mode.
  6. */
  7. #define _GNU_SOURCE
  8. #include <stdio.h>
  9. #include <errno.h>
  10. #include <string.h>
  11. #include <fenv.h>
  12. #include <unistd.h>
  13. #include <fcntl.h>
  14. const char *test_fpu_path = "/sys/kernel/debug/selftest_helpers/test_fpu";
  15. int main(void)
  16. {
  17. char dummy[1];
  18. int fd = open(test_fpu_path, O_RDONLY);
  19. if (fd < 0) {
  20. printf("[SKIP]\tcan't access %s: %s\n",
  21. test_fpu_path, strerror(errno));
  22. return 0;
  23. }
  24. if (read(fd, dummy, 1) < 0) {
  25. printf("[FAIL]\taccess with default rounding mode failed\n");
  26. return 1;
  27. }
  28. fesetround(FE_DOWNWARD);
  29. if (read(fd, dummy, 1) < 0) {
  30. printf("[FAIL]\taccess with downward rounding mode failed\n");
  31. return 2;
  32. }
  33. if (fegetround() != FE_DOWNWARD) {
  34. printf("[FAIL]\tusermode rounding mode clobbered\n");
  35. return 3;
  36. }
  37. /* Note: the tests up to this point are quite safe and will only return
  38. * an error. But the exception mask setting can cause misbehaving kernel
  39. * to crash.
  40. */
  41. feclearexcept(FE_ALL_EXCEPT);
  42. feenableexcept(FE_ALL_EXCEPT);
  43. if (read(fd, dummy, 1) < 0) {
  44. printf("[FAIL]\taccess with fpu exceptions unmasked failed\n");
  45. return 4;
  46. }
  47. if (fegetexcept() != FE_ALL_EXCEPT) {
  48. printf("[FAIL]\tusermode fpu exception mask clobbered\n");
  49. return 5;
  50. }
  51. printf("[OK]\ttest_fpu\n");
  52. return 0;
  53. }