@@ -1361,7 +1361,8 @@ static void restore_args(struct jit_ctx *ctx, int nargs, int args_off)
1361
1361
}
1362
1362
1363
1363
static int invoke_bpf_prog (struct jit_ctx * ctx , struct bpf_tramp_link * l ,
1364
- int args_off , int retval_off , int run_ctx_off , bool save_ret )
1364
+ const struct btf_func_model * m , int args_off ,
1365
+ int retval_off , int run_ctx_off , bool save_ret )
1365
1366
{
1366
1367
int ret ;
1367
1368
u32 * branch ;
@@ -1425,13 +1426,14 @@ static int invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l,
1425
1426
}
1426
1427
1427
1428
static void invoke_bpf_mod_ret (struct jit_ctx * ctx , struct bpf_tramp_links * tl ,
1428
- int args_off , int retval_off , int run_ctx_off , u32 * * branches )
1429
+ const struct btf_func_model * m , int args_off ,
1430
+ int retval_off , int run_ctx_off , u32 * * branches )
1429
1431
{
1430
1432
int i ;
1431
1433
1432
1434
emit_insn (ctx , std , LOONGARCH_GPR_ZERO , LOONGARCH_GPR_FP , - retval_off );
1433
1435
for (i = 0 ; i < tl -> nr_links ; i ++ ) {
1434
- invoke_bpf_prog (ctx , tl -> links [i ], args_off , retval_off , run_ctx_off , true);
1436
+ invoke_bpf_prog (ctx , tl -> links [i ], m , args_off , retval_off , run_ctx_off , true);
1435
1437
emit_insn (ctx , ldd , LOONGARCH_GPR_T1 , LOONGARCH_GPR_FP , - retval_off );
1436
1438
branches [i ] = (u32 * )ctx -> image + ctx -> idx ;
1437
1439
emit_insn (ctx , nop );
@@ -1448,6 +1450,30 @@ void arch_free_bpf_trampoline(void *image, unsigned int size)
1448
1450
bpf_prog_pack_free (image , size );
1449
1451
}
1450
1452
1453
+ /*
1454
+ * Sign-extend the register if necessary
1455
+ */
1456
+ static int sign_extend (struct jit_ctx * ctx , int r , u8 size )
1457
+ {
1458
+ switch (size ) {
1459
+ case 1 :
1460
+ emit_insn (ctx , sllid , r , r , 56 );
1461
+ emit_insn (ctx , sraid , r , r , 56 );
1462
+ return 0 ;
1463
+ case 2 :
1464
+ emit_insn (ctx , sllid , r , r , 48 );
1465
+ emit_insn (ctx , sraid , r , r , 48 );
1466
+ return 0 ;
1467
+ case 4 :
1468
+ emit_insn (ctx , addiw , r , r , 0 );
1469
+ return 0 ;
1470
+ case 8 :
1471
+ return 0 ;
1472
+ default :
1473
+ return -1 ;
1474
+ }
1475
+ }
1476
+
1451
1477
static int __arch_prepare_bpf_trampoline (struct jit_ctx * ctx , struct bpf_tramp_image * im ,
1452
1478
const struct btf_func_model * m , struct bpf_tramp_links * tlinks ,
1453
1479
void * func_addr , u32 flags )
@@ -1602,8 +1628,8 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
1602
1628
}
1603
1629
1604
1630
for (i = 0 ; i < fentry -> nr_links ; i ++ ) {
1605
- ret = invoke_bpf_prog (ctx , fentry -> links [i ], args_off , retval_off ,
1606
- run_ctx_off , flags & BPF_TRAMP_F_RET_FENTRY_RET );
1631
+ ret = invoke_bpf_prog (ctx , fentry -> links [i ], m , args_off , retval_off ,
1632
+ run_ctx_off , flags & BPF_TRAMP_F_RET_FENTRY_RET );
1607
1633
if (ret )
1608
1634
return ret ;
1609
1635
}
@@ -1612,7 +1638,7 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
1612
1638
if (!branches )
1613
1639
return - ENOMEM ;
1614
1640
1615
- invoke_bpf_mod_ret (ctx , fmod_ret , args_off , retval_off , run_ctx_off , branches );
1641
+ invoke_bpf_mod_ret (ctx , fmod_ret , m , args_off , retval_off , run_ctx_off , branches );
1616
1642
}
1617
1643
1618
1644
if (flags & BPF_TRAMP_F_CALL_ORIG ) {
@@ -1638,7 +1664,8 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
1638
1664
}
1639
1665
1640
1666
for (i = 0 ; i < fexit -> nr_links ; i ++ ) {
1641
- ret = invoke_bpf_prog (ctx , fexit -> links [i ], args_off , retval_off , run_ctx_off , false);
1667
+ ret = invoke_bpf_prog (ctx , fexit -> links [i ], m , args_off ,
1668
+ retval_off , run_ctx_off , false);
1642
1669
if (ret )
1643
1670
goto out ;
1644
1671
}
@@ -1657,6 +1684,12 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
1657
1684
if (save_ret ) {
1658
1685
emit_insn (ctx , ldd , LOONGARCH_GPR_A0 , LOONGARCH_GPR_FP , - retval_off );
1659
1686
emit_insn (ctx , ldd , regmap [BPF_REG_0 ], LOONGARCH_GPR_FP , - (retval_off - 8 ));
1687
+ if (is_struct_ops ) {
1688
+ move_reg (ctx , LOONGARCH_GPR_A0 , regmap [BPF_REG_0 ]);
1689
+ ret = sign_extend (ctx , LOONGARCH_GPR_A0 , m -> ret_size );
1690
+ if (ret )
1691
+ goto out ;
1692
+ }
1660
1693
}
1661
1694
1662
1695
emit_insn (ctx , ldd , LOONGARCH_GPR_S1 , LOONGARCH_GPR_FP , - sreg_off );
0 commit comments