cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fw_fallback.sh (6756B)


      1#!/bin/bash
      2# SPDX-License-Identifier: GPL-2.0
      3# This validates that the kernel will fall back to using the fallback mechanism
      4# to load firmware it can't find on disk itself. We must request a firmware
      5# that the kernel won't find, and any installed helper (e.g. udev) also
      6# won't find so that we can do the load ourself manually.
      7set -e
      8
      9TEST_REQS_FW_SYSFS_FALLBACK="yes"
     10TEST_REQS_FW_SET_CUSTOM_PATH="no"
     11TEST_DIR=$(dirname $0)
     12source $TEST_DIR/fw_lib.sh
     13
     14check_mods
     15check_setup
     16verify_reqs
     17setup_tmp_file
     18
     19trap "test_finish" EXIT
     20
     21load_fw()
     22{
     23	local name="$1"
     24	local file="$2"
     25
     26	# This will block until our load (below) has finished.
     27	echo -n "$name" >"$DIR"/trigger_request &
     28
     29	# Give kernel a chance to react.
     30	local timeout=10
     31	while [ ! -e "$DIR"/"$name"/loading ]; do
     32		sleep 0.1
     33		timeout=$(( $timeout - 1 ))
     34		if [ "$timeout" -eq 0 ]; then
     35			echo "$0: firmware interface never appeared" >&2
     36			exit 1
     37		fi
     38	done
     39
     40	echo 1 >"$DIR"/"$name"/loading
     41	cat "$file" >"$DIR"/"$name"/data
     42	echo 0 >"$DIR"/"$name"/loading
     43
     44	# Wait for request to finish.
     45	wait
     46}
     47
     48load_fw_cancel()
     49{
     50	local name="$1"
     51	local file="$2"
     52
     53	# This will block until our load (below) has finished.
     54	echo -n "$name" >"$DIR"/trigger_request 2>/dev/null &
     55
     56	# Give kernel a chance to react.
     57	local timeout=10
     58	while [ ! -e "$DIR"/"$name"/loading ]; do
     59		sleep 0.1
     60		timeout=$(( $timeout - 1 ))
     61		if [ "$timeout" -eq 0 ]; then
     62			echo "$0: firmware interface never appeared" >&2
     63			exit 1
     64		fi
     65	done
     66
     67	echo -1 >"$DIR"/"$name"/loading
     68
     69	# Wait for request to finish.
     70	wait
     71}
     72
     73load_fw_custom()
     74{
     75	if [ ! -e "$DIR"/trigger_custom_fallback ]; then
     76		echo "$0: custom fallback trigger not present, ignoring test" >&2
     77		exit $ksft_skip
     78	fi
     79
     80	local name="$1"
     81	local file="$2"
     82
     83	echo -n "$name" >"$DIR"/trigger_custom_fallback 2>/dev/null &
     84
     85	# Give kernel a chance to react.
     86	local timeout=10
     87	while [ ! -e "$DIR"/"$name"/loading ]; do
     88		sleep 0.1
     89		timeout=$(( $timeout - 1 ))
     90		if [ "$timeout" -eq 0 ]; then
     91			echo "$0: firmware interface never appeared" >&2
     92			exit 1
     93		fi
     94	done
     95
     96	echo 1 >"$DIR"/"$name"/loading
     97	cat "$file" >"$DIR"/"$name"/data
     98	echo 0 >"$DIR"/"$name"/loading
     99
    100	# Wait for request to finish.
    101	wait
    102	return 0
    103}
    104
    105
    106load_fw_custom_cancel()
    107{
    108	if [ ! -e "$DIR"/trigger_custom_fallback ]; then
    109		echo "$0: canceling custom fallback trigger not present, ignoring test" >&2
    110		exit $ksft_skip
    111	fi
    112
    113	local name="$1"
    114	local file="$2"
    115
    116	echo -n "$name" >"$DIR"/trigger_custom_fallback 2>/dev/null &
    117
    118	# Give kernel a chance to react.
    119	local timeout=10
    120	while [ ! -e "$DIR"/"$name"/loading ]; do
    121		sleep 0.1
    122		timeout=$(( $timeout - 1 ))
    123		if [ "$timeout" -eq 0 ]; then
    124			echo "$0: firmware interface never appeared" >&2
    125			exit 1
    126		fi
    127	done
    128
    129	echo -1 >"$DIR"/"$name"/loading
    130
    131	# Wait for request to finish.
    132	wait
    133	return 0
    134}
    135
    136load_fw_fallback_with_child()
    137{
    138	local name="$1"
    139	local file="$2"
    140
    141	# This is the value already set but we want to be explicit
    142	echo 4 >/sys/class/firmware/timeout
    143
    144	sleep 1 &
    145	SECONDS_BEFORE=$(date +%s)
    146	echo -n "$name" >"$DIR"/trigger_request 2>/dev/null
    147	SECONDS_AFTER=$(date +%s)
    148	SECONDS_DELTA=$(($SECONDS_AFTER - $SECONDS_BEFORE))
    149	if [ "$SECONDS_DELTA" -lt 4 ]; then
    150		RET=1
    151	else
    152		RET=0
    153	fi
    154	wait
    155	return $RET
    156}
    157
    158test_syfs_timeout()
    159{
    160	DEVPATH="$DIR"/"nope-$NAME"/loading
    161
    162	# Test failure when doing nothing (timeout works).
    163	echo -n 2 >/sys/class/firmware/timeout
    164	echo -n "nope-$NAME" >"$DIR"/trigger_request 2>/dev/null &
    165
    166	# Give the kernel some time to load the loading file, must be less
    167	# than the timeout above.
    168	sleep 1
    169	if [ ! -f $DEVPATH ]; then
    170		echo "$0: fallback mechanism immediately cancelled"
    171		echo ""
    172		echo "The file never appeared: $DEVPATH"
    173		echo ""
    174		echo "This might be a distribution udev rule setup by your distribution"
    175		echo "to immediately cancel all fallback requests, this must be"
    176		echo "removed before running these tests. To confirm look for"
    177		echo "a firmware rule like /lib/udev/rules.d/50-firmware.rules"
    178		echo "and see if you have something like this:"
    179		echo ""
    180		echo "SUBSYSTEM==\"firmware\", ACTION==\"add\", ATTR{loading}=\"-1\""
    181		echo ""
    182		echo "If you do remove this file or comment out this line before"
    183		echo "proceeding with these tests."
    184		exit 1
    185	fi
    186
    187	if diff -q "$FW" /dev/test_firmware >/dev/null ; then
    188		echo "$0: firmware was not expected to match" >&2
    189		exit 1
    190	else
    191		echo "$0: timeout works"
    192	fi
    193}
    194
    195run_sysfs_main_tests()
    196{
    197	test_syfs_timeout
    198	# Put timeout high enough for us to do work but not so long that failures
    199	# slow down this test too much.
    200	echo 4 >/sys/class/firmware/timeout
    201
    202	# Load this script instead of the desired firmware.
    203	load_fw "$NAME" "$0"
    204	if diff -q "$FW" /dev/test_firmware >/dev/null ; then
    205		echo "$0: firmware was not expected to match" >&2
    206		exit 1
    207	else
    208		echo "$0: firmware comparison works"
    209	fi
    210
    211	# Do a proper load, which should work correctly.
    212	load_fw "$NAME" "$FW"
    213	if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
    214		echo "$0: firmware was not loaded" >&2
    215		exit 1
    216	else
    217		echo "$0: fallback mechanism works"
    218	fi
    219
    220	load_fw_cancel "nope-$NAME" "$FW"
    221	if diff -q "$FW" /dev/test_firmware >/dev/null ; then
    222		echo "$0: firmware was expected to be cancelled" >&2
    223		exit 1
    224	else
    225		echo "$0: cancelling fallback mechanism works"
    226	fi
    227
    228	set +e
    229	load_fw_fallback_with_child "nope-signal-$NAME" "$FW"
    230	if [ "$?" -eq 0 ]; then
    231		echo "$0: SIGCHLD on sync ignored as expected" >&2
    232	else
    233		echo "$0: error - sync firmware request cancelled due to SIGCHLD" >&2
    234		exit 1
    235	fi
    236	set -e
    237}
    238
    239run_sysfs_custom_load_tests()
    240{
    241	RANDOM_FILE_PATH=$(setup_random_file)
    242	RANDOM_FILE="$(basename $RANDOM_FILE_PATH)"
    243	if load_fw_custom "$RANDOM_FILE" "$RANDOM_FILE_PATH" ; then
    244		if ! diff -q "$RANDOM_FILE_PATH" /dev/test_firmware >/dev/null ; then
    245			echo "$0: firmware was not loaded" >&2
    246			exit 1
    247		else
    248			echo "$0: custom fallback loading mechanism works"
    249		fi
    250	fi
    251
    252	RANDOM_FILE_PATH=$(setup_random_file)
    253	RANDOM_FILE="$(basename $RANDOM_FILE_PATH)"
    254	if load_fw_custom "$RANDOM_FILE" "$RANDOM_FILE_PATH" ; then
    255		if ! diff -q "$RANDOM_FILE_PATH" /dev/test_firmware >/dev/null ; then
    256			echo "$0: firmware was not loaded" >&2
    257			exit 1
    258		else
    259			echo "$0: custom fallback loading mechanism works"
    260		fi
    261	fi
    262
    263	RANDOM_FILE_REAL="$RANDOM_FILE_PATH"
    264	FAKE_RANDOM_FILE_PATH=$(setup_random_file_fake)
    265	FAKE_RANDOM_FILE="$(basename $FAKE_RANDOM_FILE_PATH)"
    266
    267	if load_fw_custom_cancel "$FAKE_RANDOM_FILE" "$RANDOM_FILE_REAL" ; then
    268		if diff -q "$RANDOM_FILE_PATH" /dev/test_firmware >/dev/null ; then
    269			echo "$0: firmware was expected to be cancelled" >&2
    270			exit 1
    271		else
    272			echo "$0: cancelling custom fallback mechanism works"
    273		fi
    274	fi
    275}
    276
    277if [ "$HAS_FW_LOADER_USER_HELPER_FALLBACK" = "yes" ]; then
    278	run_sysfs_main_tests
    279fi
    280
    281run_sysfs_custom_load_tests
    282
    283exit 0