@@ -411,7 +411,11 @@ static int add_exception_handler(const struct bpf_insn *insn,
411411 off_t offset ;
412412 struct exception_table_entry * ex ;
413413
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 )
415419 return 0 ;
416420
417421 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
450454{
451455 u8 tm = -1 ;
452456 u64 func_addr ;
453- bool func_addr_fixed ;
457+ bool func_addr_fixed , sign_extend ;
454458 int i = insn - ctx -> prog -> insnsi ;
455459 int ret , jmp_offset ;
456460 const u8 code = insn -> code ;
@@ -879,31 +883,56 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
879883 case BPF_LDX | BPF_PROBE_MEM | BPF_W :
880884 case BPF_LDX | BPF_PROBE_MEM | BPF_H :
881885 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 ;
882895 switch (BPF_SIZE (code )) {
883896 case BPF_B :
884897 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 );
886902 } else {
887903 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 );
889908 }
890909 break ;
891910 case BPF_H :
892911 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 );
894916 } else {
895917 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 );
897922 }
898923 break ;
899924 case BPF_W :
900925 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 );
904930 } else {
905931 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 );
907936 }
908937 break ;
909938 case BPF_DW :
0 commit comments