@@ -1451,6 +1451,32 @@ void arch_free_bpf_trampoline(void *image, unsigned int size)
14511451	bpf_prog_pack_free (image , size );
14521452}
14531453
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+ 
14541480static  int  __arch_prepare_bpf_trampoline (struct  jit_ctx  * ctx , struct  bpf_tramp_image  * im ,
14551481					 const  struct  btf_func_model  * m , struct  bpf_tramp_links  * tlinks ,
14561482					 void  * func_addr , u32  flags )
@@ -1659,8 +1685,12 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
16591685		restore_args (ctx , m -> nr_args , args_off );
16601686
16611687	if  (save_ret ) {
1662- 		emit_insn (ctx , ldd , LOONGARCH_GPR_A0 , LOONGARCH_GPR_FP , - retval_off );
16631688		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 );
16641694	}
16651695
16661696	emit_insn (ctx , ldd , LOONGARCH_GPR_S1 , LOONGARCH_GPR_FP , - sreg_off );
0 commit comments