[PATCH bpf-next v6 6/7] riscv, bpf: Mixing bpf2bpf and tailcalls

Pu Lehui pulehui at huaweicloud.com
Wed Jul 8 01:54:50 PDT 2026



On 2026/7/8 15:35, bot+bpf-ci at kernel.org wrote:
>> commit 64161f8a9f1c78ecd88b27109e6ed8b53282f94b
>> Author: Pu Lehui <pulehui at huawei.com>
>> Date:   Wed Jul 8 06:44:35 2026 +0000
>>
>>      riscv, bpf: Mixing bpf2bpf and tailcalls
>>
>>      In the current RV64 JIT, if we just don't initialize the TCC in subprog,
>>      the TCC can be propagated from the parent process to the subprocess, but
>>      the updated TCC of the parent process cannot be restored when the
>>      subprocess exits. Since the RV64 TCC is initialized before saving the
>>      callee saved registers into the stack, we cannot use the callee saved
>>      register to pass the TCC, otherwise the original value of the callee
>>      saved register will be destroyed. So we implemented mixing bpf2bpf and
>>      tailcalls similar to x86_64, i.e. using a non-callee saved register to
>>      transfer the TCC between functions, and saving that register to the
>>      stack to protect the TCC value. As for the tailcall hierarchy issue,
>>      inspired by the s390's low-overhead approach, we store TCC from
>>      RV_REG_TCC back to stack after calling bpf2bpf call or calling orig bpf
>>      func in bpf trampoline.
>>
>>      Tests test_bpf.ko and test_verifier have passed, as well as the relative
>>      testcases of test_progs*.
>>
>>      Signed-off-by: Pu Lehui <pulehui at huawei.com>
> 
> This looks like a bug fix for TCC handling across bpf2bpf calls and
> tailcalls. Should this include:
> 
>    Fixes: 2353ecc6f91f ("bpf, riscv: add BPF JIT for RV64G")
> 
>> diff --git a/arch/riscv/net/bpf_jit.h b/arch/riscv/net/bpf_jit.h
>> index da02717902442..419b9d795f2a7 100644
>> --- a/arch/riscv/net/bpf_jit.h
>> +++ b/arch/riscv/net/bpf_jit.h
>> @@ -81,6 +81,7 @@ struct rv_jit_context {
>>   	int ex_jmp_off;
>>   	unsigned long flags;
>>   	int stack_size;
>> +	int tcc_offset;
>>   	u64 arena_vm_start;
>>   	u64 user_vm_start;
>>   };
>> diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
>> index 7c6304e0b846a..823262ca47ebf 100644
>> --- a/arch/riscv/net/bpf_jit_comp64.c
>> +++ b/arch/riscv/net/bpf_jit_comp64.c
> 
> [ ... ]
> 
>> @@ -2038,11 +2038,10 @@ void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog)
>>   	for (i = 0; i < RV_FENTRY_NINSNS; i++)
>>   		emit(rv_nop(), ctx);
>>
>> -	/* First instruction is always setting the tail-call-counter
>> -	 * (TCC) register. This instruction is skipped for tail calls.
>> -	 * Force using a 4-byte (non-compressed) instruction.
>> -	 */
>> -	emit(rv_addi(RV_REG_TCC, RV_REG_ZERO, MAX_TAIL_CALL_CNT), ctx);
>> +	if (!is_subprog)
>> +		emit(rv_addi(RV_REG_TCC, RV_REG_ZERO, MAX_TAIL_CALL_CNT), ctx);
>> +
>> +	/* tailcall starts here, emit insn before it must be fixed */
>>
>>   	emit_addi(RV_REG_SP, RV_REG_SP, -stack_adjust, ctx);
> 
> The TCC initialization is now conditionally emitted based on is_subprog.
> Does this affect the RV_TAILCALL_OFFSET calculation?
> 
> Looking at the RV_TAILCALL_OFFSET macro definition:
> 
>    #define RV_TAILCALL_OFFSET ((RV_FENTRY_NINSNS + 1) * 4)
> 
> This assumes a fixed number of instructions before the tailcall entry
> point. When is_subprog is true, the rv_addi() instruction is not emitted,
> which means the tailcall entry point moves forward by 4 bytes relative to
> where RV_TAILCALL_OFFSET expects it to be.
> 
> The tailcall entry is used in emit_bpf_tail_call() when calculating the
> jump target for the tail call. If RV_TAILCALL_OFFSET doesn't account for
> the conditional emission, could this cause the wrong entry point to be
> used when tail calling into subprograms?

This is not an issue, subprog can not be the tailcall callee.

> 
> 
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
> 
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/28923410500




More information about the linux-riscv mailing list