On 11/06/26 9:08 pm, [email protected] wrote:
From: Abhishek Dubey <[email protected]>

The tail_call_info field can contain either a scalar counter
value or a 64-bit pointer to the counter, using a 32-bit
compare (cmplwi) only checks the lower 32 bits, which can lead
to incorrect comparisions when location of counter is near 4GB
boundary. Use instruction cmpldi for accurate comparision in
all cases.

Reported-by: [email protected]
Closes: https://lore.kernel.org/bpf/[email protected]/
Fixes: 2ed2d8f6fb38 ("powerpc64/bpf: Support tailcalls with subprogs")
Signed-off-by: Abhishek Dubey <[email protected]>
---
  arch/powerpc/net/bpf_jit_comp.c   | 2 +-
  arch/powerpc/net/bpf_jit_comp64.c | 8 ++++----
  2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index ebee23d33396..b36b55f12a8b 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -763,7 +763,7 @@ static void bpf_trampoline_setup_tail_call_info(u32 *image, 
struct codegen_conte
                 * Setting the tail_call_info in trampoline's frame
                 * depending on if previous frame had value or reference.
                 */

-               EMIT(PPC_RAW_CMPLWI(_R3, MAX_TAIL_CALL_CNT));
+               EMIT(PPC_RAW_CMPLDI(_R3, MAX_TAIL_CALL_CNT));

This should be "Use cmpldi/cmplwi instruction" instead of "Use
instruction cmpldi"

This code is meant for both 32-bit and 64-bit powerpc. So, can't
simply use PPC_RAW_CMPLDI here. Instead, similar to PPC_RAW_CMPLI
& PPC_RAW_LL macros, define PPC_RAW_CMPLLI to resolve it as
PPC_RAW_CMPLDI for ppc64 and PPC_RAW_CMPLWI for ppc32..

                PPC_BCC_CONST_SHORT(COND_GT, 8);
                EMIT(PPC_RAW_ADDI(_R3, _R4, -BPF_PPC_TAILCALL));
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
index eaf816a07f14..086084abb184 100644
--- a/arch/powerpc/net/bpf_jit_comp64.c
+++ b/arch/powerpc/net/bpf_jit_comp64.c
@@ -276,7 +276,7 @@ void bpf_jit_build_prologue(u32 *image, struct 
codegen_context *ctx)
                 */
                EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_2), _R1, 0));
                EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_1), bpf_to_ppc(TMP_REG_2), 
-(BPF_PPC_TAILCALL)));
-               EMIT(PPC_RAW_CMPLWI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
+               EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
                PPC_BCC_CONST_SHORT(COND_GT, 8);
                EMIT(PPC_RAW_ADDI(bpf_to_ppc(TMP_REG_1), bpf_to_ppc(TMP_REG_2),
                                                                
-(BPF_PPC_TAILCALL)));
@@ -651,7 +651,7 @@ static int bpf_jit_emit_tail_call(u32 *image, struct 
codegen_context *ctx, u32 o
        PPC_BCC_SHORT(COND_GE, out);
EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_1), _R1, bpf_jit_stack_tailcallinfo_offset(ctx)));
-       EMIT(PPC_RAW_CMPLWI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
+       EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
        PPC_BCC_CONST_SHORT(COND_LE, 8);
/* dereference TMP_REG_1 */
@@ -661,7 +661,7 @@ static int bpf_jit_emit_tail_call(u32 *image, struct 
codegen_context *ctx, u32 o
         * if (tail_call_info == MAX_TAIL_CALL_CNT)
         *   goto out;
         */
-       EMIT(PPC_RAW_CMPLWI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
+       EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
        PPC_BCC_SHORT(COND_EQ, out);
/*
@@ -696,7 +696,7 @@ static int bpf_jit_emit_tail_call(u32 *image, struct 
codegen_context *ctx, u32 o
         * tail_call_info.
         */
        EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_2), _R1, 
bpf_jit_stack_tailcallinfo_offset(ctx)));
-       EMIT(PPC_RAW_CMPLWI(bpf_to_ppc(TMP_REG_2), MAX_TAIL_CALL_CNT));
+       EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_2), MAX_TAIL_CALL_CNT));
        PPC_BCC_CONST_SHORT(COND_GT, 8);
/* First get address of tail_call_info */

- Hari

Reply via email to