summaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests/verification
diff options
context:
space:
mode:
authorZeng Chi <zengchi@kylinos.cn>2026-09-21 18:24:42 +0800
committerSean Christopherson <seanjc@google.com>2026-09-22 08:36:16 -0700
commit119e9db233ad0f4cbd4cfb9f9385a7bca378b37d (patch)
tree660d50d4139cb750fbde1ae3432452c20726c99d /tools/testing/selftests/verification
downloadlinux-stable-119e9db233ad0f4cbd4cfb9f9385a7bca378b37d.tar.gz
linux-stable-119e9db233ad0f4cbd4cfb9f9385a7bca378b37d.zip
KVM: Don't pre-reserve xarray entries when storing empty/NULL attributesgrafted
Skip the xarray reservation loop when clearing all memory attributes, as storing NULL only erases the entry and never needs to allocate, so no reservation (and no cleanup of a failed one) is required in that case. Suggested-by: Sean Christopherson <seanjc@google.com> Cc: David Ballesteros <davimaba.v@proton.me> Signed-off-by: Zeng Chi <zengchi@kylinos.cn> Link: https://patch.msgid.link/20260921102442.1232375-1-zeng_chi911@163.com [sean: split to separate patch] Signed-off-by: Sean Christopherson <seanjc@google.com>
Diffstat (limited to 'tools/testing/selftests/verification')
-rw-r--r--tools/testing/selftests/verification/.gitignore2
-rw-r--r--tools/testing/selftests/verification/Makefile8
-rw-r--r--tools/testing/selftests/verification/config1
-rw-r--r--tools/testing/selftests/verification/settings1
-rw-r--r--tools/testing/selftests/verification/test.d/functions39
-rw-r--r--tools/testing/selftests/verification/test.d/rv_deadline.tc23
-rw-r--r--tools/testing/selftests/verification/test.d/rv_monitor_enable_disable.tc75
-rw-r--r--tools/testing/selftests/verification/test.d/rv_monitor_reactor.tc68
-rw-r--r--tools/testing/selftests/verification/test.d/rv_monitors_available.tc18
-rw-r--r--tools/testing/selftests/verification/test.d/rv_stall.tc33
-rw-r--r--tools/testing/selftests/verification/test.d/rv_wwnr_printk.tc52
-rwxr-xr-xtools/testing/selftests/verification/verificationtest-ktap8
12 files changed, 328 insertions, 0 deletions
diff --git a/tools/testing/selftests/verification/.gitignore b/tools/testing/selftests/verification/.gitignore
new file mode 100644
index 000000000..2659417cb
--- /dev/null
+++ b/tools/testing/selftests/verification/.gitignore
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+logs
diff --git a/tools/testing/selftests/verification/Makefile b/tools/testing/selftests/verification/Makefile
new file mode 100644
index 000000000..aa8790c22
--- /dev/null
+++ b/tools/testing/selftests/verification/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+all:
+
+TEST_PROGS := verificationtest-ktap
+TEST_FILES := test.d settings
+EXTRA_CLEAN := $(OUTPUT)/logs/*
+
+include ../lib.mk
diff --git a/tools/testing/selftests/verification/config b/tools/testing/selftests/verification/config
new file mode 100644
index 000000000..43072c1c3
--- /dev/null
+++ b/tools/testing/selftests/verification/config
@@ -0,0 +1 @@
+CONFIG_RV=y
diff --git a/tools/testing/selftests/verification/settings b/tools/testing/selftests/verification/settings
new file mode 100644
index 000000000..e7b941753
--- /dev/null
+++ b/tools/testing/selftests/verification/settings
@@ -0,0 +1 @@
+timeout=0
diff --git a/tools/testing/selftests/verification/test.d/functions b/tools/testing/selftests/verification/test.d/functions
new file mode 100644
index 000000000..ec36a092f
--- /dev/null
+++ b/tools/testing/selftests/verification/test.d/functions
@@ -0,0 +1,39 @@
+check_requires() { # Check required files, monitors and reactors
+ for i in "$@" ; do
+ p=${i%:program}
+ m=${i%:monitor}
+ r=${i%:reactor}
+ if [ $p != $i ]; then
+ if ! which $p ; then
+ echo "Required program $p is not found."
+ exit_unresolved
+ fi
+ elif [ $m != $i ]; then
+ if ! grep -wq $m available_monitors ; then
+ echo "Required monitor $m is not configured."
+ exit_unsupported
+ fi
+ elif [ $r != $i ]; then
+ if ! grep -wq $r available_reactors ; then
+ echo "Required reactor $r is not configured."
+ exit_unsupported
+ fi
+ elif [ ! -e $i ]; then
+ echo "Required feature interface $i doesn't exist."
+ exit_unsupported
+ fi
+ done
+}
+
+initialize_system() { # Reset RV to initial-state
+ echo > enabled_monitors
+ for m in monitors/*; do
+ echo nop > $m/reactors || true
+ done
+ echo 1 > monitoring_on
+ echo 1 > reacting_on || true
+}
+
+finish_system() {
+ initialize_system
+}
diff --git a/tools/testing/selftests/verification/test.d/rv_deadline.tc b/tools/testing/selftests/verification/test.d/rv_deadline.tc
new file mode 100644
index 000000000..fc95267db
--- /dev/null
+++ b/tools/testing/selftests/verification/test.d/rv_deadline.tc
@@ -0,0 +1,23 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# description: Test deadline monitors trigger no reaction
+# requires: available_reactors deadline:monitor printk:reactor stress-ng:program
+
+load() { # returns true if there was a reaction
+ local lines_before
+ lines_before=$(dmesg | wc -l)
+ stress-ng --cpu 2 --sched deadline --sched-period 100000000 \
+ --sched-deadline 100000000 --sched-runtime 20000000 -t 5 &
+ stress-ng --cpu 2 --sched rr --sched-prio 50 --cyclic 1 \
+ --cyclic-policy rr --cyclic-prio 50 -t 5 &
+ wait
+ dmesg | tail -n +$((lines_before + 1)) | grep -q "rv: monitor [a-z]\+ does not allow event"
+}
+
+echo 1 > monitors/deadline/enable
+echo printk > monitors/deadline/reactors
+
+! load || false
+
+echo nop > monitors/deadline/reactors
+echo 0 > monitors/deadline/enable
diff --git a/tools/testing/selftests/verification/test.d/rv_monitor_enable_disable.tc b/tools/testing/selftests/verification/test.d/rv_monitor_enable_disable.tc
new file mode 100644
index 000000000..61e2c8b54
--- /dev/null
+++ b/tools/testing/selftests/verification/test.d/rv_monitor_enable_disable.tc
@@ -0,0 +1,75 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# description: Test monitor enable/disable
+
+test_simple_monitor() {
+ local monitor="$1"
+ local prefix="$2" # nested monitors
+
+ echo 1 > "monitors/$prefix$monitor/enable"
+ grep -q "$monitor$" enabled_monitors
+
+ echo 0 > "monitors/$prefix$monitor/enable"
+ ! grep -q "$monitor$" enabled_monitors || false
+
+ echo "$monitor" >> enabled_monitors
+ grep -q 1 "monitors/$prefix$monitor/enable"
+
+ echo "!$monitor" >> enabled_monitors
+ grep -q 0 "monitors/$prefix$monitor/enable"
+}
+
+test_container_monitor() {
+ local monitor="$1"
+ local nested
+
+ echo 1 > "monitors/$monitor/enable"
+ grep -q "^$monitor$" enabled_monitors
+
+ for nested_dir in "monitors/$monitor"/*; do
+ [ -d "$nested_dir" ] || continue
+ nested=$(basename "$nested_dir")
+ grep -q "^$monitor:$nested$" enabled_monitors
+ done
+ test -n "$nested"
+
+ echo 0 > "monitors/$monitor/enable"
+ ! grep -q "^$monitor$" enabled_monitors || false
+
+ for nested_dir in "monitors/$monitor"/*; do
+ [ -d "$nested_dir" ] || continue
+ nested=$(basename "$nested_dir")
+ ! grep -q "^$monitor:$nested$" enabled_monitors || false
+ done
+
+ echo "$monitor" >> enabled_monitors
+ grep -q 1 "monitors/$monitor/enable"
+
+ for nested_dir in "monitors/$monitor"/*; do
+ [ -d "$nested_dir" ] || continue
+ nested=$(basename "$nested_dir")
+ grep -q "^$monitor:$nested$" enabled_monitors
+ done
+
+ echo "!$monitor" >> enabled_monitors
+ grep -q 0 "monitors/$monitor/enable"
+
+ for nested_dir in "monitors/$monitor"/*; do
+ [ -d "$nested_dir" ] || continue
+ nested=$(basename "$nested_dir")
+ test_simple_monitor "$nested" "$monitor/"
+ done
+}
+
+for monitor_dir in monitors/*; do
+ monitor=$(basename "$monitor_dir")
+
+ if find "$monitor_dir" -mindepth 1 -type d | grep -q .; then
+ test_container_monitor "$monitor"
+ else
+ test_simple_monitor "$monitor"
+ fi
+done
+
+! echo non_existent_monitor > enabled_monitors || false
+! grep -q "^non_existent_monitor$" enabled_monitors || false
diff --git a/tools/testing/selftests/verification/test.d/rv_monitor_reactor.tc b/tools/testing/selftests/verification/test.d/rv_monitor_reactor.tc
new file mode 100644
index 000000000..516a20971
--- /dev/null
+++ b/tools/testing/selftests/verification/test.d/rv_monitor_reactor.tc
@@ -0,0 +1,68 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# description: Test monitor reactor setting
+# requires: available_reactors
+
+test_monitor_reactor() {
+ local monitor="$1"
+ local prefix="$2" # nested monitors
+
+ while read -r reactor; do
+ [ "$reactor" = nop ] && continue
+
+ echo "$reactor" > "monitors/$prefix$monitor/reactors"
+ grep -q "\\[$reactor\\]" "monitors/$prefix$monitor/reactors"
+ done < available_reactors
+
+ echo nop > "monitors/$prefix$monitor/reactors"
+ grep -q "\\[nop\\]" "monitors/$prefix$monitor/reactors"
+}
+
+test_container_monitor() {
+ local monitor="$1"
+ local nested
+
+ while read -r reactor; do
+ [ "$reactor" = nop ] && continue
+
+ echo "$reactor" > "monitors/$monitor/reactors"
+ grep -q "\\[$reactor\\]" "monitors/$monitor/reactors"
+
+ for nested_dir in "monitors/$monitor"/*; do
+ [ -d "$nested_dir" ] || continue
+ nested=$(basename "$nested_dir")
+ grep -q "\\[$reactor\\]" "monitors/$monitor/$nested/reactors"
+ done
+ done < available_reactors
+ test -n "$nested"
+
+ echo nop > "monitors/$monitor/reactors"
+ grep -q "\\[nop\\]" "monitors/$monitor/reactors"
+
+ for nested_dir in "monitors/$monitor"/*; do
+ [ -d "$nested_dir" ] || continue
+ nested=$(basename "$nested_dir")
+ grep -q "\\[nop\\]" "monitors/$monitor/$nested/reactors"
+ done
+
+ for nested_dir in "monitors/$monitor"/*; do
+ [ -d "$nested_dir" ] || continue
+ nested=$(basename "$nested_dir")
+ test_monitor_reactor "$nested" "$monitor/"
+ done
+}
+
+for monitor_dir in monitors/*; do
+ monitor=$(basename "$monitor_dir")
+
+ if find "$monitor_dir" -mindepth 1 -type d | grep -q .; then
+ test_container_monitor "$monitor"
+ else
+ test_monitor_reactor "$monitor"
+ fi
+done
+
+monitor=$(ls /sys/kernel/tracing/rv/monitors -1 | head -n 1)
+test -f "monitors/$monitor/reactors"
+! echo non_existent_reactor > "monitors/$monitor/reactors" || false
+! grep -q "\\[non_existent_reactor\\]" "monitors/$monitor/reactors" || false
diff --git a/tools/testing/selftests/verification/test.d/rv_monitors_available.tc b/tools/testing/selftests/verification/test.d/rv_monitors_available.tc
new file mode 100644
index 000000000..e6a4a1410
--- /dev/null
+++ b/tools/testing/selftests/verification/test.d/rv_monitors_available.tc
@@ -0,0 +1,18 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# description: Check available monitors
+
+for monitor_dir in monitors/*; do
+ monitor=$(basename "$monitor_dir")
+
+ grep -q "^$monitor$" available_monitors
+ grep -q . "$monitor_dir"/desc
+
+ for nested_dir in "$monitor_dir"/*; do
+ [ -d "$nested_dir" ] || continue
+ nested=$(basename "$nested_dir")
+
+ grep -q "^$monitor:$nested$" available_monitors
+ grep -q . "$nested_dir"/desc
+ done
+done
diff --git a/tools/testing/selftests/verification/test.d/rv_stall.tc b/tools/testing/selftests/verification/test.d/rv_stall.tc
new file mode 100644
index 000000000..515a10263
--- /dev/null
+++ b/tools/testing/selftests/verification/test.d/rv_stall.tc
@@ -0,0 +1,33 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# description: Test stall monitor
+# requires: available_reactors stall:monitor printk:reactor stress-ng:program
+
+THRESHOLD=/sys/module/stall/parameters/threshold_jiffies
+ORIG_THRESHOLD=$(cat $THRESHOLD)
+trap 'echo $ORIG_THRESHOLD > $THRESHOLD' EXIT
+
+load() { # returns true if there was a reaction
+ local lines_before cpu
+ cpu=$(($(nproc) - 1))
+ lines_before=$(dmesg | wc -l)
+ stress-ng --cpu 1 --taskset "$cpu" --sched rr --sched-prio 1 -t 3 &
+ stress-ng --cpu 5 --taskset "$cpu" -t 3 &
+ wait
+ dmesg | tail -n +$((lines_before + 1)) | grep -q "rv: monitor stall does not allow event"
+}
+
+echo 5000 > $THRESHOLD
+echo 1 > monitors/stall/enable
+echo printk > monitors/stall/reactors
+
+! load || false
+
+echo 0 > monitors/stall/enable
+echo 70 > $THRESHOLD
+echo 1 > monitors/stall/enable
+
+load
+
+echo nop > monitors/stall/reactors
+echo 0 > monitors/stall/enable
diff --git a/tools/testing/selftests/verification/test.d/rv_wwnr_printk.tc b/tools/testing/selftests/verification/test.d/rv_wwnr_printk.tc
new file mode 100644
index 000000000..17e1edfb3
--- /dev/null
+++ b/tools/testing/selftests/verification/test.d/rv_wwnr_printk.tc
@@ -0,0 +1,52 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# description: Test wwnr monitor with printk reactor
+# requires: available_reactors wwnr:monitor printk:reactor stress-ng:program
+
+load() { # returns true if there was a reaction
+ local lines_before num load_pid ret
+ num=$((($(nproc) + 1) / 2))
+ lines_before=$(dmesg | wc -l)
+ stress-ng --cpu-sched "$num" --timer "$num" -t 5 -q &
+ load_pid=$!
+ timeout 5 dmesg -w | tail -n +$((lines_before + 1)) | \
+ grep -m 1 -q "rv: monitor wwnr does not allow event"
+ ret=$?
+ kill "$load_pid" || true
+ wait "$load_pid" || true
+ return $ret
+}
+
+# loads may flood the ringbuffer, wait for all pending printks (timeout at 2 minutes)
+wait_dmesg_flush() {
+ local last_before last_after
+ for _ in $(seq 400); do
+ last_before=$last_after
+ last_after=$(dmesg | grep "rv:" | tail -n 1 || true)
+ [ "$last_before" = "$last_after" ] && return 0
+ sleep .3
+ done
+ return 1
+}
+
+echo 1 > monitors/wwnr/enable
+echo printk > monitors/wwnr/reactors
+
+load
+
+echo 0 > monitoring_on
+wait_dmesg_flush
+
+! load || false
+echo 1 > monitoring_on
+
+load
+
+echo 0 > reacting_on
+wait_dmesg_flush
+
+! load || false
+echo 1 > reacting_on
+
+echo nop > monitors/wwnr/reactors
+echo 0 > monitors/wwnr/enable
diff --git a/tools/testing/selftests/verification/verificationtest-ktap b/tools/testing/selftests/verification/verificationtest-ktap
new file mode 100755
index 000000000..18f7fe324
--- /dev/null
+++ b/tools/testing/selftests/verification/verificationtest-ktap
@@ -0,0 +1,8 @@
+#!/bin/sh -e
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# ftracetest-ktap: Wrapper to integrate ftracetest with the kselftest runner
+#
+# Copyright (C) Arm Ltd., 2023
+
+../ftrace/ftracetest -K -v --rv ../verification