@@ -411,7 +411,11 @@ static int add_exception_handler(const struct bpf_insn *insn,
411
411
off_t offset ;
412
412
struct exception_table_entry * ex ;
413
413
414
- if (!ctx -> image || !ctx -> prog -> aux -> extable || BPF_MODE (insn -> code ) != BPF_PROBE_MEM )
414
+ if (!ctx -> image || !ctx -> prog -> aux -> extable )
415
+ return 0 ;
416
+
417
+ if (BPF_MODE (insn -> code ) != BPF_PROBE_MEM &&
418
+ BPF_MODE (insn -> code ) != BPF_PROBE_MEMSX )
415
419
return 0 ;
416
420
417
421
if (WARN_ON_ONCE (ctx -> num_exentries >= ctx -> prog -> aux -> num_exentries ))
@@ -450,7 +454,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
450
454
{
451
455
u8 tm = -1 ;
452
456
u64 func_addr ;
453
- bool func_addr_fixed ;
457
+ bool func_addr_fixed , sign_extend ;
454
458
int i = insn - ctx -> prog -> insnsi ;
455
459
int ret , jmp_offset ;
456
460
const u8 code = insn -> code ;
@@ -879,31 +883,56 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
879
883
case BPF_LDX | BPF_PROBE_MEM | BPF_W :
880
884
case BPF_LDX | BPF_PROBE_MEM | BPF_H :
881
885
case BPF_LDX | BPF_PROBE_MEM | BPF_B :
886
+ /* dst_reg = (s64)*(signed size *)(src_reg + off) */
887
+ case BPF_LDX | BPF_MEMSX | BPF_B :
888
+ case BPF_LDX | BPF_MEMSX | BPF_H :
889
+ case BPF_LDX | BPF_MEMSX | BPF_W :
890
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_B :
891
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_H :
892
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_W :
893
+ sign_extend = BPF_MODE (insn -> code ) == BPF_MEMSX ||
894
+ BPF_MODE (insn -> code ) == BPF_PROBE_MEMSX ;
882
895
switch (BPF_SIZE (code )) {
883
896
case BPF_B :
884
897
if (is_signed_imm12 (off )) {
885
- emit_insn (ctx , ldbu , dst , src , off );
898
+ if (sign_extend )
899
+ emit_insn (ctx , ldb , dst , src , off );
900
+ else
901
+ emit_insn (ctx , ldbu , dst , src , off );
886
902
} else {
887
903
move_imm (ctx , t1 , off , is32 );
888
- emit_insn (ctx , ldxbu , dst , src , t1 );
904
+ if (sign_extend )
905
+ emit_insn (ctx , ldxb , dst , src , t1 );
906
+ else
907
+ emit_insn (ctx , ldxbu , dst , src , t1 );
889
908
}
890
909
break ;
891
910
case BPF_H :
892
911
if (is_signed_imm12 (off )) {
893
- emit_insn (ctx , ldhu , dst , src , off );
912
+ if (sign_extend )
913
+ emit_insn (ctx , ldh , dst , src , off );
914
+ else
915
+ emit_insn (ctx , ldhu , dst , src , off );
894
916
} else {
895
917
move_imm (ctx , t1 , off , is32 );
896
- emit_insn (ctx , ldxhu , dst , src , t1 );
918
+ if (sign_extend )
919
+ emit_insn (ctx , ldxh , dst , src , t1 );
920
+ else
921
+ emit_insn (ctx , ldxhu , dst , src , t1 );
897
922
}
898
923
break ;
899
924
case BPF_W :
900
925
if (is_signed_imm12 (off )) {
901
- emit_insn (ctx , ldwu , dst , src , off );
902
- } else if (is_signed_imm14 (off )) {
903
- emit_insn (ctx , ldptrw , dst , src , off );
926
+ if (sign_extend )
927
+ emit_insn (ctx , ldw , dst , src , off );
928
+ else
929
+ emit_insn (ctx , ldwu , dst , src , off );
904
930
} else {
905
931
move_imm (ctx , t1 , off , is32 );
906
- emit_insn (ctx , ldxwu , dst , src , t1 );
932
+ if (sign_extend )
933
+ emit_insn (ctx , ldxw , dst , src , t1 );
934
+ else
935
+ emit_insn (ctx , ldxwu , dst , src , t1 );
907
936
}
908
937
break ;
909
938
case BPF_DW :
0 commit comments