@@ -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 ))
@@ -1046,7 +1047,19 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
1046
1047
emit_zext_32 (rd , ctx );
1047
1048
break ;
1048
1049
}
1049
- emit_mv (rd , rs , ctx );
1050
+ switch (insn -> off ) {
1051
+ case 0 :
1052
+ emit_mv (rd , rs , ctx );
1053
+ break ;
1054
+ case 8 :
1055
+ case 16 :
1056
+ emit_slli (RV_REG_T1 , rs , 64 - insn -> off , ctx );
1057
+ emit_srai (rd , RV_REG_T1 , 64 - insn -> off , ctx );
1058
+ break ;
1059
+ case 32 :
1060
+ emit_addiw (rd , rs , 0 , ctx );
1061
+ break ;
1062
+ }
1050
1063
if (!is64 && !aux -> verifier_zext )
1051
1064
emit_zext_32 (rd , ctx );
1052
1065
break ;
@@ -1094,13 +1107,19 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
1094
1107
break ;
1095
1108
case BPF_ALU | BPF_DIV | BPF_X :
1096
1109
case BPF_ALU64 | BPF_DIV | BPF_X :
1097
- emit (is64 ? rv_divu (rd , rd , rs ) : rv_divuw (rd , rd , rs ), ctx );
1110
+ if (off )
1111
+ emit (is64 ? rv_div (rd , rd , rs ) : rv_divw (rd , rd , rs ), ctx );
1112
+ else
1113
+ emit (is64 ? rv_divu (rd , rd , rs ) : rv_divuw (rd , rd , rs ), ctx );
1098
1114
if (!is64 && !aux -> verifier_zext )
1099
1115
emit_zext_32 (rd , ctx );
1100
1116
break ;
1101
1117
case BPF_ALU | BPF_MOD | BPF_X :
1102
1118
case BPF_ALU64 | BPF_MOD | BPF_X :
1103
- emit (is64 ? rv_remu (rd , rd , rs ) : rv_remuw (rd , rd , rs ), ctx );
1119
+ if (off )
1120
+ emit (is64 ? rv_rem (rd , rd , rs ) : rv_remw (rd , rd , rs ), ctx );
1121
+ else
1122
+ emit (is64 ? rv_remu (rd , rd , rs ) : rv_remuw (rd , rd , rs ), ctx );
1104
1123
if (!is64 && !aux -> verifier_zext )
1105
1124
emit_zext_32 (rd , ctx );
1106
1125
break ;
@@ -1149,6 +1168,7 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
1149
1168
break ;
1150
1169
1151
1170
case BPF_ALU | BPF_END | BPF_FROM_BE :
1171
+ case BPF_ALU64 | BPF_END | BPF_FROM_LE :
1152
1172
emit_li (RV_REG_T2 , 0 , ctx );
1153
1173
1154
1174
emit_andi (RV_REG_T1 , rd , 0xff , ctx );
@@ -1271,16 +1291,24 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
1271
1291
case BPF_ALU | BPF_DIV | BPF_K :
1272
1292
case BPF_ALU64 | BPF_DIV | BPF_K :
1273
1293
emit_imm (RV_REG_T1 , imm , ctx );
1274
- emit (is64 ? rv_divu (rd , rd , RV_REG_T1 ) :
1275
- rv_divuw (rd , rd , RV_REG_T1 ), ctx );
1294
+ if (off )
1295
+ emit (is64 ? rv_div (rd , rd , RV_REG_T1 ) :
1296
+ rv_divw (rd , rd , RV_REG_T1 ), ctx );
1297
+ else
1298
+ emit (is64 ? rv_divu (rd , rd , RV_REG_T1 ) :
1299
+ rv_divuw (rd , rd , RV_REG_T1 ), ctx );
1276
1300
if (!is64 && !aux -> verifier_zext )
1277
1301
emit_zext_32 (rd , ctx );
1278
1302
break ;
1279
1303
case BPF_ALU | BPF_MOD | BPF_K :
1280
1304
case BPF_ALU64 | BPF_MOD | BPF_K :
1281
1305
emit_imm (RV_REG_T1 , imm , ctx );
1282
- emit (is64 ? rv_remu (rd , rd , RV_REG_T1 ) :
1283
- rv_remuw (rd , rd , RV_REG_T1 ), ctx );
1306
+ if (off )
1307
+ emit (is64 ? rv_rem (rd , rd , RV_REG_T1 ) :
1308
+ rv_remw (rd , rd , RV_REG_T1 ), ctx );
1309
+ else
1310
+ emit (is64 ? rv_remu (rd , rd , RV_REG_T1 ) :
1311
+ rv_remuw (rd , rd , RV_REG_T1 ), ctx );
1284
1312
if (!is64 && !aux -> verifier_zext )
1285
1313
emit_zext_32 (rd , ctx );
1286
1314
break ;
@@ -1314,7 +1342,11 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
1314
1342
1315
1343
/* JUMP off */
1316
1344
case BPF_JMP | BPF_JA :
1317
- rvoff = rv_offset (i , off , ctx );
1345
+ case BPF_JMP32 | BPF_JA :
1346
+ if (BPF_CLASS (code ) == BPF_JMP )
1347
+ rvoff = rv_offset (i , off , ctx );
1348
+ else
1349
+ rvoff = rv_offset (i , imm , ctx );
1318
1350
ret = emit_jump_and_link (RV_REG_ZERO , rvoff , true, ctx );
1319
1351
if (ret )
1320
1352
return ret ;
@@ -1486,7 +1518,7 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
1486
1518
return 1 ;
1487
1519
}
1488
1520
1489
- /* LDX: dst = *(size *)(src + off) */
1521
+ /* LDX: dst = *(unsigned size *)(src + off) */
1490
1522
case BPF_LDX | BPF_MEM | BPF_B :
1491
1523
case BPF_LDX | BPF_MEM | BPF_H :
1492
1524
case BPF_LDX | BPF_MEM | BPF_W :
@@ -1495,57 +1527,80 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
1495
1527
case BPF_LDX | BPF_PROBE_MEM | BPF_H :
1496
1528
case BPF_LDX | BPF_PROBE_MEM | BPF_W :
1497
1529
case BPF_LDX | BPF_PROBE_MEM | BPF_DW :
1530
+ /* LDSX: dst = *(signed size *)(src + off) */
1531
+ case BPF_LDX | BPF_MEMSX | BPF_B :
1532
+ case BPF_LDX | BPF_MEMSX | BPF_H :
1533
+ case BPF_LDX | BPF_MEMSX | BPF_W :
1534
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_B :
1535
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_H :
1536
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_W :
1498
1537
{
1499
1538
int insn_len , insns_start ;
1539
+ bool sign_ext ;
1540
+
1541
+ sign_ext = BPF_MODE (insn -> code ) == BPF_MEMSX ||
1542
+ BPF_MODE (insn -> code ) == BPF_PROBE_MEMSX ;
1500
1543
1501
1544
switch (BPF_SIZE (code )) {
1502
1545
case BPF_B :
1503
1546
if (is_12b_int (off )) {
1504
1547
insns_start = ctx -> ninsns ;
1505
- emit (rv_lbu (rd , off , rs ), ctx );
1548
+ if (sign_ext )
1549
+ emit (rv_lb (rd , off , rs ), ctx );
1550
+ else
1551
+ emit (rv_lbu (rd , off , rs ), ctx );
1506
1552
insn_len = ctx -> ninsns - insns_start ;
1507
1553
break ;
1508
1554
}
1509
1555
1510
1556
emit_imm (RV_REG_T1 , off , ctx );
1511
1557
emit_add (RV_REG_T1 , RV_REG_T1 , rs , ctx );
1512
1558
insns_start = ctx -> ninsns ;
1513
- emit (rv_lbu (rd , 0 , RV_REG_T1 ), ctx );
1559
+ if (sign_ext )
1560
+ emit (rv_lb (rd , 0 , RV_REG_T1 ), ctx );
1561
+ else
1562
+ emit (rv_lbu (rd , 0 , RV_REG_T1 ), ctx );
1514
1563
insn_len = ctx -> ninsns - insns_start ;
1515
- if (insn_is_zext (& insn [1 ]))
1516
- return 1 ;
1517
1564
break ;
1518
1565
case BPF_H :
1519
1566
if (is_12b_int (off )) {
1520
1567
insns_start = ctx -> ninsns ;
1521
- emit (rv_lhu (rd , off , rs ), ctx );
1568
+ if (sign_ext )
1569
+ emit (rv_lh (rd , off , rs ), ctx );
1570
+ else
1571
+ emit (rv_lhu (rd , off , rs ), ctx );
1522
1572
insn_len = ctx -> ninsns - insns_start ;
1523
1573
break ;
1524
1574
}
1525
1575
1526
1576
emit_imm (RV_REG_T1 , off , ctx );
1527
1577
emit_add (RV_REG_T1 , RV_REG_T1 , rs , ctx );
1528
1578
insns_start = ctx -> ninsns ;
1529
- emit (rv_lhu (rd , 0 , RV_REG_T1 ), ctx );
1579
+ if (sign_ext )
1580
+ emit (rv_lh (rd , 0 , RV_REG_T1 ), ctx );
1581
+ else
1582
+ emit (rv_lhu (rd , 0 , RV_REG_T1 ), ctx );
1530
1583
insn_len = ctx -> ninsns - insns_start ;
1531
- if (insn_is_zext (& insn [1 ]))
1532
- return 1 ;
1533
1584
break ;
1534
1585
case BPF_W :
1535
1586
if (is_12b_int (off )) {
1536
1587
insns_start = ctx -> ninsns ;
1537
- emit (rv_lwu (rd , off , rs ), ctx );
1588
+ if (sign_ext )
1589
+ emit (rv_lw (rd , off , rs ), ctx );
1590
+ else
1591
+ emit (rv_lwu (rd , off , rs ), ctx );
1538
1592
insn_len = ctx -> ninsns - insns_start ;
1539
1593
break ;
1540
1594
}
1541
1595
1542
1596
emit_imm (RV_REG_T1 , off , ctx );
1543
1597
emit_add (RV_REG_T1 , RV_REG_T1 , rs , ctx );
1544
1598
insns_start = ctx -> ninsns ;
1545
- emit (rv_lwu (rd , 0 , RV_REG_T1 ), ctx );
1599
+ if (sign_ext )
1600
+ emit (rv_lw (rd , 0 , RV_REG_T1 ), ctx );
1601
+ else
1602
+ emit (rv_lwu (rd , 0 , RV_REG_T1 ), ctx );
1546
1603
insn_len = ctx -> ninsns - insns_start ;
1547
- if (insn_is_zext (& insn [1 ]))
1548
- return 1 ;
1549
1604
break ;
1550
1605
case BPF_DW :
1551
1606
if (is_12b_int (off )) {
@@ -1566,6 +1621,9 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
1566
1621
ret = add_exception_handler (insn , ctx , rd , insn_len );
1567
1622
if (ret )
1568
1623
return ret ;
1624
+
1625
+ if (BPF_SIZE (code ) != BPF_DW && insn_is_zext (& insn [1 ]))
1626
+ return 1 ;
1569
1627
break ;
1570
1628
}
1571
1629
/* speculation barrier */
0 commit comments