@@ -1448,6 +1448,28 @@ void arch_free_bpf_trampoline(void *image, unsigned int size)
14481448	bpf_prog_pack_free (image , size );
14491449}
14501450
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+ 
14511473static  int  __arch_prepare_bpf_trampoline (struct  jit_ctx  * ctx , struct  bpf_tramp_image  * im ,
14521474					 const  struct  btf_func_model  * m , struct  bpf_tramp_links  * tlinks ,
14531475					 void  * func_addr , u32  flags )
@@ -1654,6 +1676,10 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
16541676	if  (save_ret ) {
16551677		emit_insn (ctx , ldd , LOONGARCH_GPR_A0 , LOONGARCH_GPR_FP , - retval_off );
16561678		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+ 		}
16571683	}
16581684
16591685	emit_insn (ctx , ldd , LOONGARCH_GPR_S1 , LOONGARCH_GPR_FP , - sreg_off );
0 commit comments