mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
bpf: Emit timed may_goto for JITed progs only
The timed form of may_goto calls arch_bpf_timed_may_goto(). This function
takes its argument and returns its result in BPF_REG_AX, in a register of
the cpu. Only JITed code can call it.
The verifier emits the timed form when the arch has a JIT that supports it.
It does not look at the prog. With CONFIG_BPF_JIT_ALWAYS_ON=n the
interpreter can run such a prog: the JIT is off, or it fails. The
interpreter calls the function like a helper. The function takes what the C
code left in that register for a pointer, and bpf_check_timed_may_goto()
reads and writes through it.
Emit the timed form only when the prog asks for a JIT, and make the JIT
mandatory for such a prog. All other progs get the form that counts down
from BPF_MAX_LOOPS.
One test of verifier_may_goto_1 shows the insns of the timed form. Load it
only when progs are JITed.
Fixes: e723608bf4 ("bpf: Add verifier support for timed may_goto")
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20261031215543.682284-2-alexei.starovoitov@gmail.com
This commit is contained in:
parent
29f85bba33
commit
1ddffb57b3
|
|
@ -1823,6 +1823,8 @@ int bpf_do_misc_fixups(struct bpf_verifier_env *env)
|
|||
struct bpf_subprog_info *subprogs = env->subprog_info;
|
||||
u16 stack_depth = subprogs[cur_subprog].stack_depth;
|
||||
u16 stack_depth_extra = 0;
|
||||
/* arch_bpf_timed_may_goto() takes and returns AX in a cpu register: for JITs only */
|
||||
bool timed_may_goto = prog->jit_requested && bpf_jit_supports_timed_may_goto();
|
||||
|
||||
if (env->seen_exception && !env->exception_callback_subprog) {
|
||||
struct bpf_insn *patch = insn_buf;
|
||||
|
|
@ -2078,7 +2080,7 @@ int bpf_do_misc_fixups(struct bpf_verifier_env *env)
|
|||
goto next_insn;
|
||||
}
|
||||
|
||||
if (bpf_is_may_goto_insn(insn) && bpf_jit_supports_timed_may_goto()) {
|
||||
if (bpf_is_may_goto_insn(insn) && timed_may_goto) {
|
||||
int stack_off_cnt = -stack_depth - 16;
|
||||
/*
|
||||
* AX is used as an argument to pass in stack_off_cnt
|
||||
|
|
@ -2108,6 +2110,7 @@ int bpf_do_misc_fixups(struct bpf_verifier_env *env)
|
|||
* after subtraction, rinse and repeat.
|
||||
*/
|
||||
stack_depth_extra = 16;
|
||||
prog->jit_required = 1;
|
||||
cnt = may_goto_expand(insn_buf, insn->off, stack_off_cnt,
|
||||
tail, ARRAY_SIZE(tail));
|
||||
|
||||
|
|
@ -2730,7 +2733,7 @@ int bpf_do_misc_fixups(struct bpf_verifier_env *env)
|
|||
|
||||
env->prog->aux->stack_depth = subprogs[0].stack_depth;
|
||||
for (i = 0; i < env->subprog_cnt; i++) {
|
||||
int delta = bpf_jit_supports_timed_may_goto() ? 2 : 1;
|
||||
int delta = timed_may_goto ? 2 : 1;
|
||||
int subprog_start = subprogs[i].start;
|
||||
int stack_slots = subprogs[i].stack_extra / 8;
|
||||
int slots = delta, cnt = 0;
|
||||
|
|
@ -2744,7 +2747,7 @@ int bpf_do_misc_fixups(struct bpf_verifier_env *env)
|
|||
}
|
||||
|
||||
stack_depth = subprogs[i].stack_depth;
|
||||
if (bpf_jit_supports_timed_may_goto()) {
|
||||
if (timed_may_goto) {
|
||||
insn_buf[cnt++] = BPF_ST_MEM(BPF_DW, BPF_REG_FP, -stack_depth,
|
||||
BPF_MAX_TIMED_LOOPS);
|
||||
insn_buf[cnt++] = BPF_ST_MEM(BPF_DW, BPF_REG_FP, -stack_depth + 8, 0);
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ __naked void may_goto_batch_1(void)
|
|||
|
||||
SEC("raw_tp")
|
||||
__description("may_goto batch with offsets 2/0")
|
||||
__load_if_JITed()
|
||||
__arch_x86_64
|
||||
__arch_s390x
|
||||
__arch_arm64
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user