Context |
Check |
Description |
netdev/series_format |
success
|
Posting correctly formatted
|
netdev/tree_selection |
success
|
Clearly marked for bpf-next, async
|
netdev/fixes_present |
success
|
Fixes tag not required for -next series
|
netdev/header_inline |
success
|
No static functions without inline keyword in header files
|
netdev/build_32bit |
success
|
Errors and warnings before: 9 this patch: 9
|
netdev/cc_maintainers |
warning
|
11 maintainers not CCed: song@kernel.org mykolal@fb.com yonghong.song@linux.dev jolsa@kernel.org kpsingh@kernel.org john.fastabend@gmail.com shuah@kernel.org linux-kselftest@vger.kernel.org sdf@google.com haoluo@google.com martin.lau@linux.dev
|
netdev/build_clang |
success
|
Errors and warnings before: 9 this patch: 9
|
netdev/verify_signedoff |
success
|
Signed-off-by tag matches author and committer
|
netdev/deprecated_api |
success
|
None detected
|
netdev/check_selftest |
success
|
No net selftest shell script
|
netdev/verify_fixes |
success
|
No Fixes tag
|
netdev/build_allmodconfig_warn |
success
|
Errors and warnings before: 9 this patch: 9
|
netdev/checkpatch |
warning
|
CHECK: spaces preferred around that '*' (ctx:WxV)
WARNING: Prefer __aligned(8) over __attribute__((aligned(8)))
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
|
netdev/kdoc |
success
|
Errors and warnings before: 0 this patch: 0
|
netdev/source_inline |
success
|
Was 0 now: 0
|
bpf/vmtest-bpf-next-PR |
success
|
PR summary
|
bpf/vmtest-bpf-next-VM_Test-32 |
success
|
Logs for x86_64-llvm-16 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-16
|
bpf/vmtest-bpf-next-VM_Test-33 |
success
|
Logs for x86_64-llvm-16 / veristat
|
bpf/vmtest-bpf-next-VM_Test-30 |
success
|
Logs for x86_64-llvm-16 / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with llvm-16
|
bpf/vmtest-bpf-next-VM_Test-31 |
success
|
Logs for x86_64-llvm-16 / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with llvm-16
|
bpf/vmtest-bpf-next-VM_Test-2 |
success
|
Logs for Validate matrix.py
|
bpf/vmtest-bpf-next-VM_Test-8 |
success
|
Logs for aarch64-gcc / veristat
|
bpf/vmtest-bpf-next-VM_Test-0 |
success
|
Logs for Lint
|
bpf/vmtest-bpf-next-VM_Test-3 |
success
|
Logs for aarch64-gcc / build / build for aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-1 |
success
|
Logs for ShellCheck
|
bpf/vmtest-bpf-next-VM_Test-7 |
success
|
Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-5 |
success
|
Logs for aarch64-gcc / test (test_progs, false, 360) / test_progs on aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-4 |
success
|
Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-6 |
success
|
Logs for aarch64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-24 |
success
|
Logs for x86_64-llvm-16 / build / build for x86_64 with llvm-16
|
bpf/vmtest-bpf-next-VM_Test-25 |
success
|
Logs for x86_64-llvm-16 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-16
|
bpf/vmtest-bpf-next-VM_Test-18 |
success
|
Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-16 |
success
|
Logs for x86_64-gcc / build / build for x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-17 |
success
|
Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-9 |
success
|
Logs for s390x-gcc / build / build for s390x with gcc
|
bpf/vmtest-bpf-next-VM_Test-14 |
success
|
Logs for s390x-gcc / veristat
|
bpf/vmtest-bpf-next-VM_Test-19 |
success
|
Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-20 |
success
|
Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-15 |
success
|
Logs for set-matrix
|
bpf/vmtest-bpf-next-VM_Test-26 |
success
|
Logs for x86_64-llvm-16 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-16
|
bpf/vmtest-bpf-next-VM_Test-21 |
success
|
Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-22 |
success
|
Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-23 |
success
|
Logs for x86_64-gcc / veristat / veristat on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-27 |
success
|
Logs for x86_64-llvm-16 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-16
|
bpf/vmtest-bpf-next-VM_Test-28 |
success
|
Logs for x86_64-llvm-16 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-16
|
bpf/vmtest-bpf-next-VM_Test-29 |
success
|
Logs for x86_64-llvm-16 / veristat
|
bpf/vmtest-bpf-next-VM_Test-12 |
success
|
Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc
|
bpf/vmtest-bpf-next-VM_Test-13 |
success
|
Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
|
bpf/vmtest-bpf-next-VM_Test-11 |
success
|
Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc
|
bpf/vmtest-bpf-next-VM_Test-10 |
success
|
Logs for s390x-gcc / test (test_maps, false, 360) / test_maps on s390x with gcc
|
new file mode 100644
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
+
+#include <test_progs.h>
+
+#include "array_kptr.skel.h"
+
+void test_array_kptr(void)
+{
+ if (env.has_testmod)
+ RUN_TESTS(array_kptr);
+}
new file mode 100644
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
+
+#include <vmlinux.h>
+#include <bpf/bpf_tracing.h>
+#include <bpf/bpf_helpers.h>
+#include "../bpf_testmod/bpf_testmod_kfunc.h"
+#include "bpf_misc.h"
+
+struct val {
+ int d;
+ struct prog_test_ref_kfunc __kptr *ref_ptr;
+};
+
+struct val2 {
+ char c;
+ struct val v;
+};
+
+struct val_holder {
+ int e;
+ struct val2 first[2];
+ int f;
+ struct val second[2];
+};
+
+struct array_map {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __type(key, int);
+ __type(value, struct val);
+ __uint(max_entries, 10);
+} array_map SEC(".maps");
+
+struct array_map2 {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __type(key, int);
+ __type(value, struct val2);
+ __uint(max_entries, 10);
+} array_map2 SEC(".maps");
+
+__hidden struct val array[25];
+__hidden struct val double_array[5][5];
+__hidden struct val_holder double_holder_array[2][2];
+
+/* Some tests need their own section to force separate bss arraymap,
+ * otherwise above arrays wouldn't have btf_field_info either
+ */
+#define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8)))
+private(A) struct val array_too_big[300];
+
+private(B) struct val exactly_max_fields[256];
+private(B) int ints[50];
+
+SEC("tc")
+__success __retval(0)
+int test_arraymap(void *ctx)
+{
+ struct prog_test_ref_kfunc *p;
+ unsigned long dummy = 0;
+ struct val *v;
+ int idx = 0;
+
+ v = bpf_map_lookup_elem(&array_map, &idx);
+ if (!v)
+ return 1;
+
+ p = bpf_kfunc_call_test_acquire(&dummy);
+ if (!p)
+ return 2;
+
+ p = bpf_kptr_xchg(&v->ref_ptr, p);
+ if (p) {
+ bpf_kfunc_call_test_release(p);
+ return 3;
+ }
+
+ return 0;
+}
+
+SEC("tc")
+__success __retval(0)
+int test_arraymap2(void *ctx)
+{
+ struct prog_test_ref_kfunc *p;
+ unsigned long dummy = 0;
+ struct val2 *v;
+ int idx = 0;
+
+ v = bpf_map_lookup_elem(&array_map2, &idx);
+ if (!v)
+ return 1;
+
+ p = bpf_kfunc_call_test_acquire(&dummy);
+ if (!p)
+ return 2;
+
+ p = bpf_kptr_xchg(&v->v.ref_ptr, p);
+ if (p) {
+ bpf_kfunc_call_test_release(p);
+ return 3;
+ }
+
+ return 0;
+}
+
+/* elem must be contained within some mapval so it can be used as
+ * bpf_kptr_xchg's first param
+ */
+static __always_inline int test_array_xchg(struct val *elem)
+{
+ struct prog_test_ref_kfunc *p;
+ unsigned long dummy = 0;
+
+ p = bpf_kfunc_call_test_acquire(&dummy);
+ if (!p)
+ return 1;
+
+ p = bpf_kptr_xchg(&elem->ref_ptr, p);
+ if (p) {
+ bpf_kfunc_call_test_release(p);
+ return 2;
+ }
+
+ return 0;
+}
+
+SEC("tc")
+__success __retval(0)
+int test_array(void *ctx)
+{
+ return test_array_xchg(&array[10]);
+}
+
+SEC("tc")
+__success __retval(0)
+int test_double_array(void *ctx)
+{
+ /* array -> array -> struct -> kptr */
+ return test_array_xchg(&double_array[4][3]);
+}
+
+SEC("tc")
+__success __retval(0)
+int test_double_holder_array_first(void *ctx)
+{
+ /* array -> array -> struct -> array -> struct -> struct -> kptr */
+ return test_array_xchg(&double_holder_array[1][1].first[1].v);
+}
+
+SEC("tc")
+__success __retval(0)
+int test_double_holder_array_second(void *ctx)
+{
+ /* array -> array -> struct -> array -> struct -> kptr */
+ return test_array_xchg(&double_holder_array[1][1].second[1]);
+}
+
+SEC("tc")
+__success __retval(0)
+int test_exactly_max_fields(void *ctx)
+{
+ /* Edge case where verifier finds BTF_FIELDS_MAX fields. It should be
+ * safe to examine .bss.B's other array, and .bss.B will have a valid
+ * btf_record if no more fields are found
+ */
+ return test_array_xchg(&exactly_max_fields[255]);
+}
+
+SEC("tc")
+__failure __msg("map '.bss.A' has no valid kptr")
+int test_array_fail__too_big(void *ctx)
+{
+ /* array_too_big's btf_record parsing will fail due to the
+ * number of btf_field_infos being > BTF_FIELDS_MAX
+ */
+ return test_array_xchg(&array_too_big[50]);
+}
+
+char _license[] SEC("license") = "GPL";
The newly-added test file attempts to kptr_xchg a prog_test_ref_kfunc kptr into a kptr field in a variety of nested aggregate types. If the verifier recognizes that there's a kptr field where we're trying to kptr_xchg, then the aggregate type digging logic works as expected. Some of the refactoring changes in this series are tested as well. Specifically: * BTF_FIELDS_MAX is now higher and represents the max size of the growable array. Confirm that btf_parse_fields fails for a type which contains too many fields. * If we've already seen BTF_FIELDS_MAX fields, we should continue looking for fields and fail if we find another one, otherwise the search should succeed and return BTF_FIELDS_MAX btf_field_infos. Confirm that this edge case works as expected. Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com> --- .../selftests/bpf/prog_tests/array_kptr.c | 12 ++ .../testing/selftests/bpf/progs/array_kptr.c | 179 ++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/array_kptr.c create mode 100644 tools/testing/selftests/bpf/progs/array_kptr.c