Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /* This testcase operates with the test_fpu kernel driver.
0003  * It modifies the FPU control register in user mode and calls the kernel
0004  * module to perform floating point operations in the kernel. The control
0005  * register value should be independent between kernel and user mode.
0006  */
0007 
0008 #define _GNU_SOURCE
0009 #include <stdio.h>
0010 #include <errno.h>
0011 #include <string.h>
0012 #include <fenv.h>
0013 #include <unistd.h>
0014 #include <fcntl.h>
0015 
0016 const char *test_fpu_path = "/sys/kernel/debug/selftest_helpers/test_fpu";
0017 
0018 int main(void)
0019 {
0020     char dummy[1];
0021     int fd = open(test_fpu_path, O_RDONLY);
0022 
0023     if (fd < 0) {
0024         printf("[SKIP]\tcan't access %s: %s\n",
0025                test_fpu_path, strerror(errno));
0026         return 0;
0027     }
0028 
0029     if (read(fd, dummy, 1) < 0) {
0030         printf("[FAIL]\taccess with default rounding mode failed\n");
0031         return 1;
0032     }
0033 
0034     fesetround(FE_DOWNWARD);
0035     if (read(fd, dummy, 1) < 0) {
0036         printf("[FAIL]\taccess with downward rounding mode failed\n");
0037         return 2;
0038     }
0039     if (fegetround() != FE_DOWNWARD) {
0040         printf("[FAIL]\tusermode rounding mode clobbered\n");
0041         return 3;
0042     }
0043 
0044     /* Note: the tests up to this point are quite safe and will only return
0045      * an error. But the exception mask setting can cause misbehaving kernel
0046      * to crash.
0047      */
0048     feclearexcept(FE_ALL_EXCEPT);
0049     feenableexcept(FE_ALL_EXCEPT);
0050     if (read(fd, dummy, 1) < 0) {
0051         printf("[FAIL]\taccess with fpu exceptions unmasked failed\n");
0052         return 4;
0053     }
0054     if (fegetexcept() != FE_ALL_EXCEPT) {
0055         printf("[FAIL]\tusermode fpu exception mask clobbered\n");
0056         return 5;
0057     }
0058 
0059     printf("[OK]\ttest_fpu\n");
0060     return 0;
0061 }