Skip to content

Commit 6ad4f09

Browse files
iii-iKernel Patches Daemon
authored andcommitted
s390/bpf: Use direct calls and jumps where possible
After the V!=R rework (commit c98d2ec ("s390/mm: Uncouple physical vs virtual address spaces")), all kernel code and related data are allocated within a 4G region, making it possible to use relative addressing in BPF code more extensively. Convert as many indirect calls and jumps to direct calls as possible, namely: * BPF_CALL * __bpf_tramp_enter() * __bpf_tramp_exit() * __bpf_prog_enter() * __bpf_prog_exit() * fentry * fmod_ret * fexit * BPF_TRAMP_F_CALL_ORIG without BPF_TRAMP_F_ORIG_STACK * Trampoline returns without BPF_TRAMP_F_SKIP_FRAME and BPF_TRAMP_F_ORIG_STACK The following indirect calls and jumps remain: * Prog returns * Trampoline returns with BPF_TRAMP_F_SKIP_FRAME or BPF_TRAMP_F_ORIG_STACK * BPF_TAIL_CALL * BPF_TRAMP_F_CALL_ORIG with BPF_TRAMP_F_ORIG_STACK As a result, only one usage of call_r1() remains, so inline it. Signed-off-by: Ilya Leoshkevich <[email protected]>
1 parent 715d6cb commit 6ad4f09

File tree

1 file changed

+32
-48
lines changed

1 file changed

+32
-48
lines changed

arch/s390/net/bpf_jit_comp.c

Lines changed: 32 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -674,20 +674,6 @@ static void bpf_jit_prologue(struct bpf_jit *jit, struct bpf_prog *fp)
674674
_EMIT2(0x07f0 | reg); \
675675
} while (0)
676676

677-
/*
678-
* Call r1 either directly or via __s390_indirect_jump_r1 thunk
679-
*/
680-
static void call_r1(struct bpf_jit *jit)
681-
{
682-
if (nospec_uses_trampoline())
683-
/* brasl %r14,__s390_indirect_jump_r1 */
684-
EMIT6_PCREL_RILB_PTR(0xc0050000, REG_14,
685-
__s390_indirect_jump_r1);
686-
else
687-
/* basr %r14,%r1 */
688-
EMIT2(0x0d00, REG_14, REG_1);
689-
}
690-
691677
/*
692678
* Function epilogue
693679
*/
@@ -1819,10 +1805,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
18191805
}
18201806
}
18211807

