From 557d0cc3f2520feba45360beeafb93203b3230e0 Mon Sep 17 00:00:00 2001 From: Varun R Mallya Date: Wed, 3 Jun 2026 02:28:46 +0530 Subject: [PATCH 1/2] selftests/bpf: use host CPU features in JIT disassembler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass the host CPU name and feature string to LLVMCreateDisasmCPUFeatures() instead of using LLVMCreateDisasm(), so the disassembler correctly decodes CPU-specific instructions and extensions such as RISC-V compressed and vector instructions. Signed-off-by: Varun R Mallya Reviewed-by: Björn Töpel Link: https://lore.kernel.org/r/20260602205847.102825-2-varunrmallya@gmail.com Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/jit_disasm_helpers.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/bpf/jit_disasm_helpers.c b/tools/testing/selftests/bpf/jit_disasm_helpers.c index 364c557c5115..3558fe10e28c 100644 --- a/tools/testing/selftests/bpf/jit_disasm_helpers.c +++ b/tools/testing/selftests/bpf/jit_disasm_helpers.c @@ -96,10 +96,19 @@ static int disasm_one_func(FILE *text_out, uint8_t *image, __u32 len) __u32 *label_pc, pc; int i, cnt, err = 0; char buf[64]; + char *cpu, *features; triple = LLVMGetDefaultTargetTriple(); - ctx = LLVMCreateDisasm(triple, &labels, 0, NULL, lookup_symbol); - if (!ASSERT_OK_PTR(ctx, "LLVMCreateDisasm")) { + + cpu = LLVMGetHostCPUName(); + features = LLVMGetHostCPUFeatures(); + + ctx = LLVMCreateDisasmCPUFeatures(triple, cpu, features, &labels, 0, NULL, lookup_symbol); + + LLVMDisposeMessage(cpu); + LLVMDisposeMessage(features); + + if (!ASSERT_OK_PTR(ctx, "LLVMCreateDisasmCPUFeatures")) { err = -EINVAL; goto out; } From 6d13ddb1d46525931d2324d9358721eb3c495d72 Mon Sep 17 00:00:00 2001 From: Varun R Mallya Date: Wed, 3 Jun 2026 02:28:47 +0530 Subject: [PATCH 2/2] bpf, riscv: inline bpf_get_current_task() and bpf_get_current_task_btf() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On RISC-V, the current task pointer is stored in the thread pointer register (tp). Emit a single `mv a5, tp` instead of a full helper call for BPF_FUNC_get_current_task and BPF_FUNC_get_current_task_btf. Register bpf_jit_inlines_helper_call() entries for both helpers so the verifier treats them as inlined, and add the expected `mv a5, tp` annotation to the riscv64 selftests. The following show changes before and after this patch. Before patch: auipc t1,0x817a # load upper PC-relative address jalr -2004(t1) # call bpf_get_current_task helper mv a5,a0 # move return value to BPF_REG_0 After patch: mv a5,tp # directly: a5 = current (tp = thread pointer) Benchmark (bpf_prog_test_run wrapping bpf_get_current_task in loop, batch=100, 10s, QEMU RISC-V): | runs/sec | helper-calls/sec | ns/call -------------+-----------+------------------+--------- Before patch | 173,490 | 17,349,090 | 57 After patch | 320,497 | 32,049,780 | 31 -------------+-----------+------------------+--------- Improvement | +84.7% | +84.7% | -45.6% Signed-off-by: Varun R Mallya Acked-by: Björn Töpel Link: https://lore.kernel.org/r/20260602205847.102825-3-varunrmallya@gmail.com Signed-off-by: Alexei Starovoitov --- arch/riscv/net/bpf_jit_comp64.c | 9 +++++++++ tools/testing/selftests/bpf/progs/verifier_jit_inline.c | 2 ++ 2 files changed, 11 insertions(+) diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c index 2f1109dbf105..e2c70c70cca8 100644 --- a/arch/riscv/net/bpf_jit_comp64.c +++ b/arch/riscv/net/bpf_jit_comp64.c @@ -1808,6 +1808,13 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx, break; } + /* Implement helper call to bpf_get_current_task/_btf() inline */ + if (insn->src_reg == 0 && (insn->imm == BPF_FUNC_get_current_task || + insn->imm == BPF_FUNC_get_current_task_btf)) { + emit_mv(bpf_to_rv_reg(BPF_REG_0, ctx), RV_REG_TP, ctx); + break; + } + mark_call(ctx); ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass, &addr, &fixed_addr); @@ -2138,6 +2145,8 @@ bool bpf_jit_inlines_helper_call(s32 imm) { switch (imm) { case BPF_FUNC_get_smp_processor_id: + case BPF_FUNC_get_current_task: + case BPF_FUNC_get_current_task_btf: return true; default: return false; diff --git a/tools/testing/selftests/bpf/progs/verifier_jit_inline.c b/tools/testing/selftests/bpf/progs/verifier_jit_inline.c index 885ff69a3a62..76d80605ec7f 100644 --- a/tools/testing/selftests/bpf/progs/verifier_jit_inline.c +++ b/tools/testing/selftests/bpf/progs/verifier_jit_inline.c @@ -10,6 +10,8 @@ __arch_x86_64 __jited(" addq %gs:{{.*}}, %rax") __arch_arm64 __jited(" mrs x8, SP_EL0") +__arch_riscv64 +__jited(" mv a5, tp") int inline_bpf_get_current_task(void) { bpf_get_current_task();