@@ -559,52 +559,39 @@ static int emit_load_64(bool sign_ext, u8 rd, s32 off, u8 rs, struct rv_jit_cont
559559 return ctx -> ninsns - insns_start ;
560560}
561561
562- static void emit_store_8 (u8 rd , s32 off , u8 rs , struct rv_jit_context * ctx )
562+ static void emit_stx_insn (u8 rd , s16 off , u8 rs , u8 size , struct rv_jit_context * ctx )
563563{
564- if (is_12b_int (off )) {
564+ switch (size ) {
565+ case BPF_B :
565566 emit (rv_sb (rd , off , rs ), ctx );
566- return ;
567- }
568-
569- emit_imm (RV_REG_T1 , off , ctx );
570- emit_add (RV_REG_T1 , RV_REG_T1 , rd , ctx );
571- emit (rv_sb (RV_REG_T1 , 0 , rs ), ctx );
572- }
573-
574- static void emit_store_16 (u8 rd , s32 off , u8 rs , struct rv_jit_context * ctx )
575- {
576- if (is_12b_int (off )) {
567+ break ;
568+ case BPF_H :
577569 emit (rv_sh (rd , off , rs ), ctx );
578- return ;
579- }
580-
581- emit_imm (RV_REG_T1 , off , ctx );
582- emit_add (RV_REG_T1 , RV_REG_T1 , rd , ctx );
583- emit (rv_sh (RV_REG_T1 , 0 , rs ), ctx );
584- }
585-
586- static void emit_store_32 (u8 rd , s32 off , u8 rs , struct rv_jit_context * ctx )
587- {
588- if (is_12b_int (off )) {
570+ break ;
571+ case BPF_W :
589572 emit_sw (rd , off , rs , ctx );
590- return ;
573+ break ;
574+ case BPF_DW :
575+ emit_sd (rd , off , rs , ctx );
576+ break ;
591577 }
592-
593- emit_imm (RV_REG_T1 , off , ctx );
594- emit_add (RV_REG_T1 , RV_REG_T1 , rd , ctx );
595- emit_sw (RV_REG_T1 , 0 , rs , ctx );
596578}
597579
598- static void emit_store_64 (u8 rd , s32 off , u8 rs , struct rv_jit_context * ctx )
580+ static int emit_stx (u8 rd , s16 off , u8 rs , u8 size , struct rv_jit_context * ctx )
599581{
582+ int insns_start ;
583+
600584 if (is_12b_int (off )) {
601- emit_sd (rd , off , rs , ctx );
602- return ;
585+ insns_start = ctx -> ninsns ;
586+ emit_stx_insn (rd , off , rs , size , ctx );
587+ return ctx -> ninsns - insns_start ;
603588 }
604589
605590 emit_imm (RV_REG_T1 , off , ctx );
606591 emit_add (RV_REG_T1 , RV_REG_T1 , rd , ctx );
607- emit_sd (RV_REG_T1 , 0 , rs , ctx );
592+ insns_start = ctx -> ninsns ;
593+ emit_stx_insn (RV_REG_T1 , 0 , rs , size , ctx );
594+ return ctx -> ninsns - insns_start ;
608595}
609596
610597static int emit_atomic_ld_st (u8 rd , u8 rs , const struct bpf_insn * insn ,
@@ -642,20 +629,7 @@ static int emit_atomic_ld_st(u8 rd, u8 rs, const struct bpf_insn *insn,
642629 /* store_release(dst_reg + off16, src_reg) */
643630 case BPF_STORE_REL :
644631 emit_fence_rw_w (ctx );
645- switch (BPF_SIZE (code )) {
646- case BPF_B :
647- emit_store_8 (rd , off , rs , ctx );
648- break ;
649- case BPF_H :
650- emit_store_16 (rd , off , rs , ctx );
651- break ;
652- case BPF_W :
653- emit_store_32 (rd , off , rs , ctx );
654- break ;
655- case BPF_DW :
656- emit_store_64 (rd , off , rs , ctx );
657- break ;
658- }
632+ emit_stx (rd , off , rs , BPF_SIZE (code ), ctx );
659633 break ;
660634 default :
661635 pr_err_once ("bpf-jit: invalid atomic load/store opcode %02x\n" , imm );
@@ -2023,106 +1997,42 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
20231997
20241998 /* STX: *(size *)(dst + off) = src */
20251999 case BPF_STX | BPF_MEM | BPF_B :
2026- emit_store_8 (rd , off , rs , ctx );
2027- break ;
20282000 case BPF_STX | BPF_MEM | BPF_H :
2029- emit_store_16 (rd , off , rs , ctx );
2030- break ;
20312001 case BPF_STX | BPF_MEM | BPF_W :
2032- emit_store_32 (rd , off , rs , ctx );
2033- break ;
20342002 case BPF_STX | BPF_MEM | BPF_DW :
2035- emit_store_64 (rd , off , rs , ctx );
2036- break ;
2037- case BPF_STX | BPF_ATOMIC | BPF_B :
2038- case BPF_STX | BPF_ATOMIC | BPF_H :
2039- case BPF_STX | BPF_ATOMIC | BPF_W :
2040- case BPF_STX | BPF_ATOMIC | BPF_DW :
2041- if (bpf_atomic_is_load_store (insn ))
2042- ret = emit_atomic_ld_st (rd , rs , insn , ctx );
2043- else
2044- ret = emit_atomic_rmw (rd , rs , insn , ctx );
2045- if (ret )
2046- return ret ;
2047- break ;
2048-
2003+ /* STX | PROBE_MEM32: *(size *)(dst + RV_REG_ARENA + off) = src */
20492004 case BPF_STX | BPF_PROBE_MEM32 | BPF_B :
20502005 case BPF_STX | BPF_PROBE_MEM32 | BPF_H :
20512006 case BPF_STX | BPF_PROBE_MEM32 | BPF_W :
20522007 case BPF_STX | BPF_PROBE_MEM32 | BPF_DW :
20532008 {
2054- int insn_len , insns_start ;
2055-
2056- emit_add (RV_REG_T2 , rd , RV_REG_ARENA , ctx );
2057- rd = RV_REG_T2 ;
2058-
2059- switch (BPF_SIZE (code )) {
2060- case BPF_B :
2061- if (is_12b_int (off )) {
2062- insns_start = ctx -> ninsns ;
2063- emit (rv_sb (rd , off , rs ), ctx );
2064- insn_len = ctx -> ninsns - insns_start ;
2065- break ;
2066- }
2067-
2068- emit_imm (RV_REG_T1 , off , ctx );
2069- emit_add (RV_REG_T1 , RV_REG_T1 , rd , ctx );
2070- insns_start = ctx -> ninsns ;
2071- emit (rv_sb (RV_REG_T1 , 0 , rs ), ctx );
2072- insn_len = ctx -> ninsns - insns_start ;
2073- break ;
2074- case BPF_H :
2075- if (is_12b_int (off )) {
2076- insns_start = ctx -> ninsns ;
2077- emit (rv_sh (rd , off , rs ), ctx );
2078- insn_len = ctx -> ninsns - insns_start ;
2079- break ;
2080- }
2081-
2082- emit_imm (RV_REG_T1 , off , ctx );
2083- emit_add (RV_REG_T1 , RV_REG_T1 , rd , ctx );
2084- insns_start = ctx -> ninsns ;
2085- emit (rv_sh (RV_REG_T1 , 0 , rs ), ctx );
2086- insn_len = ctx -> ninsns - insns_start ;
2087- break ;
2088- case BPF_W :
2089- if (is_12b_int (off )) {
2090- insns_start = ctx -> ninsns ;
2091- emit_sw (rd , off , rs , ctx );
2092- insn_len = ctx -> ninsns - insns_start ;
2093- break ;
2094- }
2095-
2096- emit_imm (RV_REG_T1 , off , ctx );
2097- emit_add (RV_REG_T1 , RV_REG_T1 , rd , ctx );
2098- insns_start = ctx -> ninsns ;
2099- emit_sw (RV_REG_T1 , 0 , rs , ctx );
2100- insn_len = ctx -> ninsns - insns_start ;
2101- break ;
2102- case BPF_DW :
2103- if (is_12b_int (off )) {
2104- insns_start = ctx -> ninsns ;
2105- emit_sd (rd , off , rs , ctx );
2106- insn_len = ctx -> ninsns - insns_start ;
2107- break ;
2108- }
2009+ int insn_len ;
21092010
2110- emit_imm (RV_REG_T1 , off , ctx );
2111- emit_add (RV_REG_T1 , RV_REG_T1 , rd , ctx );
2112- insns_start = ctx -> ninsns ;
2113- emit_sd (RV_REG_T1 , 0 , rs , ctx );
2114- insn_len = ctx -> ninsns - insns_start ;
2115- break ;
2011+ if (BPF_MODE (insn -> code ) == BPF_PROBE_MEM32 ) {
2012+ emit_add (RV_REG_T2 , rd , RV_REG_ARENA , ctx );
2013+ rd = RV_REG_T2 ;
21162014 }
21172015
2118- ret = add_exception_handler (insn , ctx , REG_DONT_CLEAR_MARKER ,
2119- insn_len );
2016+ insn_len = emit_stx (rd , off , rs , BPF_SIZE (code ), ctx );
2017+
2018+ ret = add_exception_handler (insn , ctx , REG_DONT_CLEAR_MARKER , insn_len );
21202019 if (ret )
21212020 return ret ;
2122-
21232021 break ;
21242022 }
21252023
2024+ case BPF_STX | BPF_ATOMIC | BPF_B :
2025+ case BPF_STX | BPF_ATOMIC | BPF_H :
2026+ case BPF_STX | BPF_ATOMIC | BPF_W :
2027+ case BPF_STX | BPF_ATOMIC | BPF_DW :
2028+ if (bpf_atomic_is_load_store (insn ))
2029+ ret = emit_atomic_ld_st (rd , rs , insn , ctx );
2030+ else
2031+ ret = emit_atomic_rmw (rd , rs , insn , ctx );
2032+ if (ret )
2033+ return ret ;
2034+ break ;
2035+
21262036 default :
21272037 pr_err ("bpf-jit: unknown opcode %02x\n" , code );
21282038 return - EINVAL ;
0 commit comments