Add an optional all-zero private bitfield to the struct_ops test. Verify that libbpf returns -ENOTSUP and emits the bitfield diagnostic. Keep the existing all-zero scalar test as the compatibility control. Assisted-by: LLM Signed-off-by: Mingpei CAO --- .../bpf/prog_tests/test_struct_ops_module.c | 31 +++++++++++++++++++ .../selftests/bpf/progs/struct_ops_module.c | 7 +++++ 2 files changed, 38 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c index 75a0dea511b3f..517e5abe67c0c 100644 --- a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c +++ b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c @@ -150,6 +150,35 @@ static void test_struct_ops_not_zeroed(void) struct_ops_module__destroy(skel); } +static void test_struct_ops_private_bitfield(void) +{ + struct struct_ops_module *skel; + char *log = NULL; + int err; + + skel = struct_ops_module__open(); + if (!ASSERT_OK_PTR(skel, "struct_ops_module_open_private_bitfield")) + return; + + bpf_map__set_autocreate(skel->maps.testmod_zeroed, false); + err = bpf_map__set_autocreate(skel->maps.testmod_private_bitfield, true); + if (!ASSERT_OK(err, "enable_private_bitfield_map")) + goto cleanup; + + if (start_libbpf_log_capture()) + goto cleanup; + err = struct_ops_module__load(skel); + log = stop_libbpf_log_capture(); + ASSERT_EQ(err, -ENOTSUP, "struct_ops_module_load_private_bitfield"); + ASSERT_HAS_SUBSTR(log, + "bitfield private_bitfield is not supported", + "private_bitfield_rejection_log"); + +cleanup: + free(log); + struct_ops_module__destroy(skel); +} + /* The signature of an implementation might not match the signature of the * function pointer prototype defined in the BPF program. This mismatch * should be allowed as long as the behavior of the operator program @@ -304,6 +333,8 @@ void serial_test_struct_ops_module(void) test_struct_ops_load(); if (test__start_subtest("struct_ops_not_zeroed")) test_struct_ops_not_zeroed(); + if (test__start_subtest("struct_ops_private_bitfield")) + test_struct_ops_private_bitfield(); if (test__start_subtest("struct_ops_incompatible")) test_struct_ops_incompatible(); if (test__start_subtest("struct_ops_null_out_cb")) diff --git a/tools/testing/selftests/bpf/progs/struct_ops_module.c b/tools/testing/selftests/bpf/progs/struct_ops_module.c index 71c420c3a5a6c..423caf78f4207 100644 --- a/tools/testing/selftests/bpf/progs/struct_ops_module.c +++ b/tools/testing/selftests/bpf/progs/struct_ops_module.c @@ -76,6 +76,13 @@ struct bpf_testmod_ops___zeroed testmod_zeroed = { .zeroed_op = (void *)zeroed_op, }; +struct bpf_testmod_ops___private_bitfield { + unsigned int private_bitfield:31; +}; + +SEC("?.struct_ops.link") +struct bpf_testmod_ops___private_bitfield testmod_private_bitfield; + struct bpf_testmod_ops___incompatible { int (*test_1)(void); void (*test_2)(int *a); -- 2.43.0