]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
powerpc/ebpf32: Use standard function call for functions within 32M distance
authorChristophe Leroy <christophe.leroy@csgroup.eu>
Mon, 12 Apr 2021 11:44:18 +0000 (11:44 +0000)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 21 Apr 2021 12:52:33 +0000 (22:52 +1000)
If the target of a function call is within 32 Mbytes distance, use a
standard function call with 'bl' instead of the 'lis/ori/mtlr/blrl'
sequence.

In the first pass, no memory has been allocated yet and the code
position is not known yet (image pointer is NULL). This pass is there
to calculate the amount of memory to allocate for the EBPF code, so
assume the 4 instructions sequence is required, so that enough memory
is allocated.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/74944a1e3e5cfecc141e440a6ccd37920e186b70.1618227846.git.christophe.leroy@csgroup.eu
arch/powerpc/include/asm/ppc-opcode.h
arch/powerpc/net/bpf_jit.h
arch/powerpc/net/bpf_jit_comp32.c

index 5b60020dc1f43c3c63ae18f7cf08c3d1ef879682..ac41776661e96300f5f2d66c1094f9800db2eb63 100644 (file)
 #define PPC_INST_ORI                   0x60000000
 #define PPC_INST_ORIS                  0x64000000
 #define PPC_INST_BRANCH                        0x48000000
+#define PPC_INST_BL                    0x48000001
 #define PPC_INST_BRANCH_COND           0x40800000
 
 /* Prefixes */
index 776abef4d2a0a7fa8692f0aa72ea37baab2c6e71..99fad093f43ec105775d1983edfa85a37e0d1f5c 100644 (file)
@@ -26,6 +26,9 @@
 /* Long jump; (unconditional 'branch') */
 #define PPC_JMP(dest)          EMIT(PPC_INST_BRANCH |                        \
                                     (((dest) - (ctx->idx * 4)) & 0x03fffffc))
+/* blr; (unconditional 'branch' with link) to absolute address */
+#define PPC_BL_ABS(dest)       EMIT(PPC_INST_BL |                            \
+                                    (((dest) - (unsigned long)(image + ctx->idx)) & 0x03fffffc))
 /* "cond" here covers BO:BI fields. */
 #define PPC_BCC_SHORT(cond, dest)      EMIT(PPC_INST_BRANCH_COND |           \
                                             (((cond) & 0x3ff) << 16) |       \
index ef21b09df76ed8cc05e939d44dfbeb4a5257a521..bbb16099e8c7fa384922f768b5ca3734670cc28b 100644 (file)
@@ -187,11 +187,17 @@ void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
 
 void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 func)
 {
-       /* Load function address into r0 */
-       EMIT(PPC_RAW_LIS(__REG_R0, IMM_H(func)));
-       EMIT(PPC_RAW_ORI(__REG_R0, __REG_R0, IMM_L(func)));
-       EMIT(PPC_RAW_MTLR(__REG_R0));
-       EMIT(PPC_RAW_BLRL());
+       s32 rel = (s32)func - (s32)(image + ctx->idx);
+
+       if (image && rel < 0x2000000 && rel >= -0x2000000) {
+               PPC_BL_ABS(func);
+       } else {
+               /* Load function address into r0 */
+               EMIT(PPC_RAW_LIS(__REG_R0, IMM_H(func)));
+               EMIT(PPC_RAW_ORI(__REG_R0, __REG_R0, IMM_L(func)));
+               EMIT(PPC_RAW_MTLR(__REG_R0));
+               EMIT(PPC_RAW_BLRL());
+       }
 }
 
 static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)