168 lines · c
1/* SPDX-License-Identifier: MIT */2 3/*4 * Copyright © 2019 Intel Corporation5 */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 15enum {16#define selftest(n, func) __idx_##n,17#include "selftests.h"18#undef selftest19};20 21#define selftest(n, f) [__idx_##n] = { .name = #n, .func = f },22static struct selftest {23 bool enabled;24 const char *name;25 int (*func)(void);26} selftests[] = {27#include "selftests.h"28};29#undef selftest30 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) \34module_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 selftest38 39int __sanitycheck__(void)40{41 pr_debug("Hello World!\n");42 return 0;43}44 45static char *__st_filter;46 47static 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 90int91__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 116static 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 128static 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 153static int __init st_init(void)154{155 return run_selftests(selftests, ARRAY_SIZE(selftests));156}157 158static void __exit st_exit(void)159{160}161 162module_param_named(st_filter, __st_filter, charp, 0400);163module_init(st_init);164module_exit(st_exit);165 166MODULE_DESCRIPTION("Self-test harness for dma-buf");167MODULE_LICENSE("GPL and additional rights");168