@@ -1448,6 +1448,28 @@ void arch_free_bpf_trampoline(void *image, unsigned int size)
1448
1448
bpf_prog_pack_free (image , size );
1449
1449
}
1450
1450
1451
+ /*
1452
+ * Sign-extend the register if necessary
1453
+ */
1454
+ static void sign_extend (struct jit_ctx * ctx , int r , u8 size )
1455
+ {
1456
+ switch (size ) {
1457
+ case 1 :
1458
+ emit_insn (ctx , extwb , r , r );
1459
+ break ;
1460
+ case 2 :
1461
+ emit_insn (ctx , extwh , r , r );
1462
+ break ;
1463
+ case 4 :
1464
+ emit_insn (ctx , addiw , r , r , 0 );
1465
+ break ;
1466
+ case 8 :
1467
+ break ;
1468
+ default :
1469
+ pr_warn ("bpf_jit: invalid size %d for sign_extend\n" , size );
1470
+ }
1471
+ }
1472
+
1451
1473
static int __arch_prepare_bpf_trampoline (struct jit_ctx * ctx , struct bpf_tramp_image * im ,
1452
1474
const struct btf_func_model * m , struct bpf_tramp_links * tlinks ,
1453
1475
void * func_addr , u32 flags )
@@ -1654,6 +1676,10 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
1654
1676
if (save_ret ) {
1655
1677
emit_insn (ctx , ldd , LOONGARCH_GPR_A0 , LOONGARCH_GPR_FP , - retval_off );
1656
1678
emit_insn (ctx , ldd , regmap [BPF_REG_0 ], LOONGARCH_GPR_FP , - (retval_off - 8 ));
1679
+ if (is_struct_ops ) {
1680
+ move_reg (ctx , LOONGARCH_GPR_A0 , regmap [BPF_REG_0 ]);
1681
+ sign_extend (ctx , LOONGARCH_GPR_A0 , m -> ret_size );
1682
+ }
1657
1683
}
1658
1684
1659
1685
emit_insn (ctx , ldd , LOONGARCH_GPR_S1 , LOONGARCH_GPR_FP , - sreg_off );
0 commit comments