brintos

brintos / linux-shallow public Read only

0
0
Text · 3.0 KiB · c60b694 Raw
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