blob: 70d18be46af5d2156dff6fc14eab59d05f16f143 [file] [log] [blame]
Luis R. Rodriguez29a1c002018-03-10 06:14:42 -08001#!/bin/bash
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01002# SPDX-License-Identifier: GPL-2.0
Luis R. Rodriguez823b0222017-01-23 08:11:08 -08003# This validates that the kernel will fall back to using the fallback mechanism
Kees Cook0a8adf52014-07-14 14:38:12 -07004# 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
Luis R. Rodriguezf5a61452018-03-10 06:14:53 -08009TEST_REQS_FW_SYSFS_FALLBACK="yes"
10TEST_REQS_FW_SET_CUSTOM_PATH="no"
Luis R. Rodriguez29a1c002018-03-10 06:14:42 -080011TEST_DIR=$(dirname $0)
12source $TEST_DIR/fw_lib.sh
Kees Cook0a8adf52014-07-14 14:38:12 -070013
Luis R. Rodriguez29a1c002018-03-10 06:14:42 -080014check_mods
Luis R. Rodriguezf5a61452018-03-10 06:14:53 -080015check_setup
16verify_reqs
17setup_tmp_file
Kees Cook0a8adf52014-07-14 14:38:12 -070018
Luis R. Rodriguezf5a61452018-03-10 06:14:53 -080019trap "test_finish" EXIT
Kees Cook0a8adf52014-07-14 14:38:12 -070020
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
Luis R. Rodriguezeb67bc32017-01-23 08:11:09 -080048load_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
Luis R. Rodriguez061132d2017-01-23 08:11:10 -080073load_fw_custom()
74{
Amit Pundirc3e0d172017-11-09 01:10:35 +053075 if [ ! -e "$DIR"/trigger_custom_fallback ]; then
76 echo "$0: custom fallback trigger not present, ignoring test" >&2
Shuah Khan (Samsung OSG)a6a9be92018-05-03 16:34:22 -060077 exit $ksft_skip
Amit Pundirc3e0d172017-11-09 01:10:35 +053078 fi
79
Luis R. Rodriguez061132d2017-01-23 08:11:10 -080080 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
Amit Pundirc3e0d172017-11-09 01:10:35 +0530102 return 0
Luis R. Rodriguez061132d2017-01-23 08:11:10 -0800103}
104
105
106load_fw_custom_cancel()
107{
Amit Pundirc3e0d172017-11-09 01:10:35 +0530108 if [ ! -e "$DIR"/trigger_custom_fallback ]; then
109 echo "$0: canceling custom fallback trigger not present, ignoring test" >&2
Shuah Khan (Samsung OSG)a6a9be92018-05-03 16:34:22 -0600110 exit $ksft_skip
Amit Pundirc3e0d172017-11-09 01:10:35 +0530111 fi
112
Luis R. Rodriguez061132d2017-01-23 08:11:10 -0800113 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
Amit Pundirc3e0d172017-11-09 01:10:35 +0530133 return 0
Luis R. Rodriguez061132d2017-01-23 08:11:10 -0800134}
135
Luis R. Rodriguez0d1f4172017-07-20 13:13:38 -0700136load_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}
Luis R. Rodriguez061132d2017-01-23 08:11:10 -0800157
Luis R. Rodriguez881c23d2017-11-20 10:23:59 -0800158test_syfs_timeout()
159{
160 DEVPATH="$DIR"/"nope-$NAME"/loading
Luis R. Rodriguezafb999c2017-01-23 08:11:07 -0800161
Luis R. Rodriguez881c23d2017-11-20 10:23:59 -0800162 # 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 &
Luis R. Rodriguezafb999c2017-01-23 08:11:07 -0800165
Luis R. Rodriguez881c23d2017-11-20 10:23:59 -0800166 # 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
Luis R. Rodriguezafb999c2017-01-23 08:11:07 -0800186
Luis R. Rodriguez881c23d2017-11-20 10:23:59 -0800187 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
Luis R. Rodriguez59106c82017-11-20 10:24:00 -0800195run_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
Kees Cook0a8adf52014-07-14 14:38:12 -0700201
Luis R. Rodriguez59106c82017-11-20 10:24:00 -0800202 # 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
Kees Cook0a8adf52014-07-14 14:38:12 -0700210
Luis R. Rodriguez59106c82017-11-20 10:24:00 -0800211 # 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
Kees Cook0a8adf52014-07-14 14:38:12 -0700219
Luis R. Rodriguez59106c82017-11-20 10:24:00 -0800220 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
Luis R. Rodriguez823b0222017-01-23 08:11:08 -0800227
Luis R. Rodriguez59106c82017-11-20 10:24:00 -0800228 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
Luis R. Rodriguez82bdf492017-11-20 10:24:01 -0800239run_sysfs_custom_load_tests()
240{
Luis R. Rodriguez9952db72018-03-10 06:14:58 -0800241 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
Luis R. Rodriguez82bdf492017-11-20 10:24:01 -0800245 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
Luis R. Rodriguez9952db72018-03-10 06:14:58 -0800252 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
Luis R. Rodriguez82bdf492017-11-20 10:24:01 -0800256 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
Luis R. Rodriguez9952db72018-03-10 06:14:58 -0800263 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
Luis R. Rodriguez82bdf492017-11-20 10:24:01 -0800269 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
Luis R. Rodriguezef557782018-03-10 06:14:43 -0800277if [ "$HAS_FW_LOADER_USER_HELPER_FALLBACK" = "yes" ]; then
278 run_sysfs_main_tests
279fi
280
Luis R. Rodriguez82bdf492017-11-20 10:24:01 -0800281run_sysfs_custom_load_tests
Luis R. Rodriguez061132d2017-01-23 08:11:10 -0800282
Kees Cook0a8adf52014-07-14 14:38:12 -0700283exit 0