All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yonghong Song <yonghong.song@linux.dev>
To: Puranjay Mohan <puranjay@kernel.org>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>,
	Martin KaFai Lau <martin.lau@linux.dev>,
	Eduard Zingerman <eddyz87@gmail.com>, Song Liu <song@kernel.org>,
	John Fastabend <john.fastabend@gmail.com>,
	KP Singh <kpsingh@kernel.org>,
	Stanislav Fomichev <sdf@fomichev.me>, Hao Luo <haoluo@google.com>,
	Jiri Olsa <jolsa@kernel.org>,
	Xu Kuohai <xukuohai@huaweicloud.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>,
	Kumar Kartikeya Dwivedi <memxor@gmail.com>,
	bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next v4 3/3] selftests/bpf: Add tests for arena fault reporting
Date: Thu, 28 Aug 2025 08:44:14 -0700	[thread overview]
Message-ID: <cb068cb2-5432-43fb-b798-c2bda2bbc173@linux.dev> (raw)
In-Reply-To: <mb61pbjnzmy4d.fsf@kernel.org>



On 8/28/25 5:25 AM, Puranjay Mohan wrote:
> Yonghong Song <yonghong.song@linux.dev> writes:
>
>> On 8/27/25 8:37 AM, Puranjay Mohan wrote:
>>> Add selftests for testing the reporting of arena page faults through BPF
>>> streams. Two new bpf programs are added that read and write to an
>>> unmapped arena address and the fault reporting is verified in the
>>> userspace through streams.
>>>
>>> Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
>>> ---
>>>    .../testing/selftests/bpf/prog_tests/stream.c | 33 +++++++++++++++-
>>>    tools/testing/selftests/bpf/progs/stream.c    | 39 +++++++++++++++++++
>>>    2 files changed, 71 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/tools/testing/selftests/bpf/prog_tests/stream.c b/tools/testing/selftests/bpf/prog_tests/stream.c
>>> index 36a1a1ebde692..8fdc83260ea14 100644
>>> --- a/tools/testing/selftests/bpf/prog_tests/stream.c
>>> +++ b/tools/testing/selftests/bpf/prog_tests/stream.c
>>> @@ -41,6 +41,22 @@ struct {
>>>    		"([a-zA-Z_][a-zA-Z0-9_]*\\+0x[0-9a-fA-F]+/0x[0-9a-fA-F]+\n"
>>>    		"|[ \t]+[^\n]+\n)*",
>>>    	},
>>> +	{
>>> +		offsetof(struct stream, progs.stream_arena_read_fault),
>>> +		"ERROR: Arena READ access at unmapped address 0x.*\n"
>>> +		"CPU: [0-9]+ UID: 0 PID: [0-9]+ Comm: .*\n"
>>> +		"Call trace:\n"
>>> +		"([a-zA-Z_][a-zA-Z0-9_]*\\+0x[0-9a-fA-F]+/0x[0-9a-fA-F]+\n"
>>> +		"|[ \t]+[^\n]+\n)*",
>>> +	},
>>> +	{
>>> +		offsetof(struct stream, progs.stream_arena_write_fault),
>>> +		"ERROR: Arena WRITE access at unmapped address 0x.*\n"
>>> +		"CPU: [0-9]+ UID: 0 PID: [0-9]+ Comm: .*\n"
>>> +		"Call trace:\n"
>>> +		"([a-zA-Z_][a-zA-Z0-9_]*\\+0x[0-9a-fA-F]+/0x[0-9a-fA-F]+\n"
>>> +		"|[ \t]+[^\n]+\n)*",
>>> +	},
>>>    };
>>>    
>>>    static int match_regex(const char *pattern, const char *string)
>>> @@ -63,6 +79,7 @@ void test_stream_errors(void)
>>>    	struct stream *skel;
>>>    	int ret, prog_fd;
>>>    	char buf[1024];
>>> +	char fault_addr[64] = {0};
>> You can replace '{0}' to '{}' so the whole array will be initialized.
> Ack!
>
>>>    
>>>    	skel = stream__open_and_load();
>>>    	if (!ASSERT_OK_PTR(skel, "stream__open_and_load"))
>>> @@ -85,6 +102,14 @@ void test_stream_errors(void)
>>>    			continue;
>>>    		}
>>>    #endif
>>> +#if !defined(__x86_64__) && !defined(__aarch64__)
>>> +		ASSERT_TRUE(1, "Arena fault reporting unsupported, skip.");
>>> +		if (i == 2 || i == 3) {
>>> +			ret = bpf_prog_stream_read(prog_fd, 2, buf, sizeof(buf), &ropts);
>>> +			ASSERT_EQ(ret, 0, "stream read");
>>> +			continue;
>>> +		}
>>> +#endif
>>>    
>>>    		ret = bpf_prog_stream_read(prog_fd, BPF_STREAM_STDERR, buf, sizeof(buf), &ropts);
>>>    		ASSERT_GT(ret, 0, "stream read");
>>> @@ -92,8 +117,14 @@ void test_stream_errors(void)
>>>    		buf[ret] = '\0';
>>>    
>>>    		ret = match_regex(stream_error_arr[i].errstr, buf);
>>> -		if (!ASSERT_TRUE(ret == 1, "regex match"))
>>> +		if (ret && (i == 2 || i == 3)) {
>>> +			sprintf(fault_addr, "0x%lx", skel->bss->fault_addr);
>>> +			ret = match_regex(fault_addr, buf);
>>> +		}
>>> +		if (!ASSERT_TRUE(ret == 1, "regex match")) {
>>>    			fprintf(stderr, "Output from stream:\n%s\n", buf);
>>> +			fprintf(stderr, "Fault Addr: 0x%lx\n", skel->bss->fault_addr);
>> This will fault addr even for i == 0 or i == 1 and those address may be confusing
>> for test 0/1.
> Will add a check before printing this.
>
>>> +		}
>>>    	}
>>>    
>>>    	stream__destroy(skel);
>>> diff --git a/tools/testing/selftests/bpf/progs/stream.c b/tools/testing/selftests/bpf/progs/stream.c
>>> index 35790897dc879..9de015ac3ced5 100644
>>> --- a/tools/testing/selftests/bpf/progs/stream.c
>>> +++ b/tools/testing/selftests/bpf/progs/stream.c
>>> @@ -5,6 +5,7 @@
>>>    #include <bpf/bpf_helpers.h>
>>>    #include "bpf_misc.h"
>>>    #include "bpf_experimental.h"
>>> +#include "bpf_arena_common.h"
>>>    
>>>    struct arr_elem {
>>>    	struct bpf_res_spin_lock lock;
>>> @@ -17,10 +18,17 @@ struct {
>>>    	__type(value, struct arr_elem);
>>>    } arrmap SEC(".maps");
>>>    
>>> +struct {
>>> +	__uint(type, BPF_MAP_TYPE_ARENA);
>>> +	__uint(map_flags, BPF_F_MMAPABLE);
>>> +	__uint(max_entries, 1); /* number of pages */
>>> +} arena SEC(".maps");
>>> +
>>>    #define ENOSPC 28
>>>    #define _STR "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
>>>    
>>>    int size;
>>> +u64 fault_addr;
>>>    
>>>    SEC("syscall")
>>>    __success __retval(0)
>>> @@ -76,4 +84,35 @@ int stream_syscall(void *ctx)
>>>    	return 0;
>>>    }
>>>    
>>> +SEC("syscall")
>>> +__success __retval(0)
>>> +int stream_arena_write_fault(void *ctx)
>>> +{
>>> +	struct bpf_arena *ptr = (void *)&arena;
>>> +	u64 user_vm_start;
>>> +
>>> +	barrier_var(ptr);
>> Do we need this barrier_var()? I tried llvm20 and it works fine without the
>> above barrier_var().
> As kumar explained in his reply, this is for making it build with GCC,
> without the barrier_var() GCC fails with:
>
>    progs/stream.c: In function ‘stream_arena_write_fault’:
>    progs/stream.c:91:76: error: array subscript ‘struct bpf_arena[0]’ is partly outside array bounds of ‘struct <anonymous>[1]’ [-Werror=array-bounds=]
>       91 |         u64 user_vm_start = ((struct bpf_arena *)(uintptr_t)(void *)&arena)->user_vm_start;
>          |                                                                            ^~
>    progs/stream.c:25:3: note: object ‘arena’ of size 24
>       25 | } arena SEC(".maps");
>          |   ^~~~~
>      GCC-BPF  [test_progs-bpf_gcc] struct_ops_refcounted_fail__tail_call.bpf.o
>    progs/stream.c: In function ‘stream_arena_read_fault’:
>    progs/stream.c:103:85: error: array subscript ‘struct bpf_arena[0]’ is partly outside array bounds of ‘struct <anonymous>[1]’ [-Werror=array-bounds=]
>      103 |         volatile u64 user_vm_start = ((struct bpf_arena *)(uintptr_t)(void *)&arena)->user_vm_start;
>          |                                                                                     ^~
>    progs/stream.c:25:3: note: object ‘arena’ of size 24
>       25 | } arena SEC(".maps");
>          |   ^~~~~
>    cc1: all warnings being treated as errors

