@@ -954,6 +954,33 @@ static int invoke_bpf_prog(struct bpf_tramp_link *l, int args_off, int retval_of
954
954
return ret ;
955
955
}
956
956
957
+ /*
958
+ * Sign-extend the register if necessary
959
+ */
960
+ static int sign_extend (struct rv_jit_context * ctx , int r , u8 size )
961
+ {
962
+ switch (size ) {
963
+ case 1 :
964
+ emit_slli (r , r , 56 , ctx );
965
+ emit_srai (r , r , 56 , ctx );
966
+ break ;
967
+ case 2 :
968
+ emit_slli (r , r , 48 , ctx );
969
+ emit_srai (r , r , 48 , ctx );
970
+ break ;
971
+ case 4 :
972
+ emit_addiw (r , r , 0 , ctx );
973
+ break ;
974
+ case 8 :
975
+ break ;
976
+ default :
977
+ pr_err ("bpf-jit: invalid size %d for sign_extend\n" , size );
978
+ return - EINVAL ;
979
+ }
980
+
981
+ return 0 ;
982
+ }
983
+
957
984
static int __arch_prepare_bpf_trampoline (struct bpf_tramp_image * im ,
958
985
const struct btf_func_model * m ,
959
986
struct bpf_tramp_links * tlinks ,
@@ -1177,6 +1204,12 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
1177
1204
if (save_ret ) {
1178
1205
emit_ld (RV_REG_A0 , - retval_off , RV_REG_FP , ctx );
1179
1206
emit_ld (regmap [BPF_REG_0 ], - (retval_off - 8 ), RV_REG_FP , ctx );
1207
+ if (is_struct_ops ) {
1208
+ emit_mv (RV_REG_A0 , regmap [BPF_REG_0 ], ctx );
1209
+ ret = sign_extend (ctx , RV_REG_A0 , m -> ret_size );
1210
+ if (ret )
1211
+ goto out ;
1212
+ }
1180
1213
}
1181
1214
1182
1215
emit_ld (RV_REG_S1 , - sreg_off , RV_REG_FP , ctx );
0 commit comments