casaroli commented on code in PR #19772:
URL: https://github.com/apache/nuttx/pull/19772#discussion_r3758071933


##########
arch/xtensa/src/common/xtensa_swint.c:
##########
@@ -296,6 +345,55 @@ int xtensa_swint(int irq, void *context, void *arg)
           regs[REG_A3]        = regs[REG_A4]; /* signal */
           regs[REG_A4]        = regs[REG_A5]; /* info */
           regs[REG_A5]        = regs[REG_A6]; /* ucontext */
+
+#ifdef CONFIG_ARCH_KERNEL_STACK
+          /* The handler runs in user mode, so it has to run on the user
+           * stack.  Signal dispatch always reaches here on the thread's
+           * kernel stack -- up_schedule_sigaction() builds the dispatch
+           * context below the interrupted one -- so put that stack pointer
+           * aside and hand the thread its own stack back for the duration.
+           *
+           * Having a kernel stack at all is what says this is a user
+           * process.  Testing xcp.ustkptr instead would be wrong: that
+           * holds the user stack pointer only while a system call is in
+           * progress, so a signal caught in user code would leave the
+           * handler running on the kernel stack.
+           */
+
+          if (rtcb->xcp.kstack != NULL)
+            {
+              uintptr_t usp;
+
+              rtcb->xcp.kstkptr = (uint32_t *)regs[REG_A1];
+
+              /* The thread's own stack pointer is the one the system call
+               * saved if it was in one, and otherwise the one it was
+               * interrupted with, which up_schedule_sigaction() kept.
+               */
+
+              usp = rtcb->xcp.ustkptr != NULL ?
+                    (uintptr_t)rtcb->xcp.ustkptr :
+                    (uintptr_t)rtcb->xcp.saved_regs[REG_A1];
+
+              /* The siginfo passed in lives on the kernel stack, which the
+               * handler must not reach -- and cannot, once the permission
+               * control is programmed.  Copy it onto the user stack and
+               * hand the handler that copy.
+               *
+               * Skip the base save area the windowed ABI keeps in the
+               * 16 bytes below a stack pointer: it belongs to the frame
+               * that was interrupted.
+               */
+
+              usp = (usp - SIGTRAMP_SAVE_AREA - sizeof(siginfo_t)) &
+                    ~(SIGTRAMP_STACK_ALIGN - 1);

Review Comment:
   see previous answer. should we add a `xtensa_internal.h` and add 
`STACK_ALIGMENT` there?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to