s390/bpf: Implement unconditional jump with 32-bit offset
authorIlya Leoshkevich <iii@linux.ibm.com>
Tue, 19 Sep 2023 10:09:09 +0000 (12:09 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 21 Sep 2023 21:22:00 +0000 (14:22 -0700)
Implement the cpuv4 unconditional jump with 32-bit offset, which is
encoded as BPF_JMP32 | BPF_JA and stores the offset in the imm field.
Reuse the existing BPF_JMP | BPF_JA logic.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Link: https://lore.kernel.org/r/20230919101336.2223655-8-iii@linux.ibm.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
arch/s390/net/bpf_jit_comp.c

index 77362dc9229b017efcafa54dec850b60f04d1ca2..d41e6443cc97437d469e9fd12c342a7319553e2d 100644 (file)
@@ -779,6 +779,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
                                 int i, bool extra_pass, u32 stack_depth)
 {
        struct bpf_insn *insn = &fp->insnsi[i];
+       s16 branch_oc_off = insn->off;
        u32 dst_reg = insn->dst_reg;
        u32 src_reg = insn->src_reg;
        int last, insn_count = 1;
@@ -1625,6 +1626,9 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
         * instruction itself (loop) and for BPF with offset 0 we
         * branch to the instruction behind the branch.
         */
+       case BPF_JMP32 | BPF_JA: /* if (true) */
+               branch_oc_off = imm;
+               fallthrough;
        case BPF_JMP | BPF_JA: /* if (true) */
                mask = 0xf000; /* j */
                goto branch_oc;
@@ -1793,14 +1797,16 @@ branch_xu:
                break;
 branch_oc:
                if (!is_first_pass(jit) &&
-                   can_use_rel(jit, addrs[i + off + 1])) {
+                   can_use_rel(jit, addrs[i + branch_oc_off + 1])) {
                        /* brc mask,off */
                        EMIT4_PCREL_RIC(0xa7040000,
-                                       mask >> 12, addrs[i + off + 1]);
+                                       mask >> 12,
+                                       addrs[i + branch_oc_off + 1]);
                } else {
                        /* brcl mask,off */
                        EMIT6_PCREL_RILC(0xc0040000,
-                                        mask >> 12, addrs[i + off + 1]);
+                                        mask >> 12,
+                                        addrs[i + branch_oc_off + 1]);
                }
                break;
        }