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_ldx() helper

There's a lot of redundant code related to load into register
operations, let's extract emit_ldx() 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-4-pulehui@huaweicloud.com

authored by

Pu Lehui and committed by
Daniel Borkmann
01422a4f d92c11a6

+35 -108
+35 -108
arch/riscv/net/bpf_jit_comp64.c
··· 473 473 emit(hash, ctx); 474 474 } 475 475 476 - static int emit_load_8(bool sign_ext, u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx) 476 + static void emit_ldx_insn(u8 rd, s16 off, u8 rs, u8 size, bool sign_ext, 477 + struct rv_jit_context *ctx) 477 478 { 478 - int insns_start; 479 - 480 - if (is_12b_int(off)) { 481 - insns_start = ctx->ninsns; 482 - if (sign_ext) 483 - emit(rv_lb(rd, off, rs), ctx); 484 - else 485 - emit(rv_lbu(rd, off, rs), ctx); 486 - return ctx->ninsns - insns_start; 487 - } 488 - 489 - emit_imm(RV_REG_T1, off, ctx); 490 - emit_add(RV_REG_T1, RV_REG_T1, rs, ctx); 491 - insns_start = ctx->ninsns; 492 - if (sign_ext) 493 - emit(rv_lb(rd, 0, RV_REG_T1), ctx); 494 - else 495 - emit(rv_lbu(rd, 0, RV_REG_T1), ctx); 496 - return ctx->ninsns - insns_start; 497 - } 498 - 499 - static int emit_load_16(bool sign_ext, u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx) 500 - { 501 - int insns_start; 502 - 503 - if (is_12b_int(off)) { 504 - insns_start = ctx->ninsns; 505 - if (sign_ext) 506 - emit(rv_lh(rd, off, rs), ctx); 507 - else 508 - emit(rv_lhu(rd, off, rs), ctx); 509 - return ctx->ninsns - insns_start; 510 - } 511 - 512 - emit_imm(RV_REG_T1, off, ctx); 513 - emit_add(RV_REG_T1, RV_REG_T1, rs, ctx); 514 - insns_start = ctx->ninsns; 515 - if (sign_ext) 516 - emit(rv_lh(rd, 0, RV_REG_T1), ctx); 517 - else 518 - emit(rv_lhu(rd, 0, RV_REG_T1), ctx); 519 - return ctx->ninsns - insns_start; 520 - } 521 - 522 - static int emit_load_32(bool sign_ext, u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx) 523 - { 524 - int insns_start; 525 - 526 - if (is_12b_int(off)) { 527 - insns_start = ctx->ninsns; 528 - if (sign_ext) 529 - emit(rv_lw(rd, off, rs), ctx); 530 - else 531 - emit(rv_lwu(rd, off, rs), ctx); 532 - return ctx->ninsns - insns_start; 533 - } 534 - 535 - emit_imm(RV_REG_T1, off, ctx); 536 - emit_add(RV_REG_T1, RV_REG_T1, rs, ctx); 537 - insns_start = ctx->ninsns; 538 - if (sign_ext) 539 - emit(rv_lw(rd, 0, RV_REG_T1), ctx); 540 - else 541 - emit(rv_lwu(rd, 0, RV_REG_T1), ctx); 542 - return ctx->ninsns - insns_start; 543 - } 544 - 545 - static int emit_load_64(bool sign_ext, u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx) 546 - { 547 - int insns_start; 548 - 549 - if (is_12b_int(off)) { 550 - insns_start = ctx->ninsns; 479 + switch (size) { 480 + case BPF_B: 481 + emit(sign_ext ? rv_lb(rd, off, rs) : rv_lbu(rd, off, rs), ctx); 482 + break; 483 + case BPF_H: 484 + emit(sign_ext ? rv_lh(rd, off, rs) : rv_lhu(rd, off, rs), ctx); 485 + break; 486 + case BPF_W: 487 + emit(sign_ext ? rv_lw(rd, off, rs) : rv_lwu(rd, off, rs), ctx); 488 + break; 489 + case BPF_DW: 551 490 emit_ld(rd, off, rs, ctx); 552 - return ctx->ninsns - insns_start; 491 + break; 553 492 } 554 493 555 - emit_imm(RV_REG_T1, off, ctx); 556 - emit_add(RV_REG_T1, RV_REG_T1, rs, ctx); 557 - insns_start = ctx->ninsns; 558 - emit_ld(rd, 0, RV_REG_T1, ctx); 559 - return ctx->ninsns - insns_start; 560 494 } 561 495 562 496 static void emit_stx_insn(u8 rd, s16 off, u8 rs, u8 size, struct rv_jit_context *ctx) ··· 509 575 emit_sd(rd, off, rs, ctx); 510 576 break; 511 577 } 578 + } 579 + 580 + static int emit_ldx(u8 rd, s16 off, u8 rs, u8 size, bool sign_ext, 581 + struct rv_jit_context *ctx) 582 + { 583 + int insns_start; 584 + 585 + if (is_12b_int(off)) { 586 + insns_start = ctx->ninsns; 587 + emit_ldx_insn(rd, off, rs, size, sign_ext, ctx); 588 + return ctx->ninsns - insns_start; 589 + } 590 + 591 + emit_imm(RV_REG_T1, off, ctx); 592 + emit_add(RV_REG_T1, RV_REG_T1, rs, ctx); 593 + insns_start = ctx->ninsns; 594 + emit_ldx_insn(rd, 0, RV_REG_T1, size, sign_ext, ctx); 595 + return ctx->ninsns - insns_start; 512 596 } 513 597 514 598 static int emit_st(u8 rd, s16 off, s32 imm, u8 size, struct rv_jit_context *ctx) ··· 574 622 switch (imm) { 575 623 /* dst_reg = load_acquire(src_reg + off16) */ 576 624 case BPF_LOAD_ACQ: 577 - switch (BPF_SIZE(code)) { 578 - case BPF_B: 579 - emit_load_8(false, rd, off, rs, ctx); 580 - break; 581 - case BPF_H: 582 - emit_load_16(false, rd, off, rs, ctx); 583 - break; 584 - case BPF_W: 585 - emit_load_32(false, rd, off, rs, ctx); 586 - break; 587 - case BPF_DW: 588 - emit_load_64(false, rd, off, rs, ctx); 589 - break; 590 - } 625 + emit_ldx(rd, off, rs, BPF_SIZE(code), false, ctx); 591 626 emit_fence_r_rw(ctx); 592 627 593 628 /* If our next insn is a redundant zext, return 1 to tell ··· 1798 1859 rs = RV_REG_T2; 1799 1860 } 1800 1861 1801 - switch (BPF_SIZE(code)) { 1802 - case BPF_B: 1803 - insn_len = emit_load_8(sign_ext, rd, off, rs, ctx); 1804 - break; 1805 - case BPF_H: 1806 - insn_len = emit_load_16(sign_ext, rd, off, rs, ctx); 1807 - break; 1808 - case BPF_W: 1809 - insn_len = emit_load_32(sign_ext, rd, off, rs, ctx); 1810 - break; 1811 - case BPF_DW: 1812 - insn_len = emit_load_64(sign_ext, rd, off, rs, ctx); 1813 - break; 1814 - } 1862 + insn_len = emit_ldx(rd, off, rs, BPF_SIZE(code), sign_ext, ctx); 1815 1863 1816 1864 ret = add_exception_handler(insn, ctx, rd, insn_len); 1817 1865 if (ret) ··· 1808 1882 return 1; 1809 1883 break; 1810 1884 } 1885 + 1811 1886 /* speculation barrier */ 1812 1887 case BPF_ST | BPF_NOSPEC: 1813 1888 break;