Commit | Line | Data |
---|---|---|
9536b64a CW |
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"); |