@@ -580,7 +580,8 @@ static int add_exception_handler(const struct bpf_insn *insn,
580580 unsigned long pc ;
581581 off_t offset ;
582582
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 ))
584585 return 0 ;
585586
586587 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,
14861487 return 1 ;
14871488 }
14881489
1489- /* LDX: dst = *(size *)(src + off) */
1490+ /* LDX: dst = *(unsigned size *)(src + off) */
14901491 case BPF_LDX | BPF_MEM | BPF_B :
14911492 case BPF_LDX | BPF_MEM | BPF_H :
14921493 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,
14951496 case BPF_LDX | BPF_PROBE_MEM | BPF_H :
14961497 case BPF_LDX | BPF_PROBE_MEM | BPF_W :
14971498 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 :
14981506 {
14991507 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 ;
15001512
15011513 switch (BPF_SIZE (code )) {
15021514 case BPF_B :
15031515 if (is_12b_int (off )) {
15041516 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 );
15061521 insn_len = ctx -> ninsns - insns_start ;
15071522 break ;
15081523 }
15091524
15101525 emit_imm (RV_REG_T1 , off , ctx );
15111526 emit_add (RV_REG_T1 , RV_REG_T1 , rs , ctx );
15121527 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 );
15141532 insn_len = ctx -> ninsns - insns_start ;
15151533 break ;
15161534 case BPF_H :
15171535 if (is_12b_int (off )) {
15181536 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 );
15201541 insn_len = ctx -> ninsns - insns_start ;
15211542 break ;
15221543 }
15231544
15241545 emit_imm (RV_REG_T1 , off , ctx );
15251546 emit_add (RV_REG_T1 , RV_REG_T1 , rs , ctx );
15261547 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 );
15281552 insn_len = ctx -> ninsns - insns_start ;
15291553 break ;
15301554 case BPF_W :
15311555 if (is_12b_int (off )) {
15321556 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 );
15341561 insn_len = ctx -> ninsns - insns_start ;
15351562 break ;
15361563 }
15371564
15381565 emit_imm (RV_REG_T1 , off , ctx );
15391566 emit_add (RV_REG_T1 , RV_REG_T1 , rs , ctx );
15401567 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 );
15421572 insn_len = ctx -> ninsns - insns_start ;
15431573 break ;
15441574 case BPF_DW :
0 commit comments