mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* Re: [PATCH bpf-next v5 1/3] bpf, x86: Support fetching AND/OR/XOR atomics in arena
       [not found] ` <20261016171319.1623447-2-puranjay@kernel.org>
@ 2026-10-16 17:49   ` Tejun Heo
  0 siblings, 0 replies; 2+ messages in thread
From: Tejun Heo @ 2026-10-16 17:49 UTC (permalink / raw)
  To: Puranjay Mohan
  Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, David Vernet, Andrea Righi,
	Changwoo Min, sched-ext, linux-kernel

On Fri, Oct 16, 2026 at 10:13:12AM -0700, Puranjay Mohan wrote:
> x86-64 has no single instruction for a fetching AND/OR/XOR, so the JIT
> lowers them to a CMPXCHG loop. That loop could not be used against arena
> memory: it contains two memory accesses, the load of the old value and
> the CMPXCHG itself, either of which can fault when the arena page goes
> away, while the verifier reserves only one exception table entry per
> instruction. bpf_jit_supports_insn() therefore rejected the three opcodes
> and such programs failed to load with
>
>   BPF_ATOMIC stores into R1 arena is not allowed
>
> Emit the same loop with R12-indexed addressing and give each of the two
> accesses its own exception table entry. The verifier still reserves one
> per instruction, so the JIT accounts for the extra entry itself by
> rescanning the instruction stream in bpf_int_jit_compile() before the
> extable is sized, as s390 does in bpf_jit_alloc() for its BPF_XCHG
> lowering. The rescan sits after the extra-pass early exit, so a program
> is counted exactly once. Drop the bpf_jit_supports_insn() rejection.
>
> A loop without the load would need only one entry, since a CMPXCHG that
> loses the comparison reloads RAX, but its first CMPXCHG would then almost
> always lose. Every operation would pay for a second locked CMPXCHG, which
> makes the fetching insn more expensive than the load and CMPXCHG loop
> programs write by hand today. The second entry is paid for once, in the
> JIT.
>
> Both entries resume past the whole loop rather than past the faulting
> instruction alone, with the fetch destination cleared, so a fault cannot
> re-enter the loop, and both are reported as writes since the BPF insn is
> a read-modify-write. This repurposes the INSN_LEN field of the fixup as a
> resume distance rather than an instruction length; a sequence long enough
> to overflow its 8 bits would first have to exceed BPF_MAX_INSN_SIZE, which
> do_jit() rejects before the image is used.
>
> The loop needs RAX for CMPXCHG and saves R0 in BPF_REG_AX, which it also
> substitutes for R0 when either operand is R0. ex_handler_bpf() may then
> have to name r10 as the register holding the arena address or the one to
> clear on fault; reg2pt_regs[] already has that entry.
>
> An access through a number, made by a program loaded with
> BPF_F_ARENA_SCALAR, keeps its address in BPF_REG_AX itself (see
> arena_scalar_access()), which is where the loop would save R0. Save R0 on
> the stack in that case, as the div and mod lowering does. An R0 operand
> stays in that stack slot: the new value is built from it, RAX ends up
> holding the old value that R0 is to return, and the slot is dropped
> instead of popped. Both entries resume before that pop or drop, so a
> fault leaves the stack balanced.
>
> Signed-off-by: Puranjay Mohan <puranjay@kernel.org>

Acked-by: Tejun Heo <tj@kernel.org>

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH bpf-next v5 2/3] selftests/bpf: Test fetching AND/OR/XOR atomics in arena
       [not found] ` <20261016171319.1623447-3-puranjay@kernel.org>
@ 2026-10-16 17:49   ` Tejun Heo
  0 siblings, 0 replies; 2+ messages in thread
From: Tejun Heo @ 2026-10-16 17:49 UTC (permalink / raw)
  To: Puranjay Mohan
  Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, David Vernet, Andrea Righi,
	Changwoo Min, sched-ext, linux-kernel

On Fri, Oct 16, 2026 at 10:13:13AM -0700, Puranjay Mohan wrote:
> The arena and/or/xor tests never exercised the fetching form of the
> instruction. Commit 2897b1e2a2f4 ("selftests/bpf: Fix arena_atomics
> failure due to llvm change") deliberately switched them to
> __c11_atomic_fetch_*() with memory_order_relaxed, which clang lowers to a
> non-fetching locked instruction when the result is unused, because
> x86-64 could not JIT the fetching one against an arena.
>
> It can now, so check the returned old value with __sync_fetch_and_*().
> Keep a __c11_atomic_fetch_*() of each width per operation with the result
> discarded: that spelling is what selects the non-fetching insn, which
> would otherwise lose its only coverage, on every architecture rather than
> just x86. Compiling the prog with clang 22 before and after confirms the
> split: 6 non-fetching and no fetching arena and/or/xor before, 6 and 22
> after.
>
> The new globals go in their operation's block, and the or block keeps its
> u32s first, so .addr_space.1 stays free of the padding holes that clang
> before 18 cannot fill when it is built without address space casts.
>
> Add a fetch_r0 test for the two register assignments the x86 JIT has to
> special-case, where the operand and where the arena pointer is R0 and
> BPF_REG_AX is substituted for it. Clang picks its own registers and will
> not reliably produce either, so spell the instructions out. The values
> have bits set above 32 so that a truncating move on that path shows up.
> Add both forms to the uaf test as well, since the substitution only
> reaches the exception table when such an access faults, and check that
> the fault cleared the fetched register and left the address alone. They
> fault on the page after the freed one: the freed page is the first of the
> arena, whose 32-bit address is 0, which would make the address check
> empty. The address is read back afterwards, which gives 0 if the JIT's
> exception table entry recovered the fault, but not if the arena had
> mapped its zeroed scratch page and let the access succeed. The powerpc64
> JIT does not clear the register of a faulting atomic yet, so those checks
> are skipped there.
>
> Both spell addr_space_cast textually, which needs LLVM 19, so uaf gains
> the __BPF_FEATURE_ADDR_SPACE_CAST guard that every other textual use in
> the file already has. It was plain C before and built on older clang.
>
> Drop x86 from the exclusion list of the uaf test, which covers the fault
> path. Its page is gone before the first access, so it faults on the load;
> the CMPXCHG entry is only reached when the page goes away between the two
> accesses, which a test cannot arrange.
>
> Finally cover fetching AND/OR/XOR through a number in
> verifier_arena_scalar, on x86-64 and arm64. Both widths are run with the
> operand in a register and in R0, which is where the x86-64 JIT keeps the
> operand on the stack because BPF_REG_AX holds the address. The 32-bit
> operands have bits set above 32 so that a missing zero-extension shows.
> The page is also freed first, after storing a nonzero value in it so that
> an access which did not fault would show, and the test checks that the
> fetched register comes back 0 and R0 is left alone, and that reading the
> address back gives 0. R0 is compared with a value derived from the page
> address: the verifier would decide a comparison with a constant at load
> time and drop it.
>
> Signed-off-by: Puranjay Mohan <puranjay@kernel.org>

Acked-by: Tejun Heo <tj@kernel.org>

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-10-16 17:49 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20261016171319.1623447-1-puranjay@kernel.org>
     [not found] ` <20261016171319.1623447-2-puranjay@kernel.org>
2026-10-16 17:49   ` [PATCH bpf-next v5 1/3] bpf, x86: Support fetching AND/OR/XOR atomics in arena Tejun Heo
     [not found] ` <20261016171319.1623447-3-puranjay@kernel.org>
2026-10-16 17:49   ` [PATCH bpf-next v5 2/3] selftests/bpf: Test " Tejun Heo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®