From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: bpf@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Eduard Zingerman <eddyz87@gmail.com>,
Emil Tsalapatis <emil@etsalapatis.com>,
kkd@meta.com, kernel-team@meta.com
Subject: [RFC PATCH bpf-next v1 13/16] selftests/bpf: Test typed arena casts and registration
Date: Sun, 27 Sep 2026 01:34:51 +0200 [thread overview]
Message-ID: <20260926233503.3114147-14-memxor@gmail.com> (raw)
In-Reply-To: <20260926233503.3114147-1-memxor@gmail.com>
The compiler inserts a typed_arena_cast where a value is converted to a
pointer to a typed struct and before every use of such a pointer as an
address, so the programs write no cast: an object is whatever value user
space hands in, a raw arena pointer, or a pointer of another type, and the
casts the verifier sees are all the compiler's.
Convert a value user space hands in and see it lowered to the mask, the
base load and the add, with the pointer typed as the struct's object;
convert a raw arena pointer, and a typed pointer passed through an opaque
value and to another type, which land on objects like any other value. See
the registration logged with the slot size. A cast of a pointer the
verifier already trusts is the identity: an allocated object, a typed
struct inside a map value and one on the stack keep their type and state
through the cast the compiler inserts, and such programs need no arena.
Reject a cast in a program without an arena map, and structs with the
special fields a typed arena does not carry: spin locks, resilient spin
locks, timers, refcounts, list heads and rbtree roots. A struct without
special fields is not typed to the compiler and no cast names it; the page
kfuncs, which take a type ID, reject one in their own tests. Reject typed
arena sizes that are not a power of two, below a page, above the region, or
too small for one object, and two size declarations on one struct; accept
sizes with a suffix and see the object count follow, take an object larger
than a page in a slot of whole pages, and see the region refuse a third
type once two 2 GiB ones have filled it.
A typed pointer is a kernel pointer: a 32-bit copy is the scalar a privileged
program may take of any pointer, and a narrow store to the stack is an
invalid spill.
The values user space would hand in stay unset: the verifier does not care
where a value lands, and at run time an unset one names object 0 of its
slice. The tests exist only when the compiler emits the cast; the runner
checks a flag the object exports and skips otherwise. Add the typed arena
size tag macro to bpf_experimental.h.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
.../testing/selftests/bpf/bpf_experimental.h | 6 +
.../selftests/bpf/prog_tests/verifier.c | 22 +
.../bpf/progs/verifier_typed_arena.c | 528 ++++++++++++++++++
3 files changed, 556 insertions(+)
create mode 100644 tools/testing/selftests/bpf/progs/verifier_typed_arena.c
diff --git a/tools/testing/selftests/bpf/bpf_experimental.h b/tools/testing/selftests/bpf/bpf_experimental.h
index 2893bf06ff25..128654997328 100644
--- a/tools/testing/selftests/bpf/bpf_experimental.h
+++ b/tools/testing/selftests/bpf/bpf_experimental.h
@@ -9,6 +9,12 @@
#define __contains(name, node) __attribute__((btf_decl_tag("contains:" #name ":" #node)))
+/*
+ * Size of a struct's typed arena in bytes: a power of two with an optional K,
+ * M or G suffix, 128M unless declared.
+ */
+#define __typed_arena_size(sz) __attribute__((btf_decl_tag("typed_arena_size:" #sz)))
+
/* Convenience macro to wrap over bpf_obj_new */
#define bpf_obj_new(type) ((type *)bpf_obj_new(bpf_core_type_id_local(type)))
diff --git a/tools/testing/selftests/bpf/prog_tests/verifier.c b/tools/testing/selftests/bpf/prog_tests/verifier.c
index 8a6d341b754a..3a4270fca559 100644
--- a/tools/testing/selftests/bpf/prog_tests/verifier.c
+++ b/tools/testing/selftests/bpf/prog_tests/verifier.c
@@ -120,6 +120,7 @@
#include "verifier_subreg.skel.h"
#include "verifier_tailcall.skel.h"
#include "verifier_tailcall_jit.skel.h"
+#include "verifier_typed_arena.skel.h"
#include "verifier_typedef.skel.h"
#include "verifier_uninit.skel.h"
#include "verifier_unpriv.skel.h"
@@ -303,6 +304,27 @@ void test_verifier_subprog_topo(void) { RUN(verifier_subprog_topo); }
void test_verifier_subreg(void) { RUN(verifier_subreg); }
void test_verifier_tailcall(void) { RUN(verifier_tailcall); }
void test_verifier_tailcall_jit(void) { RUN(verifier_tailcall_jit); }
+
+/*
+ * The typed arena tests need a compiler that emits the cast; without one the
+ * object holds no programs.
+ */
+void test_verifier_typed_arena(void)
+{
+ struct verifier_typed_arena *skel;
+ bool supported;
+
+ skel = verifier_typed_arena__open();
+ if (!ASSERT_OK_PTR(skel, "open"))
+ return;
+ supported = skel->rodata->typed_arena_supported;
+ verifier_typed_arena__destroy(skel);
+ if (!supported) {
+ test__skip();
+ return;
+ }
+ RUN(verifier_typed_arena);
+}
void test_verifier_typedef(void) { RUN(verifier_typedef); }
void test_verifier_uninit(void) { RUN(verifier_uninit); }
void test_verifier_unpriv(void) { RUN(verifier_unpriv); }
diff --git a/tools/testing/selftests/bpf/progs/verifier_typed_arena.c b/tools/testing/selftests/bpf/progs/verifier_typed_arena.c
new file mode 100644
index 000000000000..22a8c3bfd493
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/verifier_typed_arena.c
@@ -0,0 +1,528 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
+
+#include <vmlinux.h>
+#include <errno.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+#include "bpf_misc.h"
+#include "bpf_experimental.h"
+#include "bpf_arena_common.h"
+
+#ifdef __TARGET_ARCH_arm64
+#define ARENA_VM_START ((1ull << 32) | (~0u - __PAGE_SIZE * 2 + 1))
+#else
+#define ARENA_VM_START ((1ull << 44) | (~0u - __PAGE_SIZE * 2 + 1))
+#endif
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARENA);
+ __uint(map_flags, BPF_F_MMAPABLE);
+ __uint(max_entries, 2);
+ __ulong(map_extra, ARENA_VM_START);
+} arena SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, __u64);
+} not_an_arena SEC(".maps");
+
+/* Tells the runner whether the compiler emits the cast, and so whether the tests below exist. */
+const volatile bool typed_arena_supported =
+#ifdef __BPF_FEATURE_TYPED_ARENA_CAST
+ true;
+#else
+ false;
+#endif
+
+#ifdef __BPF_FEATURE_TYPED_ARENA_CAST
+
+/* 16-byte slot, 8 Mi objects in the default 128 MiB typed arena: the cast mask is 134217712 */
+struct typed_obj {
+ struct task_struct __kptr *task;
+ __u64 value;
+};
+
+/* 32-byte slot */
+struct other_obj {
+ struct task_struct __kptr *task;
+ __u64 a;
+ __u64 b;
+};
+
+struct plain_obj {
+ __u64 value;
+};
+
+/*
+ * A program is associated with an arena by referencing the map. Programs that
+ * only convert values they already hold reference it explicitly.
+ */
+#define arena_bind() asm volatile("r0 = %[m] ll" :: [m] "i"(&arena) : "r0")
+
+/*
+ * Objects as the opaque 64-bit values user space hands in. Converting one to a
+ * pointer to a typed struct is where the compiler inserts the typed_arena_cast,
+ * as it does before every use of such a pointer as an address. A cast of a
+ * pointer the verifier already trusts lowers to nothing, so a lowered program
+ * shows one sequence per value that enters. The values stay unset here: the
+ * verifier does not care where a value lands, and at run time an unset one
+ * names object 0 of its slice.
+ */
+void *ptr;
+void *ptr2;
+
+SEC("syscall")
+__description("a cast masks the value into a slot and adds the typed arena base")
+__success __retval(0) __log_level(2)
+__msg("typed arena for struct typed_obj: slot 16 bytes")
+__msg("R{{[0-9]}}=typed_arena_ptr_typed_obj(")
+__xlated("r{{[0-9]}} &= 134217712")
+__xlated("r12 = 0x{{[0-9a-f]+}}")
+__xlated("r{{[0-9]}} += r12")
+int cast_lowers_to_mask_and_base(void *ctx)
+{
+ struct typed_obj *obj;
+
+ arena_bind();
+ obj = ptr;
+ return obj->value;
+}
+
+SEC("syscall")
+__description("any 64-bit value casts: a raw arena pointer lands on an object")
+__success __retval(0)
+int cast_raw_arena_pointer(void *ctx)
+{
+ struct typed_obj *obj;
+ void __arena *page;
+
+ page = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
+ if (!page)
+ return 1;
+ obj = (void *)page;
+ obj->value = 3;
+ return obj->value - 3;
+}
+
+SEC("syscall")
+__description("a typed pointer casts to itself, and to another type without knowing the source")
+__success __retval(0)
+int cast_typed_pointer_again(void *ctx)
+{
+ struct typed_obj *obj, *again;
+ struct other_obj *other;
+ void *opaque;
+
+ arena_bind();
+ obj = ptr;
+ opaque = obj;
+ again = opaque;
+ if (again != obj)
+ return 1;
+ other = (struct other_obj *)obj;
+ other->a = 1;
+ return other->a - 1;
+}
+
+/*
+ * The same struct lives in allocated objects, in map values and on the stack,
+ * and the compiler casts every use of a pointer to it there too. Such a cast
+ * is the identity: the pointer keeps its type and its state, nothing is
+ * lowered, and the access follows that pointer's own rules. These programs
+ * reference no arena, since nothing in them is sanitized.
+ */
+SEC("syscall")
+__description("a cast of an allocated object of a typed struct is the identity")
+__success __retval(0) __log_level(2)
+__msg("typed_arena_cast(r{{[0-9]}}, {{[0-9]+}})")
+__msg("R{{[0-9]}}=ptr_typed_obj(")
+int cast_allocated_object_is_identity(void *ctx)
+{
+ struct typed_obj *obj;
+
+ obj = bpf_obj_new(struct typed_obj);
+ if (!obj)
+ return 1;
+ obj->value = 1;
+ bpf_obj_drop(obj);
+ return 0;
+}
+
+struct value_with_typed {
+ __u64 pad;
+ struct typed_obj obj;
+};
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, struct value_with_typed);
+} typed_in_map SEC(".maps");
+
+SEC("syscall")
+__description("a cast of a typed struct inside a map value is the identity")
+__success __retval(0) __log_level(2)
+__msg("typed_arena_cast(r{{[0-9]}}, {{[0-9]+}})")
+__msg("R{{[0-9]}}=map_value(")
+int cast_map_value_is_identity(void *ctx)
+{
+ struct value_with_typed *v;
+ struct typed_obj *obj;
+ __u32 key = 0;
+
+ v = bpf_map_lookup_elem(&typed_in_map, &key);
+ if (!v)
+ return 1;
+ obj = &v->obj;
+ obj->value = 1;
+ return 0;
+}
+
+SEC("syscall")
+__description("a cast of a typed struct on the stack is the identity")
+__success __retval(0) __log_level(2)
+__msg("typed_arena_cast(r{{[0-9]}}, {{[0-9]+}})")
+__msg("R{{[0-9]}}=fp-")
+int cast_stack_object_is_identity(void *ctx)
+{
+ struct typed_obj local = {};
+ struct typed_obj *obj = &local;
+
+ barrier_var(obj);
+ obj->value = 1;
+ return local.value - 1;
+}
+
+SEC("syscall")
+__description("the cast needs the program's arena")
+__failure __msg("typed_arena_cast insn can only be used in a program that has an associated arena")
+int cast_needs_arena(void *ctx)
+{
+ struct typed_obj *obj;
+
+ obj = ptr;
+ return obj->value;
+}
+
+struct locked_obj {
+ struct bpf_spin_lock lock;
+ __u64 value;
+};
+
+SEC("syscall")
+__description("spin locks are not supported in typed arena objects yet")
+__failure __msg("struct locked_obj field bpf_spin_lock is not supported in a typed arena")
+int cast_rejects_spin_lock(void *ctx)
+{
+ struct locked_obj *obj;
+
+ arena_bind();
+ obj = ptr;
+ return obj->value;
+}
+
+struct res_locked_obj {
+ struct bpf_res_spin_lock lock;
+ __u64 value;
+};
+
+SEC("syscall")
+__description("resilient spin locks are not supported in typed arena objects yet")
+__failure __msg("struct res_locked_obj field bpf_res_spin_lock is not supported in a typed arena")
+int cast_rejects_res_spin_lock(void *ctx)
+{
+ struct res_locked_obj *obj;
+
+ arena_bind();
+ obj = ptr;
+ return obj->value;
+}
+
+struct timer_obj {
+ struct bpf_timer timer;
+ __u64 value;
+};
+
+SEC("syscall")
+__description("timers are not supported in typed arena objects")
+__failure __msg("struct timer_obj field bpf_timer is not supported in a typed arena")
+int cast_rejects_timer(void *ctx)
+{
+ struct timer_obj *obj;
+
+ arena_bind();
+ obj = ptr;
+ return obj->value;
+}
+
+struct refcount_obj {
+ struct bpf_refcount ref;
+ struct task_struct __kptr *task;
+ __u64 value;
+};
+
+SEC("syscall")
+__description("refcounts are not supported in typed arena objects")
+__failure __msg("struct refcount_obj field bpf_refcount is not supported in a typed arena")
+int cast_rejects_refcount(void *ctx)
+{
+ struct refcount_obj *obj;
+
+ arena_bind();
+ obj = ptr;
+ return obj->value;
+}
+
+struct list_node_obj {
+ struct bpf_list_node node;
+ __u64 value;
+};
+
+struct list_obj {
+ struct bpf_list_head head __contains(list_node_obj, node);
+ struct bpf_spin_lock lock;
+};
+
+/* The node structs must reach the BTF for the contains tags to resolve; nothing else uses them. */
+struct list_node_obj *list_node_in_btf;
+
+SEC("syscall")
+__description("list heads are not supported in typed arena objects")
+__failure __msg("struct list_obj field bpf_list_head is not supported in a typed arena")
+int cast_rejects_list_head(void *ctx)
+{
+ struct list_obj *obj;
+
+ arena_bind();
+ obj = ptr;
+ return obj == NULL;
+}
+
+struct rb_node_obj {
+ struct bpf_rb_node node;
+ __u64 value;
+};
+
+struct rb_obj {
+ struct bpf_rb_root root __contains(rb_node_obj, node);
+ struct bpf_spin_lock lock;
+};
+
+struct rb_node_obj *rb_node_in_btf;
+
+SEC("syscall")
+__description("rbtree roots are not supported in typed arena objects")
+__failure __msg("struct rb_obj field bpf_rb_root is not supported in a typed arena")
+int cast_rejects_rb_root(void *ctx)
+{
+ struct rb_obj *obj;
+
+ arena_bind();
+ obj = ptr;
+ return obj == NULL;
+}
+
+struct size_not_pow2_obj {
+ struct task_struct __kptr *task;
+ __u64 value;
+} __typed_arena_size(3M);
+
+SEC("syscall")
+__description("a typed arena size must be a power of two")
+__failure __msg("struct size_not_pow2_obj has invalid typed arena size '3M'")
+int size_rejects_not_pow2(void *ctx)
+{
+ struct size_not_pow2_obj *obj;
+
+ arena_bind();
+ obj = ptr;
+ return obj->value;
+}
+
+struct size_below_page_obj {
+ struct task_struct __kptr *task;
+ __u64 value;
+} __typed_arena_size(2048);
+
+SEC("syscall")
+__description("a typed arena is at least a page")
+__failure __msg("struct size_below_page_obj has invalid typed arena size '2048'")
+int size_rejects_below_page(void *ctx)
+{
+ struct size_below_page_obj *obj;
+
+ arena_bind();
+ obj = ptr;
+ return obj->value;
+}
+
+struct size_above_region_obj {
+ struct task_struct __kptr *task;
+ __u64 value;
+} __typed_arena_size(8G);
+
+SEC("syscall")
+__description("a typed arena is at most the region")
+__failure __msg("struct size_above_region_obj has invalid typed arena size '8G'")
+int size_rejects_above_region(void *ctx)
+{
+ struct size_above_region_obj *obj;
+
+ arena_bind();
+ obj = ptr;
+ return obj->value;
+}
+
+/* 128 KiB slot in a 64 KiB typed arena */
+struct size_below_slot_obj {
+ struct task_struct __kptr *task;
+ char pad[65536 + 8];
+} __typed_arena_size(64K);
+
+SEC("syscall")
+__description("a typed arena holds at least one object")
+__failure __msg("struct size_below_slot_obj does not fit its typed arena: slot 131072 bytes, size 65536 bytes")
+int size_rejects_below_slot(void *ctx)
+{
+ struct size_below_slot_obj *obj;
+
+ arena_bind();
+ obj = ptr;
+ return obj->pad[0];
+}
+
+struct size_conflict_obj {
+ struct task_struct __kptr *task;
+ __u64 value;
+} __typed_arena_size(64K) __typed_arena_size(128K);
+
+SEC("syscall")
+__description("a struct declares one typed arena size")
+__failure __msg("struct size_conflict_obj has conflicting typed arena size declarations")
+int size_rejects_conflict(void *ctx)
+{
+ struct size_conflict_obj *obj;
+
+ arena_bind();
+ obj = ptr;
+ return obj->value;
+}
+
+struct size_64k_obj {
+ struct task_struct __kptr *task;
+ __u64 value;
+} __typed_arena_size(64K);
+
+struct size_2m_obj {
+ struct task_struct __kptr *task;
+ __u64 value;
+} __typed_arena_size(2M);
+
+SEC("syscall")
+__description("a typed arena size takes a suffix and sets the object count")
+__success __retval(0) __log_level(2)
+__msg("typed arena for struct size_64k_obj: slot 16 bytes")
+__msg("size 65536 bytes")
+__msg("typed arena for struct size_2m_obj: slot 16 bytes")
+__msg("size 2097152 bytes")
+int size_accepts_suffix(void *ctx)
+{
+ struct size_64k_obj *small;
+ struct size_2m_obj *large;
+
+ arena_bind();
+ small = ptr;
+ large = ptr;
+ small->value = 1;
+ large->value = 2;
+ return small->value + large->value - 3;
+}
+
+/* 16 KiB slot: an object of more than a page, four of them in a 64 KiB typed arena */
+struct big_obj {
+ struct task_struct __kptr *task;
+ char pad[8192];
+} __typed_arena_size(64K);
+
+SEC("syscall")
+__description("an object larger than a page takes a slot of whole pages")
+__success __retval(0) __log_level(2)
+__msg("typed arena for struct big_obj: slot 16384 bytes")
+int size_object_beyond_a_page(void *ctx)
+{
+ struct big_obj *obj;
+
+ arena_bind();
+ obj = ptr;
+ obj->pad[0] = 1;
+ obj->pad[8191] = 2;
+ return obj->pad[0] + obj->pad[8191] - 3;
+}
+
+/* A slice is capped at 2 GiB, half the region: two of them fill it. */
+struct huge_obj {
+ struct task_struct __kptr *task;
+ __u64 value;
+} __typed_arena_size(2G);
+
+struct huge_obj2 {
+ struct task_struct __kptr *task;
+ __u64 value;
+} __typed_arena_size(2G);
+
+SEC("syscall")
+__description("the region has room for 4 GiB of typed arenas")
+__failure __msg("no room in the typed arena region for struct typed_obj")
+int size_region_runs_out(void *ctx)
+{
+ struct huge_obj *huge;
+ struct huge_obj2 *huge2;
+ struct typed_obj *obj;
+
+ arena_bind();
+ huge = ptr;
+ huge2 = ptr;
+ obj = ptr;
+ return huge->value + huge2->value + obj->value;
+}
+
+SEC("syscall")
+__description("a 32-bit copy of a typed pointer is a scalar, as for any pointer a privileged program holds")
+__success __retval(0) __log_level(2)
+__msg("R2=scalar(smin=0,smax=umax=0xffffffff,var_off=(0x0; 0xffffffff))")
+int narrow_copy_yields_scalar(void *ctx)
+{
+ struct typed_obj *obj;
+
+ arena_bind();
+ obj = ptr;
+ asm volatile("r1 = %[p];"
+ "w2 = w1;"
+ :: [p] "r"(obj)
+ : "r1", "r2");
+ return 0;
+}
+
+SEC("syscall")
+__description("a narrow store of a typed pointer to the stack is an invalid spill")
+__failure __msg("invalid size of register spill")
+int narrow_store_is_invalid_spill(void *ctx)
+{
+ struct typed_obj *obj;
+
+ arena_bind();
+ obj = ptr;
+ asm volatile("r1 = %[p];"
+ "*(u32 *)(r10 - 8) = r1;"
+ :: [p] "r"(obj)
+ : "r1", "memory");
+ return 0;
+}
+
+#endif /* __BPF_FEATURE_TYPED_ARENA_CAST */
+
+char _license[] SEC("license") = "GPL";
--
2.53.0
next prev parent reply other threads:[~2026-09-26 23:35 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-26 23:34 [RFC PATCH bpf-next v1 00/16] BPF typed arenas Kumar Kartikeya Dwivedi
2026-09-26 23:34 ` [RFC PATCH bpf-next v1 01/16] mm/vmalloc: Add get_vm_area_align() Kumar Kartikeya Dwivedi
2026-09-26 23:42 ` sashiko-bot
2026-09-26 23:34 ` [RFC PATCH bpf-next v1 02/16] bpf: Introduce BPF typed arenas Kumar Kartikeya Dwivedi
2026-09-26 23:34 ` [RFC PATCH bpf-next v1 03/16] bpf: Back typed arena chunks with scratch on demand Kumar Kartikeya Dwivedi
2026-09-26 23:56 ` sashiko-bot
2026-09-26 23:34 ` [RFC PATCH bpf-next v1 04/16] bpf: Add the typed_arena_cast instruction Kumar Kartikeya Dwivedi
2026-09-26 23:55 ` sashiko-bot
2026-09-26 23:34 ` [RFC PATCH bpf-next v1 05/16] bpf: Allow scalar and atomic access to typed arena objects Kumar Kartikeya Dwivedi
2026-09-26 23:34 ` [RFC PATCH bpf-next v1 06/16] bpf: Support special fields in " Kumar Kartikeya Dwivedi
2026-09-26 23:59 ` sashiko-bot
2026-09-26 23:34 ` [RFC PATCH bpf-next v1 07/16] bpf: Trust typed pointer fields of " Kumar Kartikeya Dwivedi
2026-09-27 0:03 ` sashiko-bot
2026-09-26 23:34 ` [RFC PATCH bpf-next v1 08/16] bpf: Canonicalize loaded typed arena pointers where they are used Kumar Kartikeya Dwivedi
2026-09-26 23:34 ` [RFC PATCH bpf-next v1 09/16] bpf: Add typed arena page allocation and release kfuncs Kumar Kartikeya Dwivedi
2026-09-26 23:55 ` sashiko-bot
2026-09-26 23:34 ` [RFC PATCH bpf-next v1 10/16] bpf: Let typed_arena_cast copy pointers the verifier already trusts Kumar Kartikeya Dwivedi
2026-09-26 23:49 ` sashiko-bot
2026-09-26 23:34 ` [RFC PATCH bpf-next v1 11/16] libbpf: Support the typed_arena_cast instruction Kumar Kartikeya Dwivedi
2026-09-26 23:34 ` [RFC PATCH bpf-next v1 12/16] selftests/bpf: Build BPF objects with compiler-inserted typed arena casts Kumar Kartikeya Dwivedi
2026-09-26 23:46 ` sashiko-bot
2026-09-26 23:34 ` Kumar Kartikeya Dwivedi [this message]
2026-09-26 23:34 ` [RFC PATCH bpf-next v1 14/16] selftests/bpf: Test typed arena object access, kptrs and typed pointer fields Kumar Kartikeya Dwivedi
2026-09-26 23:34 ` [RFC PATCH bpf-next v1 15/16] selftests/bpf: Test typed arena page allocation and release Kumar Kartikeya Dwivedi
2026-09-26 23:46 ` sashiko-bot
2026-09-26 23:34 ` [RFC PATCH bpf-next v1 16/16] selftests/bpf: Exercise typed arenas at run time Kumar Kartikeya Dwivedi
2026-09-26 23:50 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260926233503.3114147-14-memxor@gmail.com \
--to=memxor@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=kernel-team@meta.com \
--cc=kkd@meta.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox