efivarfs is mounted read-only when the firmware does not provide a
working runtime SetVariable() service. This happens, for example, on
systems where the EFI runtime is provided by U-Boot's efi_loader (a
common case on RISC-V under QEMU booting via OpenSBI -> U-Boot -> GRUB),
or when runtime services are disabled (efi=noruntime, lockdown, etc).

In that situation every test that creates, modifies or deletes an EFI
variable is bound to fail, producing spurious test failures that do not
reflect a real kernel bug.

Detect the mount mode in check_prereqs() and store it in the global
efivarfs_mode ("ro" or "rw"). Extend run_test() to take an optional
"rw" argument marking tests that require a writable efivarfs; such tests
are reported as [SKIP] (instead of being run and failing) when efivarfs
is read-only, along with an explanatory message.

test_create_empty and test_invalid_filenames are left to run
unconditionally, since their expectation still holds on a read-only
mount; their stderr is silenced to avoid noise from the read-only
redirection failures.

Assisted-by: Copilot:claude-opus-4-8
Signed-off-by: Hui Wang <[email protected]>
---
 tools/testing/selftests/efivarfs/efivarfs.sh | 44 +++++++++++++++-----
 1 file changed, 33 insertions(+), 11 deletions(-)

diff --git a/tools/testing/selftests/efivarfs/efivarfs.sh 
b/tools/testing/selftests/efivarfs/efivarfs.sh
index c62544b966ae..d8883fdf3b01 100755
--- a/tools/testing/selftests/efivarfs/efivarfs.sh
+++ b/tools/testing/selftests/efivarfs/efivarfs.sh
@@ -26,16 +26,33 @@ check_prereqs()
                echo $msg efivarfs is not mounted on $efivarfs_mount >&2
                exit $ksft_skip
        fi
+
+       # Determine whether efivarfs is mounted read-only or read-write
+       # and store the result ("ro" or "rw") in the global efivarfs_mode.
+       if grep -q "^\S\+ $efivarfs_mount efivarfs ro[, ]" /proc/mounts; then
+               efivarfs_mode=ro
+       else
+               efivarfs_mode=rw
+       fi
 }
 
 run_test()
 {
        local test="$1"
+       # Second (optional) argument: "rw" if the test needs a writable
+       # efivarfs. Such tests are skipped when efivarfs is mounted read-only.
+       local need_rw="$2"
 
        echo "--------------------"
        echo "running $test"
        echo "--------------------"
 
+       if [ "$need_rw" = "rw" ] && [ "$efivarfs_mode" = "ro" ]; then
+               echo "  [SKIP] efivarfs is mounted read-only," \
+                    "skipping test that requires write access" >&2
+               return
+       fi
+
        if [ "$(type -t $test)" = 'function' ]; then
                ( $test )
        else
@@ -74,7 +91,7 @@ test_create_empty()
 {
        local file=$efivarfs_mount/$FUNCNAME-$test_guid
 
-       : > $file
+       : 2>/dev/null > $file
 
        if [ -e $file ]; then
                echo "$file can be created without writing" >&2
@@ -361,18 +378,23 @@ check_prereqs
 
 rc=0
 
-run_test test_create
+if [ "$efivarfs_mode" = "ro" ]; then
+       echo "efivarfs is mounted read-only on $efivarfs_mount;" \
+            "tests that require write access will be skipped" >&2
+fi
+
+run_test test_create rw
 run_test test_create_empty
-run_test test_create_read
-run_test test_delete
-run_test test_zero_size_delete
-run_test test_open_unlink
-run_test test_valid_filenames
+run_test test_create_read rw
+run_test test_delete rw
+run_test test_zero_size_delete rw
+run_test test_open_unlink rw
+run_test test_valid_filenames rw
 run_test test_invalid_filenames
-run_test test_no_set_size
+run_test test_no_set_size rw
 setup_test_multiple
-run_test test_multiple_zero_size
-run_test test_multiple_create
-run_test test_multiple_delete_on_write
+run_test test_multiple_zero_size rw
+run_test test_multiple_create rw
+run_test test_multiple_delete_on_write rw
 
 exit $rc
-- 
2.43.0


Reply via email to