Commit 4c5f21d4 authored by Emil Tsalapatis's avatar Emil Tsalapatis Committed by Alexei Starovoitov
Browse files

selftests/bpf: Add tests for non-arena/arena operations



Add a selftest that ensures instructions with arena source and
non-arena destination registers are accepted by the verifier.

Signed-off-by: default avatarEmil Tsalapatis <emil@etsalapatis.com>
Acked-by: default avatarSong Liu <song@kernel.org>
Link: https://lore.kernel.org/r/20260412174546.18684-3-emil@etsalapatis.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent ac61bffe
Loading
Loading
Loading
Loading
+130 −0
Original line number Diff line number Diff line
@@ -477,4 +477,134 @@ int arena_kfuncs_under_bpf_lock(void *ctx)

	return 0;
}

#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)

/*
 * Test that scalar += PTR_TO_ARENA correctly upgrades the
 * destination register to a PTR_TO_ARENA.
 */
SEC("syscall")
__success __retval(0)
int scalar_add_arena_ptr(void *ctx)
{
	int __arena *scalar, *arena_ptr;

	volatile char __arena *base = arena_base(&arena);

	asm volatile (
		"%[arena_ptr] = 8192;"
		"%[arena_ptr] = addr_space_cast(%[arena_ptr], 0x0, 0x1);"
		"%[scalar] = 12;"
		"%[scalar] += %[arena_ptr];"
		: [scalar] "=r"(scalar),
		  [arena_ptr] "=&r"(arena_ptr)
		: "r"(base)
		:
	);
	return 0;
}

/*
 * Tests that PTR_TO_ARENA + PTR_TO_ARENA is allowed.
 */
SEC("syscall")
__success __retval(0)
int arena_ptr_add_arena_ptr(void *ctx)
{
	int __arena *arena_ptr2, *arena_ptr1;

	/* Needed for the verifier to link the arena to the subprog. */
	volatile char __arena *base = arena_base(&arena);

	asm volatile (
		"%[arena_ptr1] = 8192;"
		"%[arena_ptr1] = addr_space_cast(%[arena_ptr1], 0x0, 0x1);"
		"%[arena_ptr2] = 4096;"
		"%[arena_ptr2] = addr_space_cast(%[arena_ptr2], 0x0, 0x1);"
		"%[arena_ptr2] += %[arena_ptr1];"
		: [arena_ptr2] "=r"(arena_ptr2),
		  [arena_ptr1] "=&r"(arena_ptr1)
		: "r"(base)
		:
	);
	return 0;
}

SEC("syscall")
__success __retval(0)
int scalar_xor_arena_ptr(void *ctx)
{
	int __arena *scalar, *arena_ptr;

	volatile char __arena *base = arena_base(&arena);

	asm volatile (
		"%[arena_ptr] = 8192;"
		"%[arena_ptr] = addr_space_cast(%[arena_ptr], 0x0, 0x1);"
		"%[scalar] = 12;"
		"%[scalar] ^= %[arena_ptr];"
		: [scalar] "=r"(scalar),
		  [arena_ptr] "=&r"(arena_ptr)
		: "r"(base)
		:
	);
	return 0;
}

/*
 * Tests that PTR_TO_ARENA and non-arena pointers can be added.
 */
SEC("syscall")
__success __retval(0)
int arena_ptr_add_to_non_arena_ptr(void *ctx)
{
	register int __arena *arena_ptr asm("r3");
	register void *dst asm("r4");

	volatile char __arena *base = arena_base(&arena);

	asm volatile (
		"%[arena_ptr] = 8192;"
		"%[arena_ptr] = addr_space_cast(%[arena_ptr], 0x0, 0x1);"
		"%[dst] = %[ctx];"
		"%[dst] += %[arena_ptr];"
		: [arena_ptr] "=&r"(arena_ptr),
		  [dst] "=&r"(dst)
		: [ctx] "r"(ctx), "r"(base)
		:
	);

	(void)ctx;

	return 0;
}

SEC("syscall")
__success __retval(0)
int non_arena_ptr_add_to_arena_ptr(void *ctx)
{
	register int __arena *arena_ptr asm("r3");
	register void *src asm("r4");

	volatile char __arena *base = arena_base(&arena);

	asm volatile (
		"%[arena_ptr] = 8192;"
		"%[arena_ptr] = addr_space_cast(%[arena_ptr], 0x0, 0x1);"
		"%[src] = %[ctx];"
		"%[arena_ptr] += %[src];"
		: [arena_ptr] "=&r"(arena_ptr),
		  [src] "=&r"(src)
		: [ctx] "r"(ctx), "r"(base)
		:
	);

	(void)ctx;

	return 0;
}

#endif

char _license[] SEC("license") = "GPL";