1 /* SPDX-License-Identifier: MIT */ 2 3 /* 4 * Copyright © 2019 Intel Corporation 5 */ 6 7 #include <linux/compiler.h> 8 #include <linux/kernel.h> 9 #include <linux/module.h> 10 #include <linux/sched/signal.h> 11 #include <linux/slab.h> 12 13 #include "selftest.h" 14 15 enum { 16 #define selftest(n, func) __idx_##n, 17 #include "selftests.h" 18 #undef selftest 19 }; 20 21 #define selftest(n, f) [__idx_##n] = { .name = #n, .func = f }, 22 static struct selftest { 23 bool enabled; 24 const char *name; 25 int (*func)(void); 26 } selftests[] = { 27 #include "selftests.h" 28 }; 29 #undef selftest 30 31 /* Embed the line number into the parameter name so that we can order tests */ 32 #define param(n) __PASTE(igt__, __PASTE(__PASTE(__LINE__, __), n)) 33 #define selftest_0(n, func, id) \ 34 module_param_named(id, selftests[__idx_##n].enabled, bool, 0400); 35 #define selftest(n, func) selftest_0(n, func, param(n)) 36 #include "selftests.h" 37 #undef selftest 38 39 int __sanitycheck__(void) 40 { 41 pr_debug("Hello World!\n"); 42 return 0; 43 } 44 45 static char *__st_filter; 46 47 static bool apply_subtest_filter(const char *caller, const char *name) 48 { 49 char *filter, *sep, *tok; 50 bool result = true; 51 52 filter = kstrdup(__st_filter, GFP_KERNEL); 53 for (sep = filter; (tok = strsep(&sep, ","));) { 54 bool allow = true; 55 char *sl; 56 57 if (*tok == '!') { 58 allow = false; 59 tok++; 60 } 61 62 if (*tok == '\0') 63 continue; 64 65 sl = strchr(tok, '/'); 66 if (sl) { 67 *sl++ = '\0'; 68 if (strcmp(tok, caller)) { 69 if (allow) 70 result = false; 71 continue; 72 } 73 tok = sl; 74 } 75 76 if (strcmp(tok, name)) { 77 if (allow) 78 result = false; 79 continue; 80 } 81 82 result = allow; 83 break; 84 } 85 kfree(filter); 86 87 return result; 88 } 89 90 int 91 __subtests(const char *caller, const struct subtest *st, int count, void *data) 92 { 93 int err; 94 95 for (; count--; st++) { 96 cond_resched(); 97 if (signal_pending(current)) 98 return -EINTR; 99 100 if (!apply_subtest_filter(caller, st->name)) 101 continue; 102 103 pr_info("dma-buf: Running %s/%s\n", caller, st->name); 104 105 err = st->func(data); 106 if (err && err != -EINTR) { 107 pr_err("dma-buf/%s: %s failed with error %d\n", 108 caller, st->name, err); 109 return err; 110 } 111 } 112 113 return 0; 114 } 115 116 static void set_default_test_all(struct selftest *st, unsigned long count) 117 { 118 unsigned long i; 119 120 for (i = 0; i < count; i++) 121 if (st[i].enabled) 122 return; 123 124 for (i = 0; i < count; i++) 125 st[i].enabled = true; 126 } 127 128 static int run_selftests(struct selftest *st, unsigned long count) 129 { 130 int err = 0; 131 132 set_default_test_all(st, count); 133 134 /* Tests are listed in natural order in selftests.h */ 135 for (; count--; st++) { 136 if (!st->enabled) 137 continue; 138 139 pr_info("dma-buf: Running %s\n", st->name); 140 err = st->func(); 141 if (err) 142 break; 143 } 144 145 if (WARN(err > 0 || err == -ENOTTY, 146 "%s returned %d, conflicting with selftest's magic values!\n", 147 st->name, err)) 148 err = -1; 149 150 return err; 151 } 152 153 static int __init st_init(void) 154 { 155 return run_selftests(selftests, ARRAY_SIZE(selftests)); 156 } 157 158 static void __exit st_exit(void) 159 { 160 } 161 162 module_param_named(st_filter, __st_filter, charp, 0400); 163 module_init(st_init); 164 module_exit(st_exit); 165 166 MODULE_DESCRIPTION("Self-test harness for dma-buf"); 167 MODULE_LICENSE("GPL and additional rights"); 168