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

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/firmware/fw_filesystem.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 load firmware out of its list of
  4 # firmware locations on disk. Since the user helper does similar work,
  5 # we reset the custom load directory to a location the user helper doesn't
  6 # know so we can be sure we're not accidentally testing the user helper.
  7 set -e
  8 
  9 TEST_REQS_FW_SYSFS_FALLBACK="no"
 10 TEST_REQS_FW_SET_CUSTOM_PATH="yes"
 11 TEST_DIR=$(dirname $0)
 12 source $TEST_DIR/fw_lib.sh
 13 
 14 RUN_XZ="xz -C crc32 --lzma2=dict=2MiB"
 15 RUN_ZSTD="zstd -q"
 16 
 17 check_mods
 18 check_setup
 19 verify_reqs
 20 setup_tmp_file
 21 
 22 trap "test_finish" EXIT
 23 
 24 if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
 25         # Turn down the timeout so failures don't take so long.
 26         echo 1 >/sys/class/firmware/timeout
 27 fi
 28 
 29 if printf '\000' >"$DIR"/trigger_request 2> /dev/null; then
 30         echo "$0: empty filename should not succeed" >&2
 31         exit 1
 32 fi
 33 
 34 if [ ! -e "$DIR"/trigger_async_request ]; then
 35         echo "$0: empty filename: async trigger not present, ignoring test" >&2
 36         exit $ksft_skip
 37 else
 38         if printf '\000' >"$DIR"/trigger_async_request 2> /dev/null; then
 39                 echo "$0: empty filename should not succeed (async)" >&2
 40                 exit 1
 41         fi
 42 fi
 43 
 44 # Request a firmware that doesn't exist, it should fail.
 45 if echo -n "nope-$NAME" >"$DIR"/trigger_request 2> /dev/null; then
 46         echo "$0: firmware shouldn't have loaded" >&2
 47         exit 1
 48 fi
 49 if diff -q "$FW" /dev/test_firmware >/dev/null ; then
 50         echo "$0: firmware was not expected to match" >&2
 51         exit 1
 52 else
 53         if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
 54                 echo "$0: timeout works"
 55         fi
 56 fi
 57 
 58 # This should succeed via kernel load or will fail after 1 second after
 59 # being handed over to the user helper, which won't find the fw either.
 60 if ! echo -n "$NAME" >"$DIR"/trigger_request ; then
 61         echo "$0: could not trigger request" >&2
 62         exit 1
 63 fi
 64 
 65 # Verify the contents are what we expect.
 66 if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
 67         echo "$0: firmware was not loaded" >&2
 68         exit 1
 69 else
 70         echo "$0: filesystem loading works"
 71 fi
 72 
 73 # Try the asynchronous version too
 74 if [ ! -e "$DIR"/trigger_async_request ]; then
 75         echo "$0: firmware loading: async trigger not present, ignoring test" >&2
 76         exit $ksft_skip
 77 else
 78         if ! echo -n "$NAME" >"$DIR"/trigger_async_request ; then
 79                 echo "$0: could not trigger async request" >&2
 80                 exit 1
 81         fi
 82 
 83         # Verify the contents are what we expect.
 84         if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
 85                 echo "$0: firmware was not loaded (async)" >&2
 86                 exit 1
 87         else
 88                 echo "$0: async filesystem loading works"
 89         fi
 90 fi
 91 
 92 # Try platform (EFI embedded fw) loading too
 93 if [ ! -e "$DIR"/trigger_request_platform ]; then
 94         echo "$0: firmware loading: platform trigger not present, ignoring test" >&2
 95 else
 96         if printf '\000' >"$DIR"/trigger_request_platform 2> /dev/null; then
 97                 echo "$0: empty filename should not succeed (platform)" >&2
 98                 exit 1
 99         fi
