Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

riscv, bpf: Extract emit_stx() helper

There's a lot of redundant code related to store from register
operations, let's extract emit_stx() to make code more compact.

Signed-off-by: Pu Lehui <pulehui@huawei.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Tested-by: Björn Töpel <bjorn@rivosinc.com>
Reviewed-by: Björn Töpel <bjorn@rivosinc.com>
Acked-by: Björn Töpel <bjorn@kernel.org>
Link: https://lore.kernel.org/bpf/20250719091730.2660197-2-pulehui@huaweicloud.com

authored by

Pu Lehui and committed by
Daniel Borkmann
02fc01ad 07866544

+41 -131
+41 -131
arch/riscv/net/bpf_jit_comp64.c
··· 559 559 return ctx->ninsns - insns_start; 560 560 } 561 561 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) 563 563 { 564 - if (is_12b_int(off)) { 564 + switch (size) { 565 + case BPF_B: 565 566 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: 577 569 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: 589 572 emit_sw(rd, off, rs, ctx); 590 - return; 573 + break; 574 + case BPF_DW: 575 + emit_sd(rd, off, rs, ctx); 576 + break; 591 577 } 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); 596 578 } 597 579 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) 599 581 { 582 + int insns_start; 583 + 600 584 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; 603 588 } 604 589 605 590 emit_imm(RV_REG_T1, off, ctx); 606 591 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; 608 595 } 609 596 610 597 static int emit_atomic_ld_st(u8 rd, u8 rs, const struct bpf_insn *insn, ··· 629 642 /* store_release(dst_reg + off16, src_reg) */ 630 643 case BPF_STORE_REL: 631 644 emit_fence_rw_w(ctx); 632 - switch (BPF_SIZE(code)) { 633 - case BPF_B: 634 - emit_store_8(rd, off, rs, ctx); 635 - break; 636 - case BPF_H: 637 - emit_store_16(rd, off, rs, ctx); 638 - break; 639 - case BPF_W: 640 - emit_store_32(rd, off, rs, ctx); 641 - break; 642 - case BPF_DW: 643 - emit_store_64(rd, off, rs, ctx); 644 - break; 645 - } 645 + emit_stx(rd, off, rs, BPF_SIZE(code), ctx); 646 646 break; 647 647 default: 648 648 pr_err_once("bpf-jit: invalid atomic load/store opcode %02x\n", imm); ··· 1997 2023 1998 2024 /* STX: *(size *)(dst + off) = src */ 1999 2025 case BPF_STX | BPF_MEM | BPF_B: 2000 - emit_store_8(rd, off, rs, ctx); 2001 - break; 2002 2026 case BPF_STX | BPF_MEM | BPF_H: 2003 - emit_store_16(rd, off, rs, ctx); 2004 - break; 2005 2027 case BPF_STX | BPF_MEM | BPF_W: 2006 - emit_store_32(rd, off, rs, ctx); 2007 - break; 2008 2028 case BPF_STX | BPF_MEM | BPF_DW: 2009 - emit_store_64(rd, off, rs, ctx); 2029 + /* STX | PROBE_MEM32: *(size *)(dst + RV_REG_ARENA + off) = src */ 2030 + case BPF_STX | BPF_PROBE_MEM32 | BPF_B: 2031 + case BPF_STX | BPF_PROBE_MEM32 | BPF_H: 2032 + case BPF_STX | BPF_PROBE_MEM32 | BPF_W: 2033 + case BPF_STX | BPF_PROBE_MEM32 | BPF_DW: 2034 + { 2035 + int insn_len; 2036 + 2037 + if (BPF_MODE(insn->code) == BPF_PROBE_MEM32) { 2038 + emit_add(RV_REG_T2, rd, RV_REG_ARENA, ctx); 2039 + rd = RV_REG_T2; 2040 + } 2041 + 2042 + insn_len = emit_stx(rd, off, rs, BPF_SIZE(code), ctx); 2043 + 2044 + ret = add_exception_handler(insn, ctx, REG_DONT_CLEAR_MARKER, insn_len); 2045 + if (ret) 2046 + return ret; 2010 2047 break; 2048 + } 2049 + 2011 2050 case BPF_STX | BPF_ATOMIC | BPF_B: 2012 2051 case BPF_STX | BPF_ATOMIC | BPF_H: 2013 2052 case BPF_STX | BPF_ATOMIC | BPF_W: ··· 2032 2045 if (ret) 2033 2046 return ret; 2034 2047 break; 2035 - 2036 - case BPF_STX | BPF_PROBE_MEM32 | BPF_B: 2037 - case BPF_STX | BPF_PROBE_MEM32 | BPF_H: 2038 - case BPF_STX | BPF_PROBE_MEM32 | BPF_W: 2039 - case BPF_STX | BPF_PROBE_MEM32 | BPF_DW: 2040 - { 2041 - int insn_len, insns_start; 2042 - 2043 - emit_add(RV_REG_T2, rd, RV_REG_ARENA, ctx); 2044 - rd = RV_REG_T2; 2045 - 2046 - switch (BPF_SIZE(code)) { 2047 - case BPF_B: 2048 - if (is_12b_int(off)) { 2049 - insns_start = ctx->ninsns; 2050 - emit(rv_sb(rd, off, rs), ctx); 2051 - insn_len = ctx->ninsns - insns_start; 2052 - break; 2053 - } 2054 - 2055 - emit_imm(RV_REG_T1, off, ctx); 2056 - emit_add(RV_REG_T1, RV_REG_T1, rd, ctx); 2057 - insns_start = ctx->ninsns; 2058 - emit(rv_sb(RV_REG_T1, 0, rs), ctx); 2059 - insn_len = ctx->ninsns - insns_start; 2060 - break; 2061 - case BPF_H: 2062 - if (is_12b_int(off)) { 2063 - insns_start = ctx->ninsns; 2064 - emit(rv_sh(rd, off, rs), ctx); 2065 - insn_len = ctx->ninsns - insns_start; 2066 - break; 2067 - } 2068 - 2069 - emit_imm(RV_REG_T1, off, ctx); 2070 - emit_add(RV_REG_T1, RV_REG_T1, rd, ctx); 2071 - insns_start = ctx->ninsns; 2072 - emit(rv_sh(RV_REG_T1, 0, rs), ctx); 2073 - insn_len = ctx->ninsns - insns_start; 2074 - break; 2075 - case BPF_W: 2076 - if (is_12b_int(off)) { 2077 - insns_start = ctx->ninsns; 2078 - emit_sw(rd, off, rs, ctx); 2079 - insn_len = ctx->ninsns - insns_start; 2080 - break; 2081 - } 2082 - 2083 - emit_imm(RV_REG_T1, off, ctx); 2084 - emit_add(RV_REG_T1, RV_REG_T1, rd, ctx); 2085 - insns_start = ctx->ninsns; 2086 - emit_sw(RV_REG_T1, 0, rs, ctx); 2087 - insn_len = ctx->ninsns - insns_start; 2088 - break; 2089 - case BPF_DW: 2090 - if (is_12b_int(off)) { 2091 - insns_start = ctx->ninsns; 2092 - emit_sd(rd, off, rs, ctx); 2093 - insn_len = ctx->ninsns - insns_start; 2094 - break; 2095 - } 2096 - 2097 - emit_imm(RV_REG_T1, off, ctx); 2098 - emit_add(RV_REG_T1, RV_REG_T1, rd, ctx); 2099 - insns_start = ctx->ninsns; 2100 - emit_sd(RV_REG_T1, 0, rs, ctx); 2101 - insn_len = ctx->ninsns - insns_start; 2102 - break; 2103 - } 2104 - 2105 - ret = add_exception_handler(insn, ctx, REG_DONT_CLEAR_MARKER, 2106 - insn_len); 2107 - if (ret) 2108 - return ret; 2109 - 2110 - break; 2111 - } 2112 2048 2113 2049 default: 2114 2050 pr_err("bpf-jit: unknown opcode %02x\n", code);