1822-
/* lgrl %w1,func */
1823-
EMIT6_PCREL_RILB(0xc4080000, REG_W1, _EMIT_CONST_U64(func));
1824-
/* %r1() */
1825-
call_r1(jit);
1808+
/* brasl %r14,func */
1809+
EMIT6_PCREL_RILB_PTR(0xc0050000, REG_14, (void *)func);
18261810
/* lgr %b0,%r2: load return value into %b0 */
18271811
EMIT4(0xb9040000, BPF_REG_0, REG_2);
18281812
break;
@@ -2517,14 +2501,12 @@ static int invoke_bpf_prog(struct bpf_tramp_jit *tjit,
25172501
* goto skip;
25182502
*/
25192503

2520-
/* %r1 = __bpf_prog_enter */
2521-
load_imm64(jit, REG_1, (u64)bpf_trampoline_enter(p));
25222504
/* %r2 = p */
25232505
load_imm64(jit, REG_2, (u64)p);
25242506
/* la %r3,run_ctx_off(%r15) */
25252507
EMIT4_DISP(0x41000000, REG_3, REG_15, tjit->run_ctx_off);
2526-
/* %r1() */
2527-
call_r1(jit);
2508+
/* brasl %r14,__bpf_prog_enter */
2509+
EMIT6_PCREL_RILB_PTR(0xc0050000, REG_14, bpf_trampoline_enter(p));
25282510
/* ltgr %r7,%r2 */
25292511
EMIT4(0xb9020000, REG_7, REG_2);
25302512
/* brcl 8,skip */
@@ -2535,15 +2517,13 @@ static int invoke_bpf_prog(struct bpf_tramp_jit *tjit,
25352517
* retval = bpf_func(args, p->insnsi);
25362518
*/
25372519

2538-
/* %r1 = p->bpf_func */
2539-
load_imm64(jit, REG_1, (u64)p->bpf_func);
25402520
/* la %r2,bpf_args_off(%r15) */
25412521
EMIT4_DISP(0x41000000, REG_2, REG_15, tjit->bpf_args_off);
25422522
/* %r3 = p->insnsi */
25432523
if (!p->jited)
25442524
load_imm64(jit, REG_3, (u64)p->insnsi);
2545-
/* %r1() */
2546-
call_r1(jit);
2525+
/* brasl %r14,p->bpf_func */
2526+
EMIT6_PCREL_RILB_PTR(0xc0050000, REG_14, p->bpf_func);
25472527
/* stg %r2,retval_off(%r15) */
25482528
if (save_ret) {
25492529
if (sign_extend(jit, REG_2, m->ret_size, m->ret_flags))
@@ -2560,16 +2540,14 @@ static int invoke_bpf_prog(struct bpf_tramp_jit *tjit,
25602540
* __bpf_prog_exit(p, start, &run_ctx);
25612541
*/
25622542

2563-
/* %r1 = __bpf_prog_exit */
2564-
load_imm64(jit, REG_1, (u64)bpf_trampoline_exit(p));
25652543
/* %r2 = p */
25662544
load_imm64(jit, REG_2, (u64)p);
25672545
/* lgr %r3,%r7 */
25682546
EMIT4(0xb9040000, REG_3, REG_7);
25692547
/* la %r4,run_ctx_off(%r15) */
25702548
EMIT4_DISP(0x41000000, REG_4, REG_15, tjit->run_ctx_off);
2571-
/* %r1() */
2572-
call_r1(jit);
2549+
/* brasl %r14,__bpf_prog_exit */
2550+
EMIT6_PCREL_RILB_PTR(0xc0050000, REG_14, bpf_trampoline_exit(p));
25732551

25742552
return 0;
25752553
}
@@ -2729,9 +2707,6 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
27292707

27302708
/* lgr %r8,%r0 */
27312709
EMIT4(0xb9040000, REG_8, REG_0);
2732-
} else {
2733-
/* %r8 = func_addr + S390X_PATCH_SIZE */
2734-
load_imm64(jit, REG_8, (u64)func_addr + S390X_PATCH_SIZE);
27352710
}
27362711

27372712
/*
@@ -2757,12 +2732,10 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
27572732
* __bpf_tramp_enter(im);
27582733
*/
27592734

2760-
/* %r1 = __bpf_tramp_enter */
2761-
load_imm64(jit, REG_1, (u64)__bpf_tramp_enter);
27622735
/* %r2 = im */
27632736
load_imm64(jit, REG_2, (u64)im);
2764-
/* %r1() */
2765-
call_r1(jit);
2737+
/* brasl %r14,__bpf_tramp_enter */
2738+
EMIT6_PCREL_RILB_PTR(0xc0050000, REG_14, __bpf_tramp_enter);
27662739
}
27672740

27682741
for (i = 0; i < fentry->nr_links; i++)
@@ -2815,10 +2788,19 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
28152788
/* mvc tail_call_cnt(4,%r15),tccnt_off(%r15) */
28162789
_EMIT6(0xd203f000 | offsetof(struct prog_frame, tail_call_cnt),
28172790
0xf000 | tjit->tccnt_off);
2818-
/* lgr %r1,%r8 */
2819-
EMIT4(0xb9040000, REG_1, REG_8);
2820-
/* %r1() */
2821-
call_r1(jit);
2791+
if (flags & BPF_TRAMP_F_ORIG_STACK) {
2792+
if (nospec_uses_trampoline())
2793+
/* brasl %r14,__s390_indirect_jump_r8 */
2794+
EMIT6_PCREL_RILB_PTR(0xc0050000, REG_14,
2795+
__s390_indirect_jump_r8);
2796+
else
2797+
/* basr %r14,%r8 */
2798+
EMIT2(0x0d00, REG_14, REG_8);
2799+
} else {
2800+
/* brasl %r14,func_addr+S390X_PATCH_SIZE */
2801+
EMIT6_PCREL_RILB_PTR(0xc0050000, REG_14,
2802+
func_addr + S390X_PATCH_SIZE);
2803+
}
28222804
/* stg %r2,retval_off(%r15) */
28232805
EMIT6_DISP_LH(0xe3000000, 0x0024, REG_2, REG_0, REG_15,
28242806
tjit->retval_off);
@@ -2846,12 +2828,10 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
28462828
* __bpf_tramp_exit(im);
28472829
*/
28482830

2849-
/* %r1 = __bpf_tramp_exit */
2850-
load_imm64(jit, REG_1, (u64)__bpf_tramp_exit);
28512831
/* %r2 = im */
28522832
load_imm64(jit, REG_2, (u64)im);
2853-
/* %r1() */
2854-
call_r1(jit);
2833+
/* brasl %r14,__bpf_tramp_exit */
2834+
EMIT6_PCREL_RILB_PTR(0xc0050000, REG_14, __bpf_tramp_exit);
28552835
}
28562836

28572837
/* lmg %r2,%rN,reg_args_off(%r15) */
@@ -2860,7 +2840,8 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
28602840
REG_2 + (nr_reg_args - 1), REG_15,
28612841
tjit->reg_args_off);
28622842
/* lgr %r1,%r8 */
2863-
if (!(flags & BPF_TRAMP_F_SKIP_FRAME))
2843+
if (!(flags & BPF_TRAMP_F_SKIP_FRAME) &&
2844+
(flags & BPF_TRAMP_F_ORIG_STACK))
28642845
EMIT4(0xb9040000, REG_1, REG_8);
28652846
/* lmg %r7,%r8,r7_r8_off(%r15) */
28662847
EMIT6_DISP_LH(0xeb000000, 0x0004, REG_7, REG_8, REG_15,
@@ -2879,9 +2860,12 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
28792860
EMIT4_IMM(0xa70b0000, REG_15, tjit->stack_size);
28802861
if (flags & BPF_TRAMP_F_SKIP_FRAME)
28812862
EMIT_JUMP_REG(14);
2882-
else
2863+
else if (flags & BPF_TRAMP_F_ORIG_STACK)
28832864
EMIT_JUMP_REG(1);
2884-
2865+
else
2866+
/* brcl 0xf,func_addr+S390X_PATCH_SIZE */
2867+
EMIT6_PCREL_RILC_PTR(0xc0040000, 0xf,
2868+
func_addr + S390X_PATCH_SIZE);
28852869
return 0;
28862870
}
28872871

0 commit comments

Comments
 (0)