]> www.infradead.org Git - users/hch/misc.git/commitdiff
s390/bpf: Add s390 JIT support for timed may_goto
authorIlya Leoshkevich <iii@linux.ibm.com>
Thu, 21 Aug 2025 11:25:55 +0000 (13:25 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 26 Aug 2025 23:51:52 +0000 (16:51 -0700)
The verifier provides an architecture-independent implementation of the
may_goto instruction, which is currently used on s390x, but it has a
downside: there is no way to prevent progs using it from running for a
very long time.

The solution to this problem is an alternative timed implementation,
which requires architecture-specific bits. Its availability is signaled
to the verifier by bpf_jit_supports_timed_may_goto() returning true.

The verifier then emits a call to arch_bpf_timed_may_goto() using a
non-standard calling convention. This function must act as a trampoline
for bpf_check_timed_may_goto().

Implement bpf_jit_supports_timed_may_goto(), account for the special
calling convention in the BPF_CALL implementation, and implement
arch_bpf_timed_may_goto().

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Link: https://lore.kernel.org/r/20250821113339.292434-2-iii@linux.ibm.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
arch/s390/net/Makefile
arch/s390/net/bpf_jit_comp.c
arch/s390/net/bpf_timed_may_goto.S [new file with mode: 0644]

index 8cab6deb0403df6639431f3b64922c4794099d2e..9275cf63192aa76e9238f96577cd5c92180eabb5 100644 (file)
@@ -2,5 +2,5 @@
 #
 # Arch-specific network modules
 #
-obj-$(CONFIG_BPF_JIT) += bpf_jit_comp.o
+obj-$(CONFIG_BPF_JIT) += bpf_jit_comp.o bpf_timed_may_goto.o
 obj-$(CONFIG_HAVE_PNETID) += pnet.o
index fd45f03a213cf1f1cd519d6d8431c49e4578067d..8b57d8532f362ee8e23fb3117704f36b6cdcf252 100644 (file)
@@ -1806,10 +1806,22 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
                        }
                }
 
-               /* brasl %r14,func */
-               EMIT6_PCREL_RILB_PTR(0xc0050000, REG_14, (void *)func);
-               /* lgr %b0,%r2: load return value into %b0 */
-               EMIT4(0xb9040000, BPF_REG_0, REG_2);
+               if ((void *)func == arch_bpf_timed_may_goto) {
+                       /*
+                        * arch_bpf_timed_may_goto() has a special ABI: the
+                        * parameters are in BPF_REG_AX and BPF_REG_10; the
+                        * return value is in BPF_REG_AX; and all GPRs except
+                        * REG_W0, REG_W1, and BPF_REG_AX are callee-saved.
+                        */
+
+                       /* brasl %r0,func */
+                       EMIT6_PCREL_RILB_PTR(0xc0050000, REG_0, (void *)func);
+               } else {
+                       /* brasl %r14,func */
+                       EMIT6_PCREL_RILB_PTR(0xc0050000, REG_14, (void *)func);
+                       /* lgr %b0,%r2: load return value into %b0 */
+                       EMIT4(0xb9040000, BPF_REG_0, REG_2);
+               }
 
                /*
                 * Copy the potentially updated tail call counter back.
@@ -2993,3 +3005,8 @@ void arch_bpf_stack_walk(bool (*consume_fn)(void *, u64, u64, u64),
                prev_addr = addr;
        }
 }
+
+bool bpf_jit_supports_timed_may_goto(void)
+{
+       return true;
+}
diff --git a/arch/s390/net/bpf_timed_may_goto.S b/arch/s390/net/bpf_timed_may_goto.S
new file mode 100644 (file)
index 0000000..06f567a
--- /dev/null
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/export.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/nospec-insn.h>
+
+#define R2_OFF 0
+#define R5_OFF (R2_OFF + (5 - 2 + 1) * 8)
+#define R14_OFF (R5_OFF + 8)
+#define RETADDR_OFF (R14_OFF + 8)
+#define R15_OFF (RETADDR_OFF + 8)
+#define BACKCHAIN_OFF (R15_OFF + 8)
+#define FRAME_SIZE (BACKCHAIN_OFF + 8)
+#define FRAME_OFF (STACK_FRAME_OVERHEAD - FRAME_SIZE)
+#if (FRAME_OFF + BACKCHAIN_OFF) != __SF_BACKCHAIN
+#error Stack frame layout calculation is broken
+#endif
+
+       GEN_BR_THUNK %r1
+
+SYM_FUNC_START(arch_bpf_timed_may_goto)
+       /*
+        * This function has a special ABI: the parameters are in %r12 and
+        * %r13; the return value is in %r12; all GPRs except %r0, %r1, and
+        * %r12 are callee-saved; and the return address is in %r0.
+        */
+       stmg %r2,%r5,FRAME_OFF+R2_OFF(%r15)
+       stg %r14,FRAME_OFF+R14_OFF(%r15)
+       stg %r0,FRAME_OFF+RETADDR_OFF(%r15)
+       stg %r15,FRAME_OFF+R15_OFF(%r15)
+       lgr %r1,%r15
+       lay %r15,-FRAME_SIZE(%r15)
+       stg %r1,__SF_BACKCHAIN(%r15)
+
+       lay %r2,0(%r12,%r13)
+       brasl %r14,bpf_check_timed_may_goto
+       lgr %r12,%r2
+
+       lg %r15,FRAME_SIZE+FRAME_OFF+R15_OFF(%r15)
+       lmg %r2,%r5,FRAME_OFF+R2_OFF(%r15)
+       lg %r14,FRAME_OFF+R14_OFF(%r15)
+       lg %r1,FRAME_OFF+RETADDR_OFF(%r15)
+       BR_EX %r1
+SYM_FUNC_END(arch_bpf_timed_may_goto)