100 
101         # Note we echo a non-existing name, since files on the file-system
102         # are preferred over firmware embedded inside the platform's firmware
103         # The test adds a fake entry with the requested name to the platform's
104         # fw list, so the name does not matter as long as it does not exist
105         if ! echo -n "nope-$NAME" >"$DIR"/trigger_request_platform ; then
106                 echo "$0: could not trigger request platform" >&2
107                 exit 1
108         fi
109 
110         # The test verifies itself that the loaded firmware contents matches
111         # the contents for the fake platform fw entry it added.
112         echo "$0: platform loading works"
113 fi
114 
115 ### Batched requests tests
116 test_config_present()
117 {
118         if [ ! -f $DIR/reset ]; then
119                 echo "Configuration triggers not present, ignoring test"
120                 exit $ksft_skip
121         fi
122 }
123 
124 # Defaults :
125 #
126 # send_uevent: 1
127 # sync_direct: 0
128 # name: test-firmware.bin
129 # num_requests: 4
130 config_reset()
131 {
132         echo 1 >  $DIR/reset
133 }
134 
135 release_all_firmware()
136 {
137         echo 1 >  $DIR/release_all_firmware
138 }
139 
140 config_set_name()
141 {
142         echo -n $1 >  $DIR/config_name
143 }
144 
145 config_set_into_buf()
146 {
147         echo 1 >  $DIR/config_into_buf
148 }
149 
150 config_unset_into_buf()
151 {
152         echo 0 >  $DIR/config_into_buf
153 }
154 
155 config_set_buf_size()
156 {
157         echo $1 >  $DIR/config_buf_size
158 }
159 
160 config_set_file_offset()
161 {
162         echo $1 >  $DIR/config_file_offset
163 }
164 
165 config_set_partial()
166 {
167         echo 1 >  $DIR/config_partial
168 }
169 
170 config_unset_partial()
171 {
172         echo 0 >  $DIR/config_partial
173 }
174 
175 config_set_sync_direct()
176 {
177         echo 1 >  $DIR/config_sync_direct
178 }
179 
180 config_unset_sync_direct()
181 {
182         echo 0 >  $DIR/config_sync_direct
183 }
184 
185 config_set_uevent()
186 {
187         echo 1 >  $DIR/config_send_uevent
188 }
189 
190 config_unset_uevent()
191 {
192         echo 0 >  $DIR/config_send_uevent
193 }
194 
195 config_trigger_sync()
196 {
197         echo -n 1 > $DIR/trigger_batched_requests 2>/dev/null
198 }
199 
200 config_trigger_async()
201 {
202         echo -n 1 > $DIR/trigger_batched_requests_async 2> /dev/null
203 }
204 
205 config_set_read_fw_idx()
206 {
207         echo -n $1 > $DIR/config_read_fw_idx 2> /dev/null
208 }
209 
210 read_firmwares()
211 {
212         if [ "$(cat $DIR/config_into_buf)" == "1" ]; then
213                 fwfile="$FW_INTO_BUF"
214         else
215                 fwfile="$FW"
216         fi
217         if [ "$1" = "componly" ]; then
218                 fwfile="${fwfile}-orig"
219         fi
220         for i in $(seq 0 3); do
221                 config_set_read_fw_idx $i
222                 # Verify the contents are what we expect.
223                 # -Z required for now -- check for yourself, md5sum
224                 # on $FW and DIR/read_firmware will yield the same. Even
225                 # cmp agrees, so something is off.
226                 if ! diff -q -Z "$fwfile" $DIR/read_firmware 2>/dev/null ; then
227                         echo "request #$i: firmware was not loaded" >&2
228                         exit 1
229                 fi
230         done
231 }
232 
233 read_partial_firmwares()
234 {
235         if [ "$(cat $DIR/config_into_buf)" == "1" ]; then
236                 fwfile="${FW_INTO_BUF}"
237         else
238                 fwfile="${FW}"
239         fi
240 
241         if [ "$1" = "componly" ]; then
242                 fwfile="${fwfile}-orig"
243         fi
244 
245         # Strip fwfile down to match partial offset and length
246         partial_data="$(cat $fwfile)"
247         partial_data="${partial_data:$2:$3}"
248 
249         for i in $(seq 0 3); do
250                 config_set_read_fw_idx $i
251 
252                 read_firmware="$(cat $DIR/read_firmware)"
253 
254                 # Verify the contents are what we expect.
255                 if [ $read_firmware != $partial_data ]; then
256                         echo "request #$i: partial firmware was not loaded" >&2
257                         exit 1
258                 fi
259         done
260 }
261 
262 read_firmwares_expect_nofile()
263 {
264         for i in $(seq 0 3); do
265                 config_set_read_fw_idx $i
266                 # Ensures contents differ
267                 if diff -q -Z "$FW" $DIR/read_firmware 2>/dev/null ; then
268                         echo "request $i: file was not expected to match" >&2
269                         exit 1
270                 fi
271         done
272 }
273 
274 test_batched_request_firmware_nofile()
275 {
276         echo -n "Batched request_firmware() nofile try #$1: "
277         config_reset
278         config_set_name nope-test-firmware.bin
279         config_trigger_sync
280         read_firmwares_expect_nofile
281         release_all_firmware
282         echo "OK"
283 }
284 
285 test_batched_request_firmware_into_buf_nofile()
286 {
287         echo -n "Batched request_firmware_into_buf() nofile try #$1: "
288         config_reset
289         config_set_name nope-test-firmware.bin
290         config_set_into_buf
291         config_trigger_sync
292         read_firmwares_expect_nofile
293         release_all_firmware
294         echo "OK"
295 }
296 
297 test_request_partial_firmware_into_buf_nofile()
298 {
299         echo -n "Test request_partial_firmware_into_buf() off=$1 size=$2 nofile: "
300         config_reset
301         config_set_name nope-test-firmware.bin
302         config_set_into_buf
303         config_set_partial
304         config_set_buf_size $2
305         config_set_file_offset $1
306         config_trigger_sync
307         read_firmwares_expect_nofile
308         release_all_firmware
309         echo "OK"
310 }
311 
312 test_batched_request_firmware_direct_nofile()
313 {
314         echo -n "Batched request_firmware_direct() nofile try #$1: "
315         config_reset
316         config_set_name nope-test-firmware.bin
317         config_set_sync_direct
318         config_trigger_sync
319         release_all_firmware
320         echo "OK"
321 }
322 
323 test_request_firmware_nowait_uevent_nofile()
324 {
325         echo -n "Batched request_firmware_nowait(uevent=true) nofile try #$1: "
326         config_reset
327         config_set_name nope-test-firmware.bin
328         config_trigger_async
329         release_all_firmware
330         echo "OK"
331 }
332 
333 test_wait_and_cancel_custom_load()
334 {
335         if [ "$HAS_FW_LOADER_USER_HELPER" != "yes" ]; then
336                 return
337         fi
338         local timeout=10
339         name=$1
340         while [ ! -e "$DIR"/"$name"/loading ]; do
341                 sleep 0.1
342                 timeout=$(( $timeout - 1 ))
343                 if [ "$timeout" -eq 0 ]; then
344                         echo "firmware interface never appeared:" >&2
345                         echo "$DIR/$name/loading" >&2
346                         exit 1
347                 fi
348         done
349         echo -1 >"$DIR"/"$name"/loading
350 }
351 
352 test_request_firmware_nowait_custom_nofile()
353 {
354         echo -n "Batched request_firmware_nowait(uevent=false) nofile try #$1: "
355         config_reset
356         config_unset_uevent
357         RANDOM_FILE_PATH=$(setup_random_file_fake)
358         RANDOM_FILE="$(basename $RANDOM_FILE_PATH)"
359         config_set_name $RANDOM_FILE
360         config_trigger_async &
361         test_wait_and_cancel_custom_load $RANDOM_FILE
362         wait
363         release_all_firmware
364         echo "OK"
365 }
366 
367 test_batched_request_firmware()
368 {
369         echo -n "Batched request_firmware() $2 try #$1: "
370         config_reset
371         config_trigger_sync
372         read_firmwares $2
373         release_all_firmware
374         echo "OK"
375 }
376 
377 test_batched_request_firmware_into_buf()
378 {
379         echo -n "Batched request_firmware_into_buf() $2 try #$1: "
380         config_reset
381         config_set_name $TEST_FIRMWARE_INTO_BUF_FILENAME
382         config_set_into_buf
383         config_trigger_sync
384         read_firmwares $2
385         release_all_firmware
386         echo "OK"
387 }
388 
389 test_batched_request_firmware_direct()
390 {
391         echo -n "Batched request_firmware_direct() $2 try #$1: "
392         config_reset
393         config_set_sync_direct
394         config_trigger_sync
395         release_all_firmware
396         echo "OK"
397 }
398 
399 test_request_firmware_nowait_uevent()
400 {
401         echo -n "Batched request_firmware_nowait(uevent=true) $2 try #$1: "
402         config_reset
403         config_trigger_async
404         release_all_firmware
405         echo "OK"
406 }
407 
408 test_request_firmware_nowait_custom()
409 {
410         echo -n "Batched request_firmware_nowait(uevent=false) $2 try #$1: "
411         config_reset
412         config_unset_uevent
413         RANDOM_FILE_PATH=$(setup_random_file)
414         RANDOM_FILE="$(basename $RANDOM_FILE_PATH)"
415         if [ -n "$2" -a "$2" != "normal" ]; then
416                 compress_"$2"_"$COMPRESS_FORMAT" $RANDOM_FILE_PATH
417         fi
418         config_set_name $RANDOM_FILE
419         config_trigger_async
420         release_all_firmware
421         echo "OK"
422 }
423 
424 test_request_partial_firmware_into_buf()
425 {
426         echo -n "Test request_partial_firmware_into_buf() off=$1 size=$2: "
427         config_reset
428         config_set_name $TEST_FIRMWARE_INTO_BUF_FILENAME
429         config_set_into_buf
430         config_set_partial
431         config_set_buf_size $2
432         config_set_file_offset $1
433         config_trigger_sync
434         read_partial_firmwares normal $1 $2
435         release_all_firmware
436         echo "OK"
437 }
438 
439 do_tests ()
440 {
441         mode="$1"
442         suffix="$2"
443 
444         for i in $(seq 1 5); do
445                 test_batched_request_firmware$suffix $i $mode
446         done
447 
448         for i in $(seq 1 5); do
449                 test_batched_request_firmware_into_buf$suffix $i $mode
450         done
451 
452         for i in $(seq 1 5); do
453                 test_batched_request_firmware_direct$suffix $i $mode
454         done
455 
456         for i in $(seq 1 5); do
457                 test_request_firmware_nowait_uevent$suffix $i $mode
458         done
459 
460         for i in $(seq 1 5); do
461                 test_request_firmware_nowait_custom$suffix $i $mode
462         done
463 }
464 
465 # Only continue if batched request triggers are present on the
466 # test-firmware driver
467 test_config_present
468 
469 # test with the file present
470 echo
471 echo "Testing with the file present..."
472 do_tests normal
473 
474 # Partial loads cannot use fallback, so do not repeat tests.
475 test_request_partial_firmware_into_buf 0 10
476 test_request_partial_firmware_into_buf 0 5
477 test_request_partial_firmware_into_buf 1 6
478 test_request_partial_firmware_into_buf 2 10
479 
480 # Test for file not found, errors are expected, the failure would be
481 # a hung task, which would require a hard reset.
482 echo
483 echo "Testing with the file missing..."
484 do_tests nofile _nofile
485 
486 # Partial loads cannot use fallback, so do not repeat tests.
487 test_request_partial_firmware_into_buf_nofile 0 10
488 test_request_partial_firmware_into_buf_nofile 0 5
489 test_request_partial_firmware_into_buf_nofile 1 6
490 test_request_partial_firmware_into_buf_nofile 2 10
491 
492 test_request_firmware_compressed ()
493 {
494         export COMPRESS_FORMAT="$1"
495 
496         # test with both files present
497         compress_both_"$COMPRESS_FORMAT" $FW
498         compress_both_"$COMPRESS_FORMAT" $FW_INTO_BUF
499 
500         config_set_name $NAME
501         echo
502         echo "Testing with both plain and $COMPRESS_FORMAT files present..."
503         do_tests both
504 
505         # test with only compressed file present
506         mv "$FW" "${FW}-orig"
507         mv "$FW_INTO_BUF" "${FW_INTO_BUF}-orig"
508 
509         config_set_name $NAME
510         echo
511         echo "Testing with only $COMPRESS_FORMAT file present..."
512         do_tests componly
513 
514         mv "${FW}-orig" "$FW"
515         mv "${FW_INTO_BUF}-orig" "$FW_INTO_BUF"
516 }
517 
518 compress_both_XZ ()
519 {
520         $RUN_XZ -k "$@"
521 }
522 
523 compress_componly_XZ ()
524 {
525         $RUN_XZ "$@"
526 }
527 
528 compress_both_ZSTD ()
529 {
530         $RUN_ZSTD -k "$@"
531 }
532 
533 compress_componly_ZSTD ()
534 {
535         $RUN_ZSTD --rm "$@"
536 }
537 
538 if test "$HAS_FW_LOADER_COMPRESS_XZ" = "yes"; then
539         test_request_firmware_compressed XZ
540 fi
541 
542 if test "$HAS_FW_LOADER_COMPRESS_ZSTD" = "yes"; then
543         test_request_firmware_compressed ZSTD
544 fi
545 
546 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