Closed thehajime closed 1 week ago
diff --git a/arch/x86/um/signal.c b/arch/x86/um/signal.c
index 27a5b4b022ac..08161041d0e9 100644
--- a/arch/x86/um/signal.c
+++ b/arch/x86/um/signal.c
@@ -538,7 +538,9 @@ int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
return err;
#ifndef CONFIG_MMU
- /* XXX: need to push handler address at SP */
+ /* we need to push handler address at top of stack, as
+ * __kernel_vsyscall, called after this returns with ret with
+ * stack contents, thus push the handler here. */
frame = (struct rt_sigframe __user *) ((unsigned long) frame -
sizeof(unsigned long));
err |= __put_user((unsigned long)ksig->ka.sa.sa_handler,
@@ -571,7 +573,17 @@ SYSCALL_DEFINE0(rt_sigreturn)
struct rt_sigframe __user *frame =
(struct rt_sigframe __user *)(sp - sizeof(long));
#ifndef CONFIG_MMU
- /* XXX: need to pop handler address at SP */
+ /**
+ * we enter here with:
+ *
+ * __restore_rt:
+ * mov $15, %rax
+ * call *%rax (translated from syscall)
+ *
+ * (code is from musl libc)
+ * so, stack needs to be popped of "call"ed address before
+ * looking at rt_sigframe.
+ */
frame = (struct rt_sigframe __user *)((unsigned long)frame + sizeof(long));
#endif
struct ucontext __user *uc = &frame->uc;
why sigreturn substract sp-sizeof(long) ?