This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch releases/12.7
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 192dde1b58decffe53444a3fd63183349cbaf99b
Author: Ville Juven <[email protected]>
AuthorDate: Tue Oct 1 13:39:42 2024 +0300

    arm64_task/pthread_start: Set sp_el0 upon starting user process
    
    As the handling of sp_el0 was moved from the context switch routine
    to exception entry/exit, we must set sp_el0 explicitly when the user
    process is first started.
---
 arch/arm64/src/common/arm64_internal.h      |  2 +-
 arch/arm64/src/common/arm64_pthread_start.c |  4 +++-
 arch/arm64/src/common/arm64_task_start.c    |  4 +++-
 arch/arm64/src/common/arm64_vectors.S       | 12 +++++++-----
 4 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/src/common/arm64_internal.h 
b/arch/arm64/src/common/arm64_internal.h
index 6643117005..6610a966ee 100644
--- a/arch/arm64/src/common/arm64_internal.h
+++ b/arch/arm64/src/common/arm64_internal.h
@@ -264,7 +264,7 @@ EXTERN uint8_t g_idle_topstack[];   /* End+1 of heap */
 
 void arm64_new_task(struct tcb_s *tak_new);
 void arm64_jump_to_user(uint64_t entry, uint64_t x0, uint64_t x1,
-                        uint64_t *regs) noreturn_function;
+                        uint64_t sp_el0, uint64_t *regs) noreturn_function;
 
 /* Low level initialization provided by chip logic */
 
diff --git a/arch/arm64/src/common/arm64_pthread_start.c 
b/arch/arm64/src/common/arm64_pthread_start.c
index 8132884cf8..3b693455b8 100644
--- a/arch/arm64/src/common/arm64_pthread_start.c
+++ b/arch/arm64/src/common/arm64_pthread_start.c
@@ -68,6 +68,8 @@
 void up_pthread_start(pthread_trampoline_t startup,
                       pthread_startroutine_t entrypt, pthread_addr_t arg)
 {
+  struct tcb_s *rtcb = this_task();
+
   /* Set up to enter the user-space pthread start-up function in
    * unprivileged mode. We need:
    *
@@ -78,7 +80,7 @@ void up_pthread_start(pthread_trampoline_t startup,
    */
 
   arm64_jump_to_user((uint64_t)startup, (uint64_t)entrypt, (uint64_t)arg,
-                     this_task()->xcp.initregs);
+                     (uint64_t)rtcb->xcp.ustkptr, rtcb->xcp.initregs);
 }
 
 #endif /* !CONFIG_BUILD_FLAT && __KERNEL__ && !CONFIG_DISABLE_PTHREAD */
diff --git a/arch/arm64/src/common/arm64_task_start.c 
b/arch/arm64/src/common/arm64_task_start.c
index 0d20f693e5..a0219a5cf6 100644
--- a/arch/arm64/src/common/arm64_task_start.c
+++ b/arch/arm64/src/common/arm64_task_start.c
@@ -65,6 +65,8 @@
 
 void up_task_start(main_t taskentry, int argc, char *argv[])
 {
+  struct tcb_s *rtcb = this_task();
+
   /* Set up to return to the user-space _start function in
    * unprivileged mode.  We need:
    *
@@ -75,7 +77,7 @@ void up_task_start(main_t taskentry, int argc, char *argv[])
    */
 
   arm64_jump_to_user((uint64_t)taskentry, (uint64_t)argc, (uint64_t)argv,
-                     this_task()->xcp.initregs);
+                     (uint64_t)rtcb->xcp.ustkptr, rtcb->xcp.initregs);
 }
 
 #endif /* !CONFIG_BUILD_FLAT */
diff --git a/arch/arm64/src/common/arm64_vectors.S 
b/arch/arm64/src/common/arm64_vectors.S
index e23bbcff91..0c0605ca72 100644
--- a/arch/arm64/src/common/arm64_vectors.S
+++ b/arch/arm64/src/common/arm64_vectors.S
@@ -107,10 +107,11 @@ SECTION_FUNC(text, up_saveusercontext)
  *  the kernel is ready to give control to the user task in user space.
  *
  * arm64_jump_to_user(entry, x0, x1, regs)
- *     entry: process entry point
- *     x0:    parameter 0 for process
- *     x1:    parameter 1 for process
- *     regs:  integer register save area to use
+ *     entry:  process entry point
+ *     x0:     parameter 0 for process
+ *     x1:     parameter 1 for process
+ *     sp_el0: user stack pointer
+ *     regs:   integer register save area to use
  *
  ****************************************************************************/
 
@@ -118,10 +119,11 @@ SECTION_FUNC(text, up_saveusercontext)
 GTEXT(arm64_jump_to_user)
 SECTION_FUNC(text, arm64_jump_to_user)
     msr daifset, #IRQ_DAIF_MASK
-    mov sp,  x3
+    mov sp,  x4
     str x0,  [sp, #8 * REG_ELR]
     str x1,  [sp, #8 * REG_X0]
     str x2,  [sp, #8 * REG_X1]
+    str x3,  [sp, #8 * REG_SP_EL0]
     mrs x0,  spsr_el1
     and x0,  x0, #~SPSR_MODE_MASK
     #orr x0, x0, #SPSR_MODE_EL0T # EL0T=0x00, out of range for orr

Reply via email to