@@ -580,7 +580,8 @@ static int add_exception_handler(const struct bpf_insn *insn,
580
580
unsigned long pc ;
581
581
off_t offset ;
582
582
583
- if (!ctx -> insns || !ctx -> prog -> aux -> extable || BPF_MODE (insn -> code ) != BPF_PROBE_MEM )
583
+ if (!ctx -> insns || !ctx -> prog -> aux -> extable ||
584
+ (BPF_MODE (insn -> code ) != BPF_PROBE_MEM && BPF_MODE (insn -> code ) != BPF_PROBE_MEMSX ))
584
585
return 0 ;
585
586
586
587
if (WARN_ON_ONCE (ctx -> nexentries >= ctx -> prog -> aux -> num_exentries ))
@@ -1486,7 +1487,7 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
1486
1487
return 1 ;
1487
1488
}
1488
1489
1489
- /* LDX: dst = *(size *)(src + off) */
1490
+ /* LDX: dst = *(unsigned size *)(src + off) */
1490
1491
case BPF_LDX | BPF_MEM | BPF_B :
1491
1492
case BPF_LDX | BPF_MEM | BPF_H :
1492
1493
case BPF_LDX | BPF_MEM | BPF_W :
@@ -1495,50 +1496,79 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
1495
1496
case BPF_LDX | BPF_PROBE_MEM | BPF_H :
1496
1497
case BPF_LDX | BPF_PROBE_MEM | BPF_W :
1497
1498
case BPF_LDX | BPF_PROBE_MEM | BPF_DW :
1499
+ /* LDSX: dst = *(signed size *)(src + off) */
1500
+ case BPF_LDX | BPF_MEMSX | BPF_B :
1501
+ case BPF_LDX | BPF_MEMSX | BPF_H :
1502
+ case BPF_LDX | BPF_MEMSX | BPF_W :
1503
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_B :
1504
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_H :
1505
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_W :
1498
1506
{
1499
1507
int insn_len , insns_start ;
1508
+ bool sign_ext ;
1509
+
1510
+ sign_ext = BPF_MODE (insn -> code ) == BPF_MEMSX ||
1511
+ BPF_MODE (insn -> code ) == BPF_PROBE_MEMSX ;
1500
1512
1501
1513
switch (BPF_SIZE (code )) {
1502
1514
case BPF_B :
1503
1515
if (is_12b_int (off )) {
1504
1516
insns_start = ctx -> ninsns ;
1505
- emit (rv_lbu (rd , off , rs ), ctx );
1517
+ if (sign_ext )
1518
+ emit (rv_lb (rd , off , rs ), ctx );
1519
+ else
1520
+ emit (rv_lbu (rd , off , rs ), ctx );
1506
1521
insn_len = ctx -> ninsns - insns_start ;
1507
1522
break ;
1508
1523
}
1509
1524
1510
1525
emit_imm (RV_REG_T1 , off , ctx );
1511
1526
emit_add (RV_REG_T1 , RV_REG_T1 , rs , ctx );
1512
1527
insns_start = ctx -> ninsns ;
1513
- emit (rv_lbu (rd , 0 , RV_REG_T1 ), ctx );
1528
+ if (sign_ext )
1529
+ emit (rv_lb (rd , 0 , RV_REG_T1 ), ctx );
1530
+ else
1531
+ emit (rv_lbu (rd , 0 , RV_REG_T1 ), ctx );
1514
1532
insn_len = ctx -> ninsns - insns_start ;
1515
1533
break ;
1516
1534
case BPF_H :
1517
1535
if (is_12b_int (off )) {
1518
1536
insns_start = ctx -> ninsns ;
1519
- emit (rv_lhu (rd , off , rs ), ctx );
1537
+ if (sign_ext )
1538
+ emit (rv_lh (rd , off , rs ), ctx );
1539
+ else
1540
+ emit (rv_lhu (rd , off , rs ), ctx );
1520
1541
insn_len = ctx -> ninsns - insns_start ;
1521
1542
break ;
1522
1543
}
1523
1544
1524
1545
emit_imm (RV_REG_T1 , off , ctx );
1525
1546
emit_add (RV_REG_T1 , RV_REG_T1 , rs , ctx );
1526
1547
insns_start = ctx -> ninsns ;
1527
- emit (rv_lhu (rd , 0 , RV_REG_T1 ), ctx );
1548
+ if (sign_ext )
1549
+ emit (rv_lh (rd , 0 , RV_REG_T1 ), ctx );
1550
+ else
1551
+ emit (rv_lhu (rd , 0 , RV_REG_T1 ), ctx );
1528
1552
insn_len = ctx -> ninsns - insns_start ;
1529
1553
break ;
1530
1554
case BPF_W :
1531
1555
if (is_12b_int (off )) {
1532
1556
insns_start = ctx -> ninsns ;
1533
- emit (rv_lwu (rd , off , rs ), ctx );
1557
+ if (sign_ext )
1558
+ emit (rv_lw (rd , off , rs ), ctx );
1559
+ else
1560
+ emit (rv_lwu (rd , off , rs ), ctx );
1534
1561
insn_len = ctx -> ninsns - insns_start ;
1535
1562
break ;
1536
1563
}
1537
1564
1538
1565
emit_imm (RV_REG_T1 , off , ctx );
1539
1566
emit_add (RV_REG_T1 , RV_REG_T1 , rs , ctx );
1540
1567
insns_start = ctx -> ninsns ;
1541
- emit (rv_lwu (rd , 0 , RV_REG_T1 ), ctx );
1568
+ if (sign_ext )
1569
+ emit (rv_lw (rd , 0 , RV_REG_T1 ), ctx );
1570
+ else
1571
+ emit (rv_lwu (rd , 0 , RV_REG_T1 ), ctx );
1542
1572
insn_len = ctx -> ninsns - insns_start ;
1543
1573
break ;
1544
1574
case BPF_DW :
0 commit comments