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