@@ -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,28 @@ 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 , extwb , r , r );
1461
+ return 0 ;
1462
+ case 2 :
1463
+ emit_insn (ctx , extwh , r , r );
1464
+ return 0 ;
1465
+ case 4 :
1466
+ emit_insn (ctx , addiw , r , r , 0 );
1467
+ return 0 ;
1468
+ case 8 :
1469
+ return 0 ;
1470
+ default :
1471
+ return -1 ;
1472
+ }
1473
+ }
1474
+
1451
1475
static int __arch_prepare_bpf_trampoline (struct jit_ctx * ctx , struct bpf_tramp_image * im ,
1452
1476
const struct btf_func_model * m , struct bpf_tramp_links * tlinks ,
1453
1477
void * func_addr , u32 flags )
@@ -1599,8 +1623,8 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
1599
1623
}
1600
1624
1601
1625
for (i = 0 ; i < fentry -> nr_links ; i ++ ) {
1602
- ret = invoke_bpf_prog (ctx , fentry -> links [i ], args_off , retval_off ,
1603
- run_ctx_off , flags & BPF_TRAMP_F_RET_FENTRY_RET );
1626
+ ret = invoke_bpf_prog (ctx , fentry -> links [i ], m , args_off , retval_off ,
1627
+ run_ctx_off , flags & BPF_TRAMP_F_RET_FENTRY_RET );
1604
1628
if (ret )
1605
1629
return ret ;
1606
1630
}
@@ -1609,7 +1633,7 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
1609
1633
if (!branches )
1610
1634
return - ENOMEM ;
1611
1635
1612
- invoke_bpf_mod_ret (ctx , fmod_ret , args_off , retval_off , run_ctx_off , branches );
1636
+ invoke_bpf_mod_ret (ctx , fmod_ret , m , args_off , retval_off , run_ctx_off , branches );
1613
1637
}
1614
1638
1615
1639
if (flags & BPF_TRAMP_F_CALL_ORIG ) {
@@ -1635,7 +1659,8 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
1635
1659
}
1636
1660
1637
1661
for (i = 0 ; i < fexit -> nr_links ; i ++ ) {
1638
- ret = invoke_bpf_prog (ctx , fexit -> links [i ], args_off , retval_off , run_ctx_off , false);
1662
+ ret = invoke_bpf_prog (ctx , fexit -> links [i ], m , args_off ,
1663
+ retval_off , run_ctx_off , false);
1639
1664
if (ret )
1640
1665
goto out ;
1641
1666
}
@@ -1654,6 +1679,12 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
1654
1679
if (save_ret ) {
1655
1680
emit_insn (ctx , ldd , LOONGARCH_GPR_A0 , LOONGARCH_GPR_FP , - retval_off );
1656
1681
emit_insn (ctx , ldd , regmap [BPF_REG_0 ], LOONGARCH_GPR_FP , - (retval_off - 8 ));
1682
+ if (is_struct_ops ) {
1683
+ move_reg (ctx , LOONGARCH_GPR_A0 , regmap [BPF_REG_0 ]);
1684
+ ret = sign_extend (ctx , LOONGARCH_GPR_A0 , m -> ret_size );
1685
+ if (ret )
1686
+ goto out ;
1687
+ }
1657
1688
}
1658
1689
1659
1690
emit_insn (ctx , ldd , LOONGARCH_GPR_S1 , LOONGARCH_GPR_FP , - sreg_off );
0 commit comments