1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3#
4# This reads tests.txt for the list of LKDTM tests to invoke. Any marked
5# with a leading "#" are skipped. The rest of the line after the
6# test name is either the text to look for in dmesg for a "success",
7# or the rationale for why a test is marked to be skipped.
8#
9set -e
10TRIGGER=/sys/kernel/debug/provoke-crash/DIRECT
11KSELFTEST_SKIP_TEST=4
12
13# Verify we have LKDTM available in the kernel.
14if [ ! -r $TRIGGER ] ; then
15	/sbin/modprobe -q lkdtm || true
16	if [ ! -r $TRIGGER ] ; then
17		echo "Cannot find $TRIGGER (missing CONFIG_LKDTM?)"
18	else
19		echo "Cannot write $TRIGGER (need to run as root?)"
20	fi
21	# Skip this test
22	exit $KSELFTEST_SKIP_TEST
23fi
24
25# Figure out which test to run from our script name.
26test=$(basename $0 .sh)
27# Look up details about the test from master list of LKDTM tests.
28line=$(grep -E '^#?'"$test"'\b' tests.txt)
29if [ -z "$line" ]; then
30	echo "Skipped: missing test '$test' in tests.txt"
31	exit $KSELFTEST_SKIP_TEST
32fi
33# Check that the test is known to LKDTM.
34if ! grep -E -q '^'"$test"'$' "$TRIGGER" ; then
35	echo "Skipped: test '$test' missing in $TRIGGER!"
36	exit $KSELFTEST_SKIP_TEST
37fi
38
39# Extract notes/expected output from test list.
40test=$(echo "$line" | cut -d" " -f1)
41if echo "$line" | grep -q ' ' ; then
42	expect=$(echo "$line" | cut -d" " -f2-)
43else
44	expect=""
45fi
46
47# If the test is commented out, report a skip
48if echo "$test" | grep -q '^#' ; then
49	test=$(echo "$test" | cut -c2-)
50	if [ -z "$expect" ]; then
51		expect="crashes entire system"
52	fi
53	echo "Skipping $test: $expect"
54	exit $KSELFTEST_SKIP_TEST
55fi
56
57# If no expected output given, assume an Oops with back trace is success.
58if [ -z "$expect" ]; then
59	expect="call trace:"
60fi
61
62# Prepare log for report checking
63LOG=$(mktemp --tmpdir -t lkdtm-log-XXXXXX)
64DMESG=$(mktemp --tmpdir -t lkdtm-dmesg-XXXXXX)
65cleanup() {
66	rm -f "$LOG" "$DMESG"
67}
68trap cleanup EXIT
69
70# Save existing dmesg so we can detect new content below
71dmesg > "$DMESG"
72
73# Most shells yell about signals and we're expecting the "cat" process
74# to usually be killed by the kernel. So we have to run it in a sub-shell
75# and silence errors.
76($SHELL -c 'cat <(echo '"$test"') >'"$TRIGGER" 2>/dev/null) || true
77
78# Record and dump the results
79dmesg | diff --changed-group-format='%>' --unchanged-group-format='' "$DMESG" - > "$LOG" || true
80
81cat "$LOG"
82# Check for expected output
83if grep -E -qi "$expect" "$LOG" ; then
84	echo "$test: saw '$expect': ok"
85	exit 0
86else
87	if grep -E -qi XFAIL: "$LOG" ; then
88		echo "$test: saw 'XFAIL': [SKIP]"
89		exit $KSELFTEST_SKIP_TEST
90	else
91		echo "$test: missing '$expect': [FAIL]"
92		exit 1
93	fi
94fi
95