123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- /* SPDX-License-Identifier: MIT */
- /*
- * Copyright © 2019 Intel Corporation
- */
- #include <linux/compiler.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/sched/signal.h>
- #include <linux/slab.h>
- #include "selftest.h"
- enum {
- #define selftest(n, func) __idx_##n,
- #include "selftests.h"
- #undef selftest
- };
- #define selftest(n, f) [__idx_##n] = { .name = #n, .func = f },
- static struct selftest {
- bool enabled;
- const char *name;
- int (*func)(void);
- } selftests[] = {
- #include "selftests.h"
- };
- #undef selftest
- /* Embed the line number into the parameter name so that we can order tests */
- #define param(n) __PASTE(igt__, __PASTE(__PASTE(__LINE__, __), n))
- #define selftest_0(n, func, id) \
- module_param_named(id, selftests[__idx_##n].enabled, bool, 0400);
- #define selftest(n, func) selftest_0(n, func, param(n))
- #include "selftests.h"
- #undef selftest
- int __sanitycheck__(void)
- {
- pr_debug("Hello World!\n");
- return 0;
- }
- static char *__st_filter;
- static bool apply_subtest_filter(const char *caller, const char *name)
- {
- char *filter, *sep, *tok;
- bool result = true;
- filter = kstrdup(__st_filter, GFP_KERNEL);
- for (sep = filter; (tok = strsep(&sep, ","));) {
- bool allow = true;
- char *sl;
- if (*tok == '!') {
- allow = false;
- tok++;
- }
- if (*tok == '\0')
- continue;
- sl = strchr(tok, '/');
- if (sl) {
- *sl++ = '\0';
- if (strcmp(tok, caller)) {
- if (allow)
- result = false;
- continue;
- }
- tok = sl;
- }
- if (strcmp(tok, name)) {
- if (allow)
- result = false;
- continue;
- }
- result = allow;
- break;
- }
- kfree(filter);
- return result;
- }
- int
- __subtests(const char *caller, const struct subtest *st, int count, void *data)
- {
- int err;
- for (; count--; st++) {
- cond_resched();
- if (signal_pending(current))
- return -EINTR;
- if (!apply_subtest_filter(caller, st->name))
- continue;
- pr_info("dma-buf: Running %s/%s\n", caller, st->name);
- err = st->func(data);
- if (err && err != -EINTR) {
- pr_err("dma-buf/%s: %s failed with error %d\n",
- caller, st->name, err);
- return err;
- }
- }
- return 0;
- }
- static void set_default_test_all(struct selftest *st, unsigned long count)
- {
- unsigned long i;
- for (i = 0; i < count; i++)
- if (st[i].enabled)
- return;
- for (i = 0; i < count; i++)
- st[i].enabled = true;
- }
- static int run_selftests(struct selftest *st, unsigned long count)
- {
- int err = 0;
- set_default_test_all(st, count);
- /* Tests are listed in natural order in selftests.h */
- for (; count--; st++) {
- if (!st->enabled)
- continue;
- pr_info("dma-buf: Running %s\n", st->name);
- err = st->func();
- if (err)
- break;
- }
- if (WARN(err > 0 || err == -ENOTTY,
- "%s returned %d, conflicting with selftest's magic values!\n",
- st->name, err))
- err = -1;
- return err;
- }
- static int __init st_init(void)
- {
- return run_selftests(selftests, ARRAY_SIZE(selftests));
- }
- static void __exit st_exit(void)
- {
- }
- module_param_named(st_filter, __st_filter, charp, 0400);
- module_init(st_init);
- module_exit(st_exit);
- MODULE_DESCRIPTION("Self-test harness for dma-buf");
- MODULE_LICENSE("GPL and additional rights");
|