On 6/30/2026 11:32 PM, Thomas Weißschuh wrote:
> On Mon, Jun 29, 2026 at 09:06:16PM +0800, Jinjie Ruan wrote:
>> Syscall User Dispatch (SUD) requires the signal trampoline code to not be
>> intercepted. This is necessary to support returning with a locked selector
>> while avoiding infinite recursion back into the signal handler.
>>
>> Implement arch_syscall_is_vdso_sigreturn() for arm64 to support this
>> exclusion mechanism. For native 64-bit tasks, it checks whether the current
>> PC matches the 'svc #0' instruction inside the vDSO sigreturn trampoline.
>>
>> SYM_CODE_START(__kernel_rt_sigreturn)
>> mov x8, #__NR_rt_sigreturn
>> svc #0
>> SYM_CODE_END(__kernel_rt_sigreturn)
>>
>> For COMPAT tasks, it verifies if the instruction falls within
>> the architecture's 'sigpage' range, allowing the kernel to safely bypass
>> dispatching syscalls originating from these areas back to userspace.
>>
>> Suggested-by: Kevin Brodsky <[email protected]>
>> Suggested-by: kemal <[email protected]>
>> Signed-off-by: Jinjie Ruan <[email protected]>
>> ---
>> arch/arm64/include/asm/elf.h | 1 +
>> arch/arm64/kernel/vdso.c | 16 ++++++++++++++++
>> 2 files changed, 17 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
>> index d2779d604c7b..f43d4dea916a 100644
>> --- a/arch/arm64/include/asm/elf.h
>> +++ b/arch/arm64/include/asm/elf.h
>> @@ -185,6 +185,7 @@ do {
>> \
>> struct linux_binprm;
>> extern int arch_setup_additional_pages(struct linux_binprm *bprm,
>> int uses_interp);
>> +extern bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs);
>
> A header for that?
Sure, it need a cleanup, as currently, there is no syscall_user_dispatch
header file related to the architecture.
>
>> /* 1GB of VA */
>> #ifdef CONFIG_COMPAT
>> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
>> index 592dd8668de4..5a0314a3c26e 100644
>> --- a/arch/arm64/kernel/vdso.c
>> +++ b/arch/arm64/kernel/vdso.c
>> @@ -343,3 +343,19 @@ int arch_setup_additional_pages(struct linux_binprm
>> *bprm, int uses_interp)
>>
>> return ret;
>> }
>> +
>> +bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs)
>> +{
>> + unsigned long sigtramp;
>> +
>> +#ifdef CONFIG_COMPAT
>> + if (is_compat_task()) {
>> + unsigned long sigpage = (unsigned
>> long)current->mm->context.sigpage;
>> +
>> + return regs->pc >= sigpage && regs->pc < (sigpage + PAGE_SIZE);
>> + }
>> +#endif
>> + sigtramp = (unsigned long)VDSO_SYMBOL(current->mm->context.vdso,
>> sigtramp);
>> +
>> + return regs->pc == (sigtramp + 8);
>
> Instead of hardcoding 'sigtramp + 8' you could add a new label to the 'svc #0'
> instruction and use that with VDSO_SYMBOL().
It seems that the modification of __kernel_rt_sigreturn() is not recommended
>
>
> Thomas