xref: /openbmc/linux/drivers/dma-buf/selftest.c (revision 976e3645923bdd2fe7893aae33fd7a21098bfb28)
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