Add a sched_ext negative-load test that calls scx_bpf_cpu_rq(-1) and then immediately reads rq->nr_running. The verifier should reject the program because scx_bpf_cpu_rq() may return NULL. This guards the KF_RET_NULL metadata for scx_bpf_cpu_rq(). Signed-off-by: Nuoqi Gui --- tools/testing/selftests/sched_ext/Makefile | 1 + .../selftests/sched_ext/cpu_rq_ret_null.bpf.c | 27 +++++++++++++++ .../testing/selftests/sched_ext/cpu_rq_ret_null.c | 38 ++++++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/tools/testing/selftests/sched_ext/Makefile b/tools/testing/selftests/sched_ext/Makefile index 5d2dffca0e91..15cedcf56a49 100644 --- a/tools/testing/selftests/sched_ext/Makefile +++ b/tools/testing/selftests/sched_ext/Makefile @@ -174,6 +174,7 @@ auto-test-targets := \ init_enable_count \ maximal \ maybe_null \ + cpu_rq_ret_null \ minimal \ non_scx_kfunc_deny \ numa \ diff --git a/tools/testing/selftests/sched_ext/cpu_rq_ret_null.bpf.c b/tools/testing/selftests/sched_ext/cpu_rq_ret_null.bpf.c new file mode 100644 index 000000000000..d08f0b582542 --- /dev/null +++ b/tools/testing/selftests/sched_ext/cpu_rq_ret_null.bpf.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2026 Nuoqi Gui + */ +#include + +char _license[] SEC("license") = "GPL"; + +u32 nr_running; + +void BPF_STRUCT_OPS(cpu_rq_ret_null_enable, struct task_struct *p) +{} + +void BPF_STRUCT_OPS(cpu_rq_ret_null_dispatch, s32 cpu, struct task_struct *p) +{ + struct rq *rq; + + rq = scx_bpf_cpu_rq(-1); + nr_running = rq->nr_running; +} + +SEC(".struct_ops.link") +struct sched_ext_ops cpu_rq_ret_null = { + .dispatch = (void *)cpu_rq_ret_null_dispatch, + .enable = (void *)cpu_rq_ret_null_enable, + .name = "cpu_rq_ret_null", +}; diff --git a/tools/testing/selftests/sched_ext/cpu_rq_ret_null.c b/tools/testing/selftests/sched_ext/cpu_rq_ret_null.c new file mode 100644 index 000000000000..bd82c310ad7a --- /dev/null +++ b/tools/testing/selftests/sched_ext/cpu_rq_ret_null.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2026 Nuoqi Gui + */ +#include +#include +#include "cpu_rq_ret_null.bpf.skel.h" +#include "scx_test.h" + +static enum scx_test_status run(void *ctx) +{ + struct cpu_rq_ret_null *skel; + int err; + + skel = cpu_rq_ret_null__open(); + if (!skel) { + SCX_ERR("Failed to open skel"); + return SCX_TEST_FAIL; + } + + err = cpu_rq_ret_null__load(skel); + cpu_rq_ret_null__destroy(skel); + + if (!err) { + SCX_ERR("scx_bpf_cpu_rq() direct dereference loaded"); + return SCX_TEST_FAIL; + } + + return SCX_TEST_PASS; +} + +struct scx_test cpu_rq_ret_null = { + .name = "cpu_rq_ret_null", + .description = "Verify that scx_bpf_cpu_rq() returns a nullable pointer", + .run = run, +}; + +REGISTER_SCX_TEST(&cpu_rq_ret_null) -- 2.34.1