@@ -1451,6 +1451,32 @@ void arch_free_bpf_trampoline(void *image, unsigned int size)
1451
1451
bpf_prog_pack_free (image , size );
1452
1452
}
1453
1453
1454
+ /*
1455
+ * Sign-extend the register if necessary
1456
+ */
1457
+ static void sign_extend (struct jit_ctx * ctx , int rd , int rj , u8 size , u8 flags )
1458
+ {
1459
+ if (!(flags & BTF_FMODEL_SIGNED_ARG ) && size != 8 )
1460
+ return ;
1461
+
1462
+ switch (size ) {
1463
+ case 1 :
1464
+ emit_insn (ctx , extwb , rd , rj );
1465
+ break ;
1466
+ case 2 :
1467
+ emit_insn (ctx , extwh , rd , rj );
1468
+ break ;
1469
+ case 4 :
1470
+ emit_insn (ctx , addiw , rd , rj , 0 );
1471
+ break ;
1472
+ case 8 :
1473
+ move_reg (ctx , rd , rj );
1474
+ break ;
1475
+ default :
1476
+ pr_warn ("bpf_jit: invalid size %d for sign_extend\n" , size );
1477
+ }
1478
+ }
1479
+
1454
1480
static int __arch_prepare_bpf_trampoline (struct jit_ctx * ctx , struct bpf_tramp_image * im ,
1455
1481
const struct btf_func_model * m , struct bpf_tramp_links * tlinks ,
1456
1482
void * func_addr , u32 flags )
@@ -1659,8 +1685,12 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
1659
1685
restore_args (ctx , m -> nr_args , args_off );
1660
1686
1661
1687
if (save_ret ) {
1662
- emit_insn (ctx , ldd , LOONGARCH_GPR_A0 , LOONGARCH_GPR_FP , - retval_off );
1663
1688
emit_insn (ctx , ldd , regmap [BPF_REG_0 ], LOONGARCH_GPR_FP , - (retval_off - 8 ));
1689
+ if (is_struct_ops )
1690
+ sign_extend (ctx , LOONGARCH_GPR_A0 , regmap [BPF_REG_0 ],
1691
+ m -> ret_size , m -> ret_flags );
1692
+ else
1693
+ emit_insn (ctx , ldd , LOONGARCH_GPR_A0 , LOONGARCH_GPR_FP , - retval_off );
1664
1694
}
1665
1695
1666
1696
emit_insn (ctx , ldd , LOONGARCH_GPR_S1 , LOONGARCH_GPR_FP , - sreg_off );
0 commit comments