summaryrefslogtreecommitdiff
path: root/tools/testing/selftests
diff options
context:
space:
mode:
authorChristian Brauner <brauner@kernel.org>2026-09-25 18:20:49 +0200
committerChristian Brauner <brauner@kernel.org>2026-09-25 18:20:49 +0200
commit3a797099a68280f4c275823e4564c3055639b3f0 (patch)
treee73f7121f631af8cc73baabfef0a8570062a8789 /tools/testing/selftests
parent04c9480230922c7295ff89e538da04c7eb925d78 (diff)
parent09c6d98c822f0a531e25a0cd8594cc46fda995fd (diff)
downloadlinux-next-3a797099a68280f4c275823e4564c3055639b3f0.tar.gz
linux-next-3a797099a68280f4c275823e4564c3055639b3f0.zip
Merge branch 'vfs-7.4.shared.super' into vfs.all
Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'tools/testing/selftests')
-rw-r--r--tools/testing/selftests/net/Makefile1
-rw-r--r--tools/testing/selftests/net/af_unix/msg_oob.c67
-rwxr-xr-xtools/testing/selftests/net/cork_fragsize.py187
-rwxr-xr-xtools/testing/selftests/net/fib_nexthops.sh28
-rw-r--r--tools/testing/selftests/net/mptcp/mptcp_connect.c4
-rw-r--r--tools/testing/selftests/net/mptcp/mptcp_lib.sh26
-rwxr-xr-xtools/testing/selftests/net/pmtu.sh2
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/lost_exception_test.c11
-rw-r--r--tools/testing/selftests/powerpc/tm/tm-signal-context-force-tm.c4
-rw-r--r--tools/testing/selftests/powerpc/tm/tm.h8
-rw-r--r--tools/testing/selftests/riscv/cfi/cfi_rv_test.h2
-rw-r--r--tools/testing/selftests/riscv/hwprobe/hwprobe.c20
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/actions/gact-rollback.json78
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/filters/route.json210
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/qdiscs/ets.json4
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/qdiscs/pfifo_fast.json204
-rw-r--r--tools/testing/selftests/ublk/Makefile2
-rwxr-xr-xtools/testing/selftests/ublk/test_recover_03.sh5
18 files changed, 840 insertions, 23 deletions
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index 517c09d60bef..3ee3378f8b26 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -25,6 +25,7 @@ TEST_PROGS := \
cmsg_so_mark.sh \
cmsg_so_priority.sh \
cmsg_time.sh \
+ cork_fragsize.py \
double_udp_encap.sh \
drop_monitor_tests.sh \
ecmp_rehash.sh \
diff --git a/tools/testing/selftests/net/af_unix/msg_oob.c b/tools/testing/selftests/net/af_unix/msg_oob.c
index 1b499d56656c..f051d79f7a8e 100644
--- a/tools/testing/selftests/net/af_unix/msg_oob.c
+++ b/tools/testing/selftests/net/af_unix/msg_oob.c
@@ -290,6 +290,25 @@ static void __setinlinepair(struct __test_metadata *_metadata,
}
}
+static void __setblockingpair(struct __test_metadata *_metadata,
+ FIXTURE_DATA(msg_oob) *self)
+{
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ int ret, old_flags, flags;
+
+ old_flags = fcntl(self->fd[i * 2 + 1], F_GETFL, 0);
+ ASSERT_NE(-1, old_flags);
+
+ ret = fcntl(self->fd[i * 2 + 1], F_SETFL, old_flags & ~O_NONBLOCK);
+ ASSERT_EQ(0, ret);
+
+ flags = fcntl(self->fd[i * 2 + 1], F_GETFL, 0);
+ ASSERT_EQ(old_flags & ~O_NONBLOCK, flags);
+ }
+}
+
static void __siocatmarkpair(struct __test_metadata *_metadata,
FIXTURE_DATA(msg_oob) *self,
bool oob_head)
@@ -347,6 +366,9 @@ static void __resetpair(struct __test_metadata *_metadata,
#define setinlinepair() \
__setinlinepair(_metadata, self)
+#define setblockingpair() \
+ __setblockingpair(_metadata, self)
+
#define resetpair(reset) \
__resetpair(_metadata, self, variant, reset)
@@ -888,4 +910,49 @@ TEST_F(msg_oob, inline_ex_oob_siocatmark)
resetpair(true);
}
+TEST_F(msg_oob, zero_buf_oob)
+{
+ sendpair("a", 1, MSG_OOB);
+ recvpair("", 0, 0, 0);
+}
+
+TEST_F(msg_oob, zero_buf_oob_blocking)
+{
+ sendpair("a", 1, MSG_OOB);
+ setblockingpair();
+ recvpair("", 0, 0, 0);
+}
+
+TEST_F(msg_oob, zero_buf_non_oob_oob)
+{
+ sendpair("ab", 2, MSG_OOB);
+ recvpair("", 0, 0, 0);
+}
+
+TEST_F(msg_oob, zero_buf_non_oob_oob_blocking)
+{
+ sendpair("ab", 2, MSG_OOB);
+ setblockingpair();
+ recvpair("", 0, 0, 0);
+}
+
+TEST_F(msg_oob, zero_buf_ex_oob_oob)
+{
+ sendpair("a", 1, MSG_OOB);
+ recvpair("a", 1, 1, MSG_OOB);
+
+ sendpair("b", 1, MSG_OOB);
+ recvpair("", 0, 0, 0);
+}
+
+TEST_F(msg_oob, zero_buf_ex_oob_oob_blocking)
+{
+ sendpair("a", 1, MSG_OOB);
+ recvpair("a", 1, 1, MSG_OOB);
+
+ sendpair("b", 1, MSG_OOB);
+ setblockingpair();
+ recvpair("", 0, 0, 0);
+}
+
TEST_HARNESS_MAIN
diff --git a/tools/testing/selftests/net/cork_fragsize.py b/tools/testing/selftests/net/cork_fragsize.py
new file mode 100755
index 000000000000..7afd643d07ec
--- /dev/null
+++ b/tools/testing/selftests/net/cork_fragsize.py
@@ -0,0 +1,187 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+
+'''Test possible UDP length overflow in udp_send_skb/udp_v6_send_skb.'''
+
+import errno
+import gzip
+import os
+import socket
+import struct
+import subprocess
+from contextlib import contextmanager
+
+from lib.py import (
+ KsftNamedVariant,
+ KsftSkipEx,
+ NetNS,
+ NetNSEnter,
+ defer,
+ ip,
+ ksft_eq,
+ ksft_exit,
+ ksft_pr,
+ ksft_raises,
+ ksft_run,
+ ksft_true,
+ ksft_variants,
+)
+
+IP_MTU_DISCOVER = 10
+IP_PMTUDISC_PROBE = 3
+IPV6_MTU_DISCOVER = 23
+IPV6_PMTUDISC_DO = 2
+IPV6_PMTUDISC_PROBE = 3
+IPV6_TLV_JUMBO = 194
+
+
+def check_kernel_config(option: str) -> bool | None:
+ '''
+ Check whether the option is enabled in the config of the running kernel.
+ Returns None if the config is not found; otherwise returns True/False
+ depending on the option value in the config.
+ '''
+
+ for filename, method in [
+ ('/proc/config.gz', gzip.open),
+ (f'/boot/config-{os.uname().release}', open),
+ ]:
+ try:
+ with method(filename, 'rt') as config:
+ for line in config:
+ if line.rstrip() == f'{option}=y':
+ return True
+ return False
+ except OSError:
+ continue
+ return None
+
+
+def assert_debug_kernel() -> None:
+ '''
+ Skip the test if CONFIG_DEBUG_NET is not set in the kernel config.
+ '''
+
+ res = check_kernel_config('CONFIG_DEBUG_NET')
+ if res is None:
+ ksft_pr("WARN: Can't read kernel config; assuming debug kernel, and running the test")
+ elif not res:
+ raise KsftSkipEx('CONFIG_DEBUG_NET is not set')
+
+
+def check_dmesg_clean(func: str) -> bool:
+ '''
+ Check if the given function produced a WARN in dmesg.
+ '''
+
+ with subprocess.Popen(['dmesg'], stdout=subprocess.PIPE) as dmesg:
+ res = subprocess.run(['grep', '-q', f'WARNING:.*{func}'], stdin=dmesg.stdout, check=False)
+ return res.returncode != 0 and dmesg.returncode == 0
+
+
+@contextmanager
+def dummy_netdev(ns: NetNS, mtu: int, ipv6: bool) -> None:
+ '''
+ Create a dummy netdev inside the given namespace, and tune it for the test.
+ '''
+
+ ip('link add dummy type dummy', ns=ns)
+ with defer(ip, 'link del dummy', ns=ns):
+ ip(f'link set dummy mtu {mtu}', ns=ns)
+ ip('link set dummy up', ns=ns)
+ flag = '-6' if ipv6 else ''
+ nodad = 'nodad' if ipv6 else ''
+ local = 'fd00::1/64' if ipv6 else '10.0.0.1/24'
+ remote = 'fd00::2' if ipv6 else '10.0.0.2'
+ ip(f'{flag} addr add {local} dev dummy {nodad}', ns=ns)
+ ip(f'{flag} neigh add {remote} lladdr 02:00:00:00:00:02 dev dummy nud permanent', ns=ns)
+ yield
+
+
+@ksft_variants([
+ KsftNamedVariant(
+ 'ipv6',
+ True,
+ socket.AF_INET6,
+ (socket.IPPROTO_IPV6, IPV6_MTU_DISCOVER, IPV6_PMTUDISC_DO),
+ 'fd00::2',
+ 'udp_v6_send_skb',
+ ),
+ KsftNamedVariant(
+ 'ipv4',
+ False,
+ socket.AF_INET,
+ (socket.IPPROTO_IP, IP_MTU_DISCOVER, IP_PMTUDISC_PROBE),
+ '10.0.0.2',
+ 'udp_send_skb',
+ ),
+])
+def test_udp(
+ ipv6: bool,
+ af: socket.AddressFamily,
+ sockopts: tuple[int, int, int],
+ destip: str,
+ func: str
+) -> None:
+ '''
+ Test that sending an oversized UDP packet over a UDP socket doesn't overflow
+ the 16-bit length field in the UDP header, which could happen on older
+ kernels in udp_send_skb/udp_v6_send_skb.
+
+ IPv4: The packet will be dropped with EMSGSIZE, but the overflow could
+ happen before it happens. The only way to test this is to check dmesg on
+ CONFIG_DEBUG_NET=y kernels that have udp_set_len_short with the warning.
+
+ IPv6: The packet will be dropped with EMSGSIZE on fixed kernels, and will be
+ sent corrupted on older kernels. Test both: sendto must return EMSGSIZE, and
+ dmesg must be clean of warnings on CONFIG_DEBUG_NET=y kernels.
+ '''
+
+ if not ipv6:
+ assert_debug_kernel()
+
+ with (
+ NetNS() as ns,
+ dummy_netdev(ns, 65556 + 20 * ipv6, ipv6),
+ NetNSEnter(ns),
+ socket.socket(af, socket.SOCK_DGRAM) as fd,
+ ):
+ fd.setsockopt(*sockopts)
+ with ksft_raises(OSError) as e:
+ fd.sendto(b' ' * 65528, (destip, 1234))
+ # IPv6: EMSGSIZE happens on kernels with the fix.
+ # IPv4: EMSGSIZE happens on both fixed and unfixed kernels, after the
+ # WARN is printed - ignore it and rely on the dmesg check.
+ if e.exception is not None:
+ ksft_eq(e.exception.errno, errno.EMSGSIZE)
+
+ ksft_true(check_dmesg_clean(func), 'WARNING detected in dmesg')
+
+
+def test_ipv6_jumbo() -> None:
+ '''
+ Test that sending UDP jumbograms over a raw IPv6 socket works, despite
+ having the fix for oversized UDP packets. sendto must not raise an OSError
+ exception (when raised, the test fails automatically).
+ '''
+
+ with (
+ NetNS() as ns,
+ dummy_netdev(ns, 65584, True),
+ NetNSEnter(ns),
+ socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_UDP) as fd,
+ ):
+ hopopts = struct.pack('!BBBBI', 0, 0, IPV6_TLV_JUMBO, 4, 65544)
+ fd.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_HOPOPTS, hopopts)
+ fd.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_CHECKSUM, 6)
+ fd.setsockopt(socket.IPPROTO_IPV6, IPV6_MTU_DISCOVER, IPV6_PMTUDISC_PROBE)
+ udp = struct.pack('!HHHH', 1234, 1234, 0, 0) + b' ' * 65528
+ fd.sendto(udp, ('fd00::2', 0))
+
+
+if __name__ == "__main__":
+ ksft_run([
+ test_udp,
+ test_ipv6_jumbo,
+ ])
+ ksft_exit()
diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh
index 3d347126730a..431d7bed7622 100755
--- a/tools/testing/selftests/net/fib_nexthops.sh
+++ b/tools/testing/selftests/net/fib_nexthops.sh
@@ -533,6 +533,20 @@ ipv6_fdb_grp_fcnal()
run_cmd "$BRIDGE fdb add 02:02:00:00:00:14 dev vx10 nhid 61 self"
log_test $? 255 "Fdb mac add with nexthop"
+ # fdb entries with a nexthop group cannot be aged out
+ run_cmd "$BRIDGE fdb add 02:02:00:00:00:15 dev vx10 nhid 102 self static"
+ log_test $? 0 "Fdb mac add with nexthop group and static state"
+
+ run_cmd "$BRIDGE fdb add 02:02:00:00:00:16 dev vx10 nhid 102 self dynamic"
+ log_test $? 255 "Fdb mac add with nexthop group and dynamic state"
+
+ run_cmd "$BRIDGE fdb add 02:02:00:00:00:17 dev vx10 nhid 102 self"
+ run_cmd "$BRIDGE fdb replace 02:02:00:00:00:17 dev vx10 dst 2001:db8:91::11 self dynamic"
+ log_test $? 255 "Fdb mac replace with nexthop group and dynamic state"
+
+ run_cmd "$BRIDGE fdb append 02:02:00:00:00:17 dev vx10 dst 2001:db8:91::11 self dynamic"
+ log_test $? 255 "Fdb mac append with nexthop group and dynamic state"
+
run_cmd "$IP -6 ro add 2001:db8:101::1/128 nhid 66"
log_test $? 2 "Route add with fdb nexthop"
@@ -669,6 +683,20 @@ ipv4_fdb_grp_fcnal()
run_cmd "$BRIDGE fdb add 02:02:00:00:00:14 dev vx10 nhid 12 self"
log_test $? 255 "Fdb mac add with nexthop"
+ # fdb entries with a nexthop group cannot be aged out
+ run_cmd "$BRIDGE fdb add 02:02:00:00:00:15 dev vx10 nhid 102 self static"
+ log_test $? 0 "Fdb mac add with nexthop group and static state"
+
+ run_cmd "$BRIDGE fdb add 02:02:00:00:00:16 dev vx10 nhid 102 self dynamic"
+ log_test $? 255 "Fdb mac add with nexthop group and dynamic state"
+
+ run_cmd "$BRIDGE fdb add 02:02:00:00:00:17 dev vx10 nhid 102 self"
+ run_cmd "$BRIDGE fdb replace 02:02:00:00:00:17 dev vx10 dst 10.0.0.3 self dynamic"
+ log_test $? 255 "Fdb mac replace with nexthop group and dynamic state"
+
+ run_cmd "$BRIDGE fdb append 02:02:00:00:00:17 dev vx10 dst 10.0.0.3 self dynamic"
+ log_test $? 255 "Fdb mac append with nexthop group and dynamic state"
+
run_cmd "$IP ro add 172.16.0.0/22 nhid 16"
log_test $? 2 "Route add with fdb nexthop"
diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c
index ea4cb6c1bd5e..178d98d91fea 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
@@ -381,6 +381,9 @@ static int sock_connect_mptcp(const char * const remoteaddr,
hints.ai_family = pf;
+ /* Keep the resolved address alive for the whole execution: it is
+ * used again when reconnecting, and will be released at exit time.
+ */
xgetaddrinfo(remoteaddr, port, &hints, &addr);
for (a = addr; a; a = a->ai_next) {
sock = socket(a->ai_family, a->ai_socktype, proto);
@@ -421,7 +424,6 @@ static int sock_connect_mptcp(const char * const remoteaddr,
sock = -1;
}
- freeaddrinfo(addr);
if (sock != -1)
SOCK_TEST_TCPULP(sock, proto);
return sock;
diff --git a/tools/testing/selftests/net/mptcp/mptcp_lib.sh b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
index 5ef6033775c8..b9d14647f401 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
@@ -108,12 +108,14 @@ mptcp_lib_pr_info() {
mptcp_lib_pr_nstat() {
local ns="${1}"
- local hist="/tmp/${ns}.out"
+ local cache="/tmp/${ns}.out"
+ local hist="/tmp/${ns}.nstat"
- if [ -f "${hist}" ]; then
- awk '$2 != 0 { print " "$0 }' "${hist}"
+ if [ -f "${cache}" ]; then
+ awk '$2 != 0 { print " "$0 }' "${cache}"
else
- ip netns exec "${ns}" nstat -as | grep Tcp
+ NSTAT_HISTORY="${hist}" ip netns exec "${ns}" nstat -s |
+ grep Tcp
fi
}
@@ -414,19 +416,21 @@ mptcp_lib_nstat_get() {
}
# $1: ns, $2: MIB counter
-# Get the counter from the history (mptcp_lib_nstat_{init,get}()) if available.
-# If not, get the counter from nstat ignoring any history.
+# Get the counter from the cache (mptcp_lib_nstat_{init,get}()) if available.
+# If not, get the counter from nstat ignoring any cache, but using the history.
mptcp_lib_get_counter() {
local ns="${1}"
local counter="${2}"
- local hist="/tmp/${ns}.out"
+ local cache="/tmp/${ns}.out"
+ local hist="/tmp/${ns}.nstat"
local count
- if [[ -s "${hist}" && "${counter}" == *"Tcp"* ]]; then
- count=$(awk "/^${counter} / {print \$2; exit}" "${hist}")
+ if [[ -s "${cache}" && "${counter}" == *"Tcp"* ]]; then
+ count=$(awk "/^${counter} / {print \$2; exit}" "${cache}")
else
- count=$(ip netns exec "${ns}" nstat -asz "${counter}" |
- awk 'NR==1 {next} {print $2}')
+ count=$(NSTAT_HISTORY="${hist}" ip netns exec "${ns}" \
+ nstat -sz "${counter}" |
+ awk 'NR==1 {next} {print $2}')
fi
if [ -z "${count}" ]; then
mptcp_lib_fail_if_expected_feature "${counter} counter"
diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh
index a3323c21f001..c7cd271714ef 100755
--- a/tools/testing/selftests/net/pmtu.sh
+++ b/tools/testing/selftests/net/pmtu.sh
@@ -1457,7 +1457,7 @@ test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception() {
mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000))
run_cmd ${ns_c} ${ping} -q -M want -i 0.1 -c 10 -s $((${ll_mtu} + 500)) ${dst} || return 1
- run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s $((${ll_mtu} + 500)) ${dst} || return 1
+ run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -c 10 -s $((${ll_mtu} + 500)) ${dst} || return 1
# Check that exceptions were created
pmtu="$(route_get_dst_pmtu_from_exception "${ns_c}" ${dst})"
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/lost_exception_test.c b/tools/testing/selftests/powerpc/pmu/ebb/lost_exception_test.c
index ba2681a12cc7..9be5945f3b1f 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/lost_exception_test.c
+++ b/tools/testing/selftests/powerpc/pmu/ebb/lost_exception_test.c
@@ -8,6 +8,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
+#include <time.h>
#include "ebb.h"
@@ -22,6 +23,7 @@ static int test_body(void)
{
int i, orig_period, max_period;
struct event event;
+ struct timespec ts = { .tv_sec = 0, .tv_nsec = 1 };
SKIP_IF(!ebb_is_supported());
@@ -57,10 +59,15 @@ static int test_body(void)
* kernel to decide our timeslice is up and context switch to
* the other thread. When we come back our EBB will have been
* lost and we'll spin in this while loop forever.
+ *
+ * Use nanosleep(0) instead of sched_yield() to guarantee a
+ * context switch to the eat_cpu child regardless of the
+ * eligibility state. sched_yield() via yield_task_fair() may
+ * become a no-op when the task is ineligible (vruntime ahead
+ * of avg_vruntime), preventing the required context switch.
*/
-
for (i = 0; i < 100000; i++)
- sched_yield();
+ nanosleep(&ts, NULL);
/* Change the sample period slightly to try and hit the race */
if (sample_period >= (orig_period + 200))
diff --git a/tools/testing/selftests/powerpc/tm/tm-signal-context-force-tm.c b/tools/testing/selftests/powerpc/tm/tm-signal-context-force-tm.c
index 0a4bc479ae39..5dc0f12f467d 100644
--- a/tools/testing/selftests/powerpc/tm/tm-signal-context-force-tm.c
+++ b/tools/testing/selftests/powerpc/tm/tm-signal-context-force-tm.c
@@ -60,7 +60,7 @@ void usr_signal_handler(int signo, siginfo_t *si, void *uc)
ucp->uc_link = mmap(NULL, sizeof(ucontext_t),
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
- if (ucp->uc_link == (void *)-1) {
+ if (ucp->uc_link == MAP_FAILED) {
perror("Mmap failed");
exit(-1);
}
@@ -129,7 +129,7 @@ void tm_trap_test(void)
ss.ss_size = SIGSTKSZ;
ss.ss_flags = 0;
- if (ss.ss_sp == (void *)-1) {
+ if (ss.ss_sp == MAP_FAILED) {
perror("mmap error\n");
exit(-1);
}
diff --git a/tools/testing/selftests/powerpc/tm/tm.h b/tools/testing/selftests/powerpc/tm/tm.h
index c03c6e778876..6024ce4ba6ff 100644
--- a/tools/testing/selftests/powerpc/tm/tm.h
+++ b/tools/testing/selftests/powerpc/tm/tm.h
@@ -105,8 +105,12 @@ static inline bool failure_is_nesting(void)
static inline int tcheck(void)
{
long cr;
- asm volatile ("tcheck 0" : "=r"(cr) : : "cr0");
- return (cr >> 28) & 4;
+ asm volatile("tcheck 0;"
+ "mfcr %0;"
+ : "=r"(cr)
+ :
+ : "cr0");
+ return (cr >> 28) & 0xf;
}
static inline bool tcheck_doomed(void)
diff --git a/tools/testing/selftests/riscv/cfi/cfi_rv_test.h b/tools/testing/selftests/riscv/cfi/cfi_rv_test.h
index 1c8043f2b778..184df6903d01 100644
--- a/tools/testing/selftests/riscv/cfi/cfi_rv_test.h
+++ b/tools/testing/selftests/riscv/cfi/cfi_rv_test.h
@@ -56,7 +56,7 @@
#define CSR_SSP 0x011
-#ifdef __ASSEMBLY__
+#ifdef __ASSEMBLER__
#define __ASM_STR(x) x
#else
#define __ASM_STR(x) #x
diff --git a/tools/testing/selftests/riscv/hwprobe/hwprobe.c b/tools/testing/selftests/riscv/hwprobe/hwprobe.c
index 54c435af9923..eca4441ee77f 100644
--- a/tools/testing/selftests/riscv/hwprobe/hwprobe.c
+++ b/tools/testing/selftests/riscv/hwprobe/hwprobe.c
@@ -9,7 +9,7 @@ int main(int argc, char **argv)
long out;
ksft_print_header();
- ksft_set_plan(5);
+ ksft_set_plan(6);
/* Fake the CPU_SET ops. */
cpus = -1;
@@ -62,5 +62,23 @@ int main(int argc, char **argv)
pairs[1].key == 1 && pairs[1].value != 0xAAAA,
"Unknown key overwritten with -1 and doesn't block other elements\n");
+ pairs[0].key = RISCV_HWPROBE_KEY_IMA_EXT_0;
+ out = riscv_hwprobe(pairs, 1, 0, 0, 0);
+ if (out != 0)
+ ksft_exit_fail_msg("hwprobe(IMA_EXT_0) failed with %ld\n", out);
+
+ /*
+ * The RISC-V ISA manual specifies that Zfh implies Zfhmin and Zvfh
+ * implies Zvfhmin, so hwprobe must report the implied subset
+ * extensions whenever the supersets are present.
+ */
+ if ((pairs[0].value & RISCV_HWPROBE_EXT_ZFH) &&
+ !(pairs[0].value & RISCV_HWPROBE_EXT_ZFHMIN))
+ ksft_exit_fail_msg("Zfh reported without implied Zfhmin\n");
+ if ((pairs[0].value & RISCV_HWPROBE_EXT_ZVFH) &&
+ !(pairs[0].value & RISCV_HWPROBE_EXT_ZVFHMIN))
+ ksft_exit_fail_msg("Zvfh reported without implied Zvfhmin\n");
+ ksft_test_result_pass("Zfh/Zvfh imply Zfhmin/Zvfhmin\n");
+
ksft_finished();
}
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/gact-rollback.json b/tools/testing/selftests/tc-testing/tc-tests/actions/gact-rollback.json
new file mode 100644
index 000000000000..e92a4180db68
--- /dev/null
+++ b/tools/testing/selftests/tc-testing/tc-tests/actions/gact-rollback.json
@@ -0,0 +1,78 @@
+[
+ {
+ "id": "e3b1",
+ "name": "Failed action batch releases a bound action reference",
+ "category": [
+ "actions",
+ "gact"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [
+ "$TC qdisc add dev $DEV1 ingress",
+ "$TC actions add action pass index 1",
+ "$TC filter add dev $DEV1 protocol all ingress prio 1 matchall action gact index 1"
+ ],
+ "cmdUnderTest": "$TC actions replace action pass index 1 action goto chain 42 index 3",
+ "expExitCode": "255",
+ "verifyCmd": "$TC actions ls action gact",
+ "matchPattern": "total acts 1.*index 1 ref 2 bind 1",
+ "matchCount": "1",
+ "teardown": [
+ "$TC qdisc del dev $DEV1 ingress"
+ ]
+ },
+ {
+ "id": "e3b2",
+ "name": "Failed action batch releases entries after a bound action",
+ "category": [
+ "actions",
+ "gact"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [
+ "$TC qdisc add dev $DEV1 ingress",
+ "$TC actions add action pass index 1",
+ "$TC filter add dev $DEV1 protocol all ingress prio 1 matchall action gact index 1",
+ [
+ "$TC actions replace action pass index 1 action pass index 2 action goto chain 42 index 3",
+ 255
+ ]
+ ],
+ "cmdUnderTest": "$TC actions add action pass index 2",
+ "expExitCode": "0",
+ "verifyCmd": "$TC actions ls action gact",
+ "matchPattern": "total acts 2.*index 1 ref 2 bind 1.*index 2 ref 1 bind 0",
+ "matchCount": "1",
+ "teardown": [
+ "$TC qdisc del dev $DEV1 ingress"
+ ]
+ },
+ {
+ "id": "e3b3",
+ "name": "Failed action batch releases repeated references to a bound action",
+ "category": [
+ "actions",
+ "gact"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [
+ "$TC qdisc add dev $DEV1 ingress",
+ "$TC actions add action pass index 1",
+ "$TC filter add dev $DEV1 protocol all ingress prio 1 matchall action gact index 1"
+ ],
+ "cmdUnderTest": "$TC actions replace action pass index 1 action pass index 1 action goto chain 42 index 3",
+ "expExitCode": "255",
+ "verifyCmd": "$TC actions ls action gact",
+ "matchPattern": "total acts 1.*index 1 ref 2 bind 1",
+ "matchCount": "1",
+ "teardown": [
+ "$TC qdisc del dev $DEV1 ingress"
+ ]
+ }
+]
diff --git a/tools/testing/selftests/tc-testing/tc-tests/filters/route.json b/tools/testing/selftests/tc-testing/tc-tests/filters/route.json
index 05cedca67cca..2d5843aebd72 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/filters/route.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/filters/route.json
@@ -202,5 +202,215 @@
"teardown": [
"$TC qdisc del dev $DEV1 parent root drr"
]
+ },
+ {
+ "id": "a7d2",
+ "name": "Delete a route filter that was moved to another bucket",
+ "category": [
+ "filter",
+ "route"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [
+ "$TC qdisc add dev $DEV1 ingress",
+ "$TC filter add dev $DEV1 parent ffff: protocol ip prio 100 route from 1 to 1 classid 1:1",
+ "$TC filter change dev $DEV1 parent ffff: protocol ip prio 100 handle 0x10001 route from 1 to 2 classid 1:1",
+ "$TC filter add dev $DEV1 parent ffff: protocol ip prio 200 route from 5 to 5 classid 1:5"
+ ],
+ "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: protocol ip prio 100 handle 0x10002 route from 1 to 2",
+ "expExitCode": "0",
+ "verifyCmd": "$TC -j filter show dev $DEV1 parent ffff:",
+ "matchJSON": [
+ {
+ "protocol": "ip",
+ "pref": 200,
+ "kind": "route",
+ "chain": 0
+ },
+ {
+ "protocol": "ip",
+ "pref": 200,
+ "kind": "route",
+ "chain": 0,
+ "options": {
+ "fh": "0x50005",
+ "flowid": "1:5"
+ }
+ }
+ ],
+ "teardown": [
+ "$TC qdisc del dev $DEV1 ingress"
+ ]
+ },
+ {
+ "id": "c05a",
+ "name": "Try to change a route filter onto an already used handle",
+ "category": [
+ "filter",
+ "route"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [
+ "$TC qdisc add dev $DEV1 ingress",
+ "$TC filter add dev $DEV1 parent ffff: protocol ip prio 100 route from 1 to 1 classid 1:1 action ok",
+ "$TC filter add dev $DEV1 parent ffff: protocol ip prio 100 route from 2 to 2 classid 1:2 action drop"
+ ],
+ "cmdUnderTest": "$TC filter change dev $DEV1 parent ffff: protocol ip prio 100 handle 0x10001 route from 2 to 2 classid 1:1 action ok",
+ "expExitCode": "2",
+ "verifyCmd": "$TC -j filter show dev $DEV1 parent ffff:",
+ "matchJSON": [
+ {
+ "protocol": "ip",
+ "pref": 100,
+ "kind": "route",
+ "chain": 0
+ },
+ {
+ "protocol": "ip",
+ "pref": 100,
+ "kind": "route",
+ "chain": 0,
+ "options": {
+ "fh": "0x10001",
+ "flowid": "1:1",
+ "actions": [
+ {
+ "order": 1,
+ "kind": "gact",
+ "control_action": {
+ "type": "pass"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "protocol": "ip",
+ "pref": 100,
+ "kind": "route",
+ "chain": 0,
+ "options": {
+ "fh": "0x20002",
+ "flowid": "1:2",
+ "actions": [
+ {
+ "order": 1,
+ "kind": "gact",
+ "control_action": {
+ "type": "drop"
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "teardown": [
+ "$TC qdisc del dev $DEV1 ingress"
+ ]
+ },
+ {
+ "id": "3f21",
+ "name": "Replace a route filter that shares its key with another filter",
+ "category": [
+ "filter",
+ "route"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [
+ "$TC qdisc add dev $DEV1 ingress",
+ "$TC filter add dev $DEV1 parent ffff: protocol ip prio 100 handle 0x10101 route from 1 to 1 classid 1:1",
+ "$TC filter add dev $DEV1 parent ffff: protocol ip prio 100 handle 0x10201 route from 1 to 1 classid 1:2"
+ ],
+ "cmdUnderTest": "$TC filter replace dev $DEV1 parent ffff: protocol ip prio 100 handle 0x10101 route from 1 to 1 classid 1:9",
+ "expExitCode": "0",
+ "verifyCmd": "$TC -j filter show dev $DEV1 parent ffff:",
+ "matchJSON": [
+ {
+ "protocol": "ip",
+ "pref": 100,
+ "kind": "route",
+ "chain": 0
+ },
+ {
+ "protocol": "ip",
+ "pref": 100,
+ "kind": "route",
+ "chain": 0,
+ "options": {
+ "fh": "0x10101",
+ "flowid": "1:9"
+ }
+ },
+ {
+ "protocol": "ip",
+ "pref": 100,
+ "kind": "route",
+ "chain": 0,
+ "options": {
+ "fh": "0x10201",
+ "flowid": "1:2"
+ }
+ }
+ ],
+ "teardown": [
+ "$TC qdisc del dev $DEV1 ingress"
+ ]
+ },
+ {
+ "id": "9d0e",
+ "name": "Replace both route filters sharing a key",
+ "category": [
+ "filter",
+ "route"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [
+ "$TC qdisc add dev $DEV1 ingress",
+ "$TC filter add dev $DEV1 parent ffff: protocol ip prio 100 handle 0x10101 route from 1 to 1 classid 1:1",
+ "$TC filter add dev $DEV1 parent ffff: protocol ip prio 100 handle 0x10201 route from 1 to 1 classid 1:2",
+ "$TC filter replace dev $DEV1 parent ffff: protocol ip prio 100 handle 0x10101 route from 1 to 1 classid 1:9"
+ ],
+ "cmdUnderTest": "$TC filter replace dev $DEV1 parent ffff: protocol ip prio 100 handle 0x10201 route from 1 to 1 classid 1:8",
+ "expExitCode": "0",
+ "verifyCmd": "$TC -j filter show dev $DEV1 parent ffff:",
+ "matchJSON": [
+ {
+ "protocol": "ip",
+ "pref": 100,
+ "kind": "route",
+ "chain": 0
+ },
+ {
+ "protocol": "ip",
+ "pref": 100,
+ "kind": "route",
+ "chain": 0,
+ "options": {
+ "fh": "0x10101",
+ "flowid": "1:9"
+ }
+ },
+ {
+ "protocol": "ip",
+ "pref": 100,
+ "kind": "route",
+ "chain": 0,
+ "options": {
+ "fh": "0x10201",
+ "flowid": "1:8"
+ }
+ }
+ ],
+ "teardown": [
+ "$TC qdisc del dev $DEV1 ingress"
+ ]
}
]
diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/ets.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/ets.json
index ee09e6d6fdf3..d2eab61c099a 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/ets.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/ets.json
@@ -987,7 +987,7 @@
},
{
"id": "41f5",
- "name": "ETS offload where the sum of quanta wraps u32",
+ "name": "ETS offload with out-of-range quanta clamped",
"category": [
"qdisc",
"ets"
@@ -1002,7 +1002,7 @@
"cmdUnderTest": "$TC qdisc add dev $ETH root ets quanta 4294967294 1 1",
"expExitCode": "0",
"verifyCmd": "$TC qdisc show dev $ETH",
- "matchPattern": "qdisc ets .*bands 3 quanta 4294967294 1 1",
+ "matchPattern": "qdisc ets .*bands 3 quanta 1048576 256 256",
"matchCount": "1",
"teardown": [
"echo \"1\" > /sys/bus/netdevsim/del_device"
diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/pfifo_fast.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/pfifo_fast.json
index 30da27fe8806..a6e25e76ecb1 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/pfifo_fast.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/pfifo_fast.json
@@ -105,5 +105,209 @@
"teardown": [
"$TC qdisc del dev $DUMMY handle 1: root"
]
+ },
+ {
+ "id": "dbe3",
+ "name": "Set tx_queue_len to S16_MAX boundary (32767 accepted)",
+ "category": [
+ "qdisc",
+ "pfifo_fast"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [],
+ "cmdUnderTest": "$IP link set dev $DUMMY txqueuelen 32767",
+ "expExitCode": "0",
+ "verifyCmd": "$IP link show dev $DUMMY",
+ "matchPattern": "qlen 32767$",
+ "matchCount": "1",
+ "teardown": []
+ },
+ {
+ "id": "b50e",
+ "name": "Reject tx_queue_len above S16_MAX at set time (32768)",
+ "category": [
+ "qdisc",
+ "pfifo_fast"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [],
+ "cmdUnderTest": "$IP link set dev $DUMMY txqueuelen 32768",
+ "expExitCode": "2",
+ "verifyCmd": "$IP link show dev $DUMMY",
+ "matchPattern": "qlen 1000$",
+ "matchCount": "1",
+ "teardown": []
+ },
+ {
+ "id": "40f8",
+ "name": "Reject tx_queue_len above S16_MAX via sysfs (32768)",
+ "category": [
+ "qdisc",
+ "pfifo_fast"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [],
+ "cmdUnderTest": "sh -c 'echo 32768 > /sys/class/net/$DUMMY/tx_queue_len'",
+ "expExitCode": "1",
+ "verifyCmd": "$IP link show dev $DUMMY",
+ "matchPattern": "qlen 1000$",
+ "matchCount": "1",
+ "teardown": []
+ },
+ {
+ "id": "4b6e",
+ "name": "Set tx_queue_len to S16_MAX via sysfs (32767 accepted)",
+ "category": [
+ "qdisc",
+ "pfifo_fast"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [],
+ "cmdUnderTest": "sh -c 'echo 32767 > /sys/class/net/$DUMMY/tx_queue_len'",
+ "expExitCode": "0",
+ "verifyCmd": "$IP link show dev $DUMMY",
+ "matchPattern": "qlen 32767$",
+ "matchCount": "1",
+ "teardown": []
+ },
+ {
+ "id": "b90d",
+ "name": "Create device with tx_queue_len at S16_MAX boundary (32767 accepted)",
+ "category": [
+ "qdisc",
+ "pfifo_fast"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [
+ [
+ "$IP link del dev $DUMMY",
+ 0,
+ 1
+ ]
+ ],
+ "cmdUnderTest": "$IP link add dev $DUMMY txqueuelen 32767 type dummy",
+ "expExitCode": "0",
+ "verifyCmd": "$IP link show dev $DUMMY",
+ "matchPattern": "qlen 32767$",
+ "matchCount": "1",
+ "teardown": [
+ [
+ "$IP link del dev $DUMMY",
+ 0,
+ 1
+ ]
+ ]
+ },
+ {
+ "id": "57ab",
+ "name": "Reject creating device with tx_queue_len above S16_MAX (32768)",
+ "category": [
+ "qdisc",
+ "pfifo_fast"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [
+ [
+ "$IP link del dev $DUMMY",
+ 0,
+ 1
+ ]
+ ],
+ "cmdUnderTest": "$IP link add dev $DUMMY txqueuelen 32768 type dummy",
+ "expExitCode": "2",
+ "verifyCmd": "$IP -o link show",
+ "matchPattern": "^[0-9]+: $DUMMY",
+ "matchCount": "0",
+ "teardown": []
+ },
+ {
+ "id": "e777",
+ "name": "Reject creating device with oversized tx_queue_len (500000)",
+ "category": [
+ "qdisc",
+ "pfifo_fast"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [
+ [
+ "$IP link del dev $DUMMY",
+ 0,
+ 1
+ ]
+ ],
+ "cmdUnderTest": "$IP link add dev $DUMMY txqueuelen 500000 type dummy",
+ "expExitCode": "2",
+ "verifyCmd": "$IP -o link show",
+ "matchPattern": "^[0-9]+: $DUMMY",
+ "matchCount": "0",
+ "teardown": []
+ },
+ {
+ "id": "31ac",
+ "name": "Reject veth peer nest tx_queue_len above S16_MAX at create",
+ "category": [
+ "qdisc",
+ "pfifo_fast"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [
+ [
+ "$IP link del dev $DEV1",
+ 0,
+ 1
+ ]
+ ],
+ "cmdUnderTest": "$IP link add dev $DEV1 type veth peer name $DEV0 txqueuelen 500000",
+ "expExitCode": "2",
+ "verifyCmd": "$IP -o link show",
+ "matchPattern": "^[0-9]+: $DEV1",
+ "matchCount": "0",
+ "teardown": []
+ },
+ {
+ "id": "b567",
+ "name": "Accept veth peer nest tx_queue_len within S16_MAX",
+ "category": [
+ "qdisc",
+ "pfifo_fast"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [
+ [
+ "$IP link del dev $DEV1",
+ 0,
+ 1
+ ]
+ ],
+ "cmdUnderTest": "$IP link add dev $DEV1 txqueuelen 100 type veth peer name $DEV0 txqueuelen 200",
+ "expExitCode": "0",
+ "verifyCmd": "$IP link show",
+ "matchPattern": "qlen (100|200)$",
+ "matchCount": "2",
+ "teardown": [
+ [
+ "$IP link del dev $DEV0",
+ 0,
+ 1
+ ]
+ ]
}
]
diff --git a/tools/testing/selftests/ublk/Makefile b/tools/testing/selftests/ublk/Makefile
index 5daf36c6c36c..37883e9d50ec 100644
--- a/tools/testing/selftests/ublk/Makefile
+++ b/tools/testing/selftests/ublk/Makefile
@@ -73,6 +73,8 @@ TEST_PROGS += test_stress_08.sh
TEST_PROGS += test_stress_09.sh
TEST_FILES := settings
+TEST_FILES += test_common.sh
+TEST_FILES += trace
TEST_GEN_PROGS_EXTENDED = kublk metadata_size
STANDALONE_UTILS := metadata_size.c
diff --git a/tools/testing/selftests/ublk/test_recover_03.sh b/tools/testing/selftests/ublk/test_recover_03.sh
index 2554805e5b02..92f4012178f0 100755
--- a/tools/testing/selftests/ublk/test_recover_03.sh
+++ b/tools/testing/selftests/ublk/test_recover_03.sh
@@ -29,6 +29,11 @@ _create_backfile 0 256M
_create_backfile 1 128M
_create_backfile 2 128M
+ublk_run_quiesce_recover -t null -q 2 -r 1 -b &
+ublk_run_quiesce_recover -t loop -q 2 -r 1 -b "${UBLK_BACKFILES[0]}" &
+ublk_run_quiesce_recover -t stripe -q 2 -r 1 -b "${UBLK_BACKFILES[1]}" "${UBLK_BACKFILES[2]}" &
+wait
+
ublk_run_quiesce_recover -t null -q 2 -r 1 &
ublk_run_quiesce_recover -t loop -q 2 -r 1 "${UBLK_BACKFILES[0]}" &
ublk_run_quiesce_recover -t stripe -q 2 -r 1 "${UBLK_BACKFILES[1]}" "${UBLK_BACKFILES[2]}" &