arch/x86_64: restore the kernel stack when a signal handler returns

SYS_signal_handler_return restored RSP from saved_rsp, which is not
written when a task signals itself: synchronous dispatch skips
up_schedule_sigaction(), so the kernel stack pointer was set to zero
and the next push faulted. Save the kernel stack pointer at dispatch
in xcp.kstkptr, as risc-v does, and restore that.

Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
This commit is contained in:
raiden00pl 2026-08-10 12:19:27 +02:00 committed by Xiang Xiao
parent 8f45ffb1c7
commit 8aa02a2362

View file

@ -235,6 +235,12 @@ uint64_t *x86_64_syscall(uint64_t *regs)
{
uint64_t usp;
/* Save the kernel stack pointer to restore on handler
* return
*/
rtcb->xcp.kstkptr = (uintptr_t *)regs[REG_RSP];
/* Copy "info" into user stack */
usp = rtcb->xcp.saved_ursp - 8;
@ -278,12 +284,21 @@ uint64_t *x86_64_syscall(uint64_t *regs)
DEBUGASSERT(rtcb->xcp.sigreturn != 0);
regs[REG_RCX] = rtcb->xcp.sigreturn;
regs[REG_RSP] = rtcb->xcp.saved_rsp;
rtcb->xcp.sigreturn = 0;
/* For kernel mode, we should be already on a correct kernel stack
* which was recovered in x86_64_syscall_entry.
*/
#ifdef CONFIG_ARCH_KERNEL_STACK
if (rtcb->xcp.kstack != NULL)
{
/* Return to the kernel stack saved at dispatch */
regs[REG_RSP] = (uint64_t)rtcb->xcp.kstkptr;
rtcb->xcp.kstkptr = rtcb->xcp.ktopstk;
}
else
#endif
{
regs[REG_RSP] = rtcb->xcp.saved_rsp;
}
break;
}