mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
bpf: Add helper macro bpf_for_each_reg_in_vstate
For a lot of use cases in future patches, we will want to modify the state of registers part of some same 'group' (e.g. same ref_obj_id). It won't just be limited to releasing reference state, but setting a type flag dynamically based on certain actions, etc. Hence, we need a way to easily pass a callback to the function that iterates over all registers in current bpf_verifier_state in all frames upto (and including) the curframe. While in C++ we would be able to easily use a lambda to pass state and the callback together, sadly we aren't using C++ in the kernel. The next best thing to avoid defining a function for each case seems like statement expressions in GNU C. The kernel already uses them heavily, hence they can passed to the macro in the style of a lambda. The statement expression will then be substituted in the for loop bodies. Variables __state and __reg are set to current bpf_func_state and reg for each invocation of the expression inside the passed in verifier state. Then, convert mark_ptr_or_null_regs, clear_all_pkt_pointers, release_reference, find_good_pkt_pointers, find_equal_scalars to use bpf_for_each_reg_in_vstate. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/r/20220904204145.3089-16-memxor@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
cc48755808
commit
b239da3420
2 changed files with 50 additions and 108 deletions
|
@ -348,6 +348,27 @@ struct bpf_verifier_state {
|
|||
iter < frame->allocated_stack / BPF_REG_SIZE; \
|
||||
iter++, reg = bpf_get_spilled_reg(iter, frame))
|
||||
|
||||
/* Invoke __expr over regsiters in __vst, setting __state and __reg */
|
||||
#define bpf_for_each_reg_in_vstate(__vst, __state, __reg, __expr) \
|
||||
({ \
|
||||
struct bpf_verifier_state *___vstate = __vst; \
|
||||
int ___i, ___j; \
|
||||
for (___i = 0; ___i <= ___vstate->curframe; ___i++) { \
|
||||
struct bpf_reg_state *___regs; \
|
||||
__state = ___vstate->frame[___i]; \
|
||||
___regs = __state->regs; \
|
||||
for (___j = 0; ___j < MAX_BPF_REG; ___j++) { \
|
||||
__reg = &___regs[___j]; \
|
||||
(void)(__expr); \
|
||||
} \
|
||||
bpf_for_each_spilled_reg(___j, __state, __reg) { \
|
||||
if (!__reg) \
|
||||
continue; \
|
||||
(void)(__expr); \
|
||||
} \
|
||||
} \
|
||||
})
|
||||
|
||||
/* linked list of verifier states used to prune search */
|
||||
struct bpf_verifier_state_list {
|
||||
struct bpf_verifier_state state;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue