12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- // SPDX-License-Identifier: GPL-2.0+
- /* This testcase operates with the test_fpu kernel driver.
- * It modifies the FPU control register in user mode and calls the kernel
- * module to perform floating point operations in the kernel. The control
- * register value should be independent between kernel and user mode.
- */
- #define _GNU_SOURCE
- #include <stdio.h>
- #include <errno.h>
- #include <string.h>
- #include <fenv.h>
- #include <unistd.h>
- #include <fcntl.h>
- const char *test_fpu_path = "/sys/kernel/debug/selftest_helpers/test_fpu";
- int main(void)
- {
- char dummy[1];
- int fd = open(test_fpu_path, O_RDONLY);
- if (fd < 0) {
- printf("[SKIP]\tcan't access %s: %s\n",
- test_fpu_path, strerror(errno));
- return 0;
- }
- if (read(fd, dummy, 1) < 0) {
- printf("[FAIL]\taccess with default rounding mode failed\n");
- return 1;
- }
- fesetround(FE_DOWNWARD);
- if (read(fd, dummy, 1) < 0) {
- printf("[FAIL]\taccess with downward rounding mode failed\n");
- return 2;
- }
- if (fegetround() != FE_DOWNWARD) {
- printf("[FAIL]\tusermode rounding mode clobbered\n");
- return 3;
- }
- /* Note: the tests up to this point are quite safe and will only return
- * an error. But the exception mask setting can cause misbehaving kernel
- * to crash.
- */
- feclearexcept(FE_ALL_EXCEPT);
- feenableexcept(FE_ALL_EXCEPT);
- if (read(fd, dummy, 1) < 0) {
- printf("[FAIL]\taccess with fpu exceptions unmasked failed\n");
- return 4;
- }
- if (fegetexcept() != FE_ALL_EXCEPT) {
- printf("[FAIL]\tusermode fpu exception mask clobbered\n");
- return 5;
- }
- printf("[OK]\ttest_fpu\n");
- return 0;
- }
|