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