It would be great if you can have the above in the commit message.

Please also put a small comments in the code such that
without barrier_var(), gcc will do some transformation like
   u64 user_vm_start = ((struct bpf_arena *)(uintptr_t)(void *)&arena)->user_vm_start;
and this will cause struct out-of-bound access due to the casting
from smaller map struct to larger "struct bpf_arena".
clang does not have this issue.

>
>>> +	user_vm_start =  ptr->user_vm_start;
>>> +
>> Remove this line.
>>
>>> +	fault_addr = user_vm_start + 0xbeef;
>>> +	*(u32 __arena *)(user_vm_start + 0xbeef) = 1;
>> Simplify to *(u32 __arena *)fault = 1;
> I wanted it to compile to an instruction with *(u32 *)src + offset = 1, which
> was naive of me to think but now I will rewrite this in inline assembly to
> also test dst_reg == src_reg case which Kumar found out.
>
> Thanks,
> Puranjay


  reply	other threads:[~2025-08-28 15:44 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-27 15:37 [PATCH bpf-next v4 0/3] bpf: Report arena faults to BPF streams Puranjay Mohan
2025-08-27 15:37 ` [PATCH bpf-next v4 1/3] bpf: arm64: simplify exception table handling Puranjay Mohan
2025-08-28  0:19   ` Kumar Kartikeya Dwivedi
2025-08-29 10:06   ` Xu Kuohai
2025-08-27 15:37 ` [PATCH bpf-next v4 2/3] bpf: Report arena faults to BPF stderr Puranjay Mohan
2025-08-28  0:22   ` Kumar Kartikeya Dwivedi
2025-08-28  0:27     ` Kumar Kartikeya Dwivedi
2025-08-28 12:14     ` Puranjay Mohan
2025-08-29 10:30   ` Xu Kuohai
2025-08-29 20:28     ` Alexei Starovoitov
2025-09-01 13:34       ` Puranjay Mohan
2025-09-01 16:39         ` Alexei Starovoitov
2025-09-01 19:22           ` Puranjay Mohan
2025-09-01 22:44             ` Kumar Kartikeya Dwivedi
2025-09-02  2:18               ` Alexei Starovoitov
2025-08-27 15:37 ` [PATCH bpf-next v4 3/3] selftests/bpf: Add tests for arena fault reporting Puranjay Mohan
2025-08-27 19:54   ` Yonghong Song
2025-08-27 23:49     ` Kumar Kartikeya Dwivedi
2025-08-28 12:25     ` Puranjay Mohan
2025-08-28 15:44       ` Yonghong Song [this message]
2025-08-28  0:23 ` [PATCH bpf-next v4 0/3] bpf: Report arena faults to BPF streams Kumar Kartikeya Dwivedi
2025-08-28 12:13   ` Puranjay Mohan

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=cb068cb2-5432-43fb-b798-c2bda2bbc173@linux.dev \
    --to=yonghong.song@linux.dev \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=haoluo@google.com \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=kpsingh@kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=memxor@gmail.com \
    --cc=puranjay@kernel.org \
    --cc=sdf@fomichev.me \
    --cc=song@kernel.org \
    --cc=will@kernel.org \
    --cc=xukuohai@huaweicloud.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.