~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/firmware/fw_fallback.sh

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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.
  7 set -e
  8 
  9 TEST_REQS_FW_SYSFS_FALLBACK="yes"
 10 TEST_REQS_FW_SET_CUSTOM_PATH="no"
 11 TEST_DIR=$(dirname $0)
 12 source $TEST_DIR/fw_lib.sh
 13 
 14 check_mods
 15 check_setup
 16 verify_reqs
 17 setup_tmp_file
 18 
 19 trap "test_finish" EXIT
 20 
 21 load_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 
 48 load_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 
 73 load_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 
106 load_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 
136 load_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 
158 test_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 
195 run_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 
239 run_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 
277 if [ "$HAS_FW_LOADER_USER_HELPER_FALLBACK" = "yes" ]; then
278         run_sysfs_main_tests
279 fi
280 
281 run_sysfs_custom_load_tests
282 
283 exit 0

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php