1*4882a593Smuzhiyun#!/bin/sh 2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0 3*4882a593Smuzhiyun# 4*4882a593Smuzhiyun# This reads tests.txt for the list of LKDTM tests to invoke. Any marked 5*4882a593Smuzhiyun# with a leading "#" are skipped. The rest of the line after the 6*4882a593Smuzhiyun# test name is either the text to look for in dmesg for a "success", 7*4882a593Smuzhiyun# or the rationale for why a test is marked to be skipped. 8*4882a593Smuzhiyun# 9*4882a593Smuzhiyunset -e 10*4882a593SmuzhiyunTRIGGER=/sys/kernel/debug/provoke-crash/DIRECT 11*4882a593SmuzhiyunCLEAR_ONCE=/sys/kernel/debug/clear_warn_once 12*4882a593SmuzhiyunKSELFTEST_SKIP_TEST=4 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun# Verify we have LKDTM available in the kernel. 15*4882a593Smuzhiyunif [ ! -r $TRIGGER ] ; then 16*4882a593Smuzhiyun /sbin/modprobe -q lkdtm || true 17*4882a593Smuzhiyun if [ ! -r $TRIGGER ] ; then 18*4882a593Smuzhiyun echo "Cannot find $TRIGGER (missing CONFIG_LKDTM?)" 19*4882a593Smuzhiyun else 20*4882a593Smuzhiyun echo "Cannot write $TRIGGER (need to run as root?)" 21*4882a593Smuzhiyun fi 22*4882a593Smuzhiyun # Skip this test 23*4882a593Smuzhiyun exit $KSELFTEST_SKIP_TEST 24*4882a593Smuzhiyunfi 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun# Figure out which test to run from our script name. 27*4882a593Smuzhiyuntest=$(basename $0 .sh) 28*4882a593Smuzhiyun# Look up details about the test from master list of LKDTM tests. 29*4882a593Smuzhiyunline=$(grep -E '^#?'"$test"'\b' tests.txt) 30*4882a593Smuzhiyunif [ -z "$line" ]; then 31*4882a593Smuzhiyun echo "Skipped: missing test '$test' in tests.txt" 32*4882a593Smuzhiyun exit $KSELFTEST_SKIP_TEST 33*4882a593Smuzhiyunfi 34*4882a593Smuzhiyun# Check that the test is known to LKDTM. 35*4882a593Smuzhiyunif ! grep -E -q '^'"$test"'$' "$TRIGGER" ; then 36*4882a593Smuzhiyun echo "Skipped: test '$test' missing in $TRIGGER!" 37*4882a593Smuzhiyun exit $KSELFTEST_SKIP_TEST 38*4882a593Smuzhiyunfi 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun# Extract notes/expected output from test list. 41*4882a593Smuzhiyuntest=$(echo "$line" | cut -d" " -f1) 42*4882a593Smuzhiyunif echo "$line" | grep -q ' ' ; then 43*4882a593Smuzhiyun expect=$(echo "$line" | cut -d" " -f2-) 44*4882a593Smuzhiyunelse 45*4882a593Smuzhiyun expect="" 46*4882a593Smuzhiyunfi 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun# If the test is commented out, report a skip 49*4882a593Smuzhiyunif echo "$test" | grep -q '^#' ; then 50*4882a593Smuzhiyun test=$(echo "$test" | cut -c2-) 51*4882a593Smuzhiyun if [ -z "$expect" ]; then 52*4882a593Smuzhiyun expect="crashes entire system" 53*4882a593Smuzhiyun fi 54*4882a593Smuzhiyun echo "Skipping $test: $expect" 55*4882a593Smuzhiyun exit $KSELFTEST_SKIP_TEST 56*4882a593Smuzhiyunfi 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun# If no expected output given, assume an Oops with back trace is success. 59*4882a593Smuzhiyunif [ -z "$expect" ]; then 60*4882a593Smuzhiyun expect="call trace:" 61*4882a593Smuzhiyunfi 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun# Prepare log for report checking 64*4882a593SmuzhiyunLOG=$(mktemp --tmpdir -t lkdtm-log-XXXXXX) 65*4882a593SmuzhiyunDMESG=$(mktemp --tmpdir -t lkdtm-dmesg-XXXXXX) 66*4882a593Smuzhiyuncleanup() { 67*4882a593Smuzhiyun rm -f "$LOG" "$DMESG" 68*4882a593Smuzhiyun} 69*4882a593Smuzhiyuntrap cleanup EXIT 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun# Reset WARN_ONCE counters so we trip it each time this runs. 72*4882a593Smuzhiyunif [ -w $CLEAR_ONCE ] ; then 73*4882a593Smuzhiyun echo 1 > $CLEAR_ONCE 74*4882a593Smuzhiyunfi 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun# Save existing dmesg so we can detect new content below 77*4882a593Smuzhiyundmesg > "$DMESG" 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun# Since the kernel is likely killing the process writing to the trigger 80*4882a593Smuzhiyun# file, it must not be the script's shell itself. i.e. we cannot do: 81*4882a593Smuzhiyun# echo "$test" >"$TRIGGER" 82*4882a593Smuzhiyun# Instead, use "cat" to take the signal. Since the shell will yell about 83*4882a593Smuzhiyun# the signal that killed the subprocess, we must ignore the failure and 84*4882a593Smuzhiyun# continue. However we don't silence stderr since there might be other 85*4882a593Smuzhiyun# useful details reported there in the case of other unexpected conditions. 86*4882a593Smuzhiyunecho "$test" | cat >"$TRIGGER" || true 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun# Record and dump the results 89*4882a593Smuzhiyundmesg | comm --nocheck-order -13 "$DMESG" - > "$LOG" || true 90*4882a593Smuzhiyun 91*4882a593Smuzhiyuncat "$LOG" 92*4882a593Smuzhiyun# Check for expected output 93*4882a593Smuzhiyunif grep -E -qi "$expect" "$LOG" ; then 94*4882a593Smuzhiyun echo "$test: saw '$expect': ok" 95*4882a593Smuzhiyun exit 0 96*4882a593Smuzhiyunelse 97*4882a593Smuzhiyun if grep -E -qi XFAIL: "$LOG" ; then 98*4882a593Smuzhiyun echo "$test: saw 'XFAIL': [SKIP]" 99*4882a593Smuzhiyun exit $KSELFTEST_SKIP_TEST 100*4882a593Smuzhiyun else 101*4882a593Smuzhiyun echo "$test: missing '$expect': [FAIL]" 102*4882a593Smuzhiyun exit 1 103*4882a593Smuzhiyun fi 104*4882a593Smuzhiyunfi 105