0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/module.h>
0018 #include <linux/kernel.h>
0019 #include <linux/debugfs.h>
0020 #include <asm/fpu/api.h>
0021
0022 static int test_fpu(void)
0023 {
0024
0025
0026
0027
0028
0029
0030 volatile double a, b, c, d, e, f, g;
0031
0032 a = 4.0;
0033 b = 1e-15;
0034 c = 1e-310;
0035
0036
0037 d = a + b;
0038
0039
0040 e = a + b / 2;
0041
0042
0043 f = b / c;
0044
0045
0046 g = a + c * f;
0047
0048 if (d > a && e > a && g > a)
0049 return 0;
0050 else
0051 return -EINVAL;
0052 }
0053
0054 static int test_fpu_get(void *data, u64 *val)
0055 {
0056 int status = -EINVAL;
0057
0058 kernel_fpu_begin();
0059 status = test_fpu();
0060 kernel_fpu_end();
0061
0062 *val = 1;
0063 return status;
0064 }
0065
0066 DEFINE_DEBUGFS_ATTRIBUTE(test_fpu_fops, test_fpu_get, NULL, "%lld\n");
0067 static struct dentry *selftest_dir;
0068
0069 static int __init test_fpu_init(void)
0070 {
0071 selftest_dir = debugfs_create_dir("selftest_helpers", NULL);
0072 if (!selftest_dir)
0073 return -ENOMEM;
0074
0075 debugfs_create_file_unsafe("test_fpu", 0444, selftest_dir, NULL,
0076 &test_fpu_fops);
0077
0078 return 0;
0079 }
0080
0081 static void __exit test_fpu_exit(void)
0082 {
0083 debugfs_remove(selftest_dir);
0084 }
0085
0086 module_init(test_fpu_init);
0087 module_exit(test_fpu_exit);
0088
0089 MODULE_LICENSE("GPL");