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

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 657ac8317e9 arch: fix addrenv_switch changing this_task causing 
exceptions
657ac8317e9 is described below

commit 657ac8317e988554531f8a2e234df2eb697e915a
Author: hujun5 <[email protected]>
AuthorDate: Tue May 6 19:24:52 2025 +0800

    arch: fix addrenv_switch changing this_task causing exceptions
    
    After addrenv_switch(), the current running task (this_task) may change due 
to
    deferred work execution. Update all architecture interrupt, syscall, and 
exit
    handlers to re-fetch tcb = this_task() after addrenv_switch(). Ensures 
scheduler
    and context operations use the correct TCB, preventing context corruption 
and
    exceptions across SMP and memory-protected builds.
    
    Signed-off-by: hujun5 <[email protected]>
---
 arch/arm/src/arm/arm_doirq.c                        |  1 +
 arch/arm/src/arm/arm_syscall.c                      |  7 ++++---
 arch/arm/src/armv7-a/arm_doirq.c                    |  1 +
 arch/arm/src/armv7-a/arm_syscall.c                  | 11 ++++++++---
 arch/arm/src/armv7-r/arm_syscall.c                  |  8 ++++----
 arch/arm64/src/common/arm64_doirq.c                 |  1 +
 arch/arm64/src/common/arm64_syscall.c               | 10 +++++++---
 arch/avr/src/avr32/avr_doirq.c                      |  1 +
 arch/avr/src/avr32/avr_switchcontext.c              |  1 +
 arch/avr/src/common/avr_exit.c                      |  9 +++++----
 arch/hc/src/common/hc_doirq.c                       |  1 +
 arch/hc/src/common/hc_exit.c                        |  9 +++++----
 arch/hc/src/common/hc_switchcontext.c               |  1 +
 arch/mips/src/mips32/mips_doirq.c                   |  1 +
 arch/misoc/src/lm32/lm32_doirq.c                    |  1 +
 arch/misoc/src/minerva/minerva_doirq.c              |  1 +
 arch/or1k/src/common/or1k_exit.c                    |  9 +++++----
 arch/or1k/src/common/or1k_switchcontext.c           |  1 +
 arch/renesas/src/common/renesas_doirq.c             |  1 +
 arch/renesas/src/common/renesas_exit.c              |  9 +++++----
 arch/renesas/src/common/renesas_switchcontext.c     |  1 +
 arch/risc-v/src/common/riscv_doirq.c                |  1 +
 .../src/common/supervisor/riscv_perform_syscall.c   |  1 +
 arch/sparc/src/sparc_v8/sparc_v8_doirq.c            |  1 +
 arch/tricore/src/common/tricore_doirq.c             |  1 +
 arch/x86/src/common/x86_exit.c                      | 13 +++++++------
 arch/x86/src/common/x86_switchcontext.c             |  1 +
 arch/x86/src/qemu/qemu_handlers.c                   |  1 +
 arch/x86_64/src/common/x86_64_exit.c                | 21 +++++++++++----------
 arch/x86_64/src/common/x86_64_switchcontext.c       |  1 +
 arch/x86_64/src/intel64/intel64_handlers.c          |  1 +
 arch/xtensa/src/common/xtensa_irqdispatch.c         |  1 +
 arch/z80/src/common/z80_doirq.c                     |  1 +
 arch/z80/src/common/z80_exit.c                      | 12 +++++++-----
 arch/z80/src/common/z80_switchcontext.c             |  1 +
 35 files changed, 92 insertions(+), 50 deletions(-)

diff --git a/arch/arm/src/arm/arm_doirq.c b/arch/arm/src/arm/arm_doirq.c
index 28d3fc780d1..292e48e9561 100644
--- a/arch/arm/src/arm/arm_doirq.c
+++ b/arch/arm/src/arm/arm_doirq.c
@@ -98,6 +98,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
 
       /* Update scheduler parameters */
diff --git a/arch/arm/src/arm/arm_syscall.c b/arch/arm/src/arm/arm_syscall.c
index d1489cea10f..80eb127c723 100644
--- a/arch/arm/src/arm/arm_syscall.c
+++ b/arch/arm/src/arm/arm_syscall.c
@@ -95,6 +95,10 @@ uint32_t *arm_syscall(uint32_t *regs)
         nxsched_switch_context(*running_task, tcb);
 
       case SYS_restore_context:
+#ifdef CONFIG_ARCH_ADDRENV
+        addrenv_switch(tcb);
+        tcb = this_task();
+#endif
 
         /* No context switch occurs in SYS_restore_context, or the
          * context switch has been completed, so there is no
@@ -106,9 +110,6 @@ uint32_t *arm_syscall(uint32_t *regs)
         /* Restore the cpu lock */
 
         restore_critical_section(tcb, cpu);
-#ifdef CONFIG_ARCH_ADDRENV
-        addrenv_switch(tcb);
-#endif
         break;
 
       default:
diff --git a/arch/arm/src/armv7-a/arm_doirq.c b/arch/arm/src/armv7-a/arm_doirq.c
index 3bed25c02e1..f3a37c6c864 100644
--- a/arch/arm/src/armv7-a/arm_doirq.c
+++ b/arch/arm/src/armv7-a/arm_doirq.c
@@ -98,6 +98,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
 
       /* Update scheduler parameters */
diff --git a/arch/arm/src/armv7-a/arm_syscall.c 
b/arch/arm/src/armv7-a/arm_syscall.c
index 9bc9fcc4712..a2ddda360b0 100644
--- a/arch/arm/src/armv7-a/arm_syscall.c
+++ b/arch/arm/src/armv7-a/arm_syscall.c
@@ -274,6 +274,14 @@ uint32_t *arm_syscall(uint32_t *regs)
 
       case SYS_restore_context:
 
+#ifdef CONFIG_ARCH_ADDRENV
+        /* The addrenv_switch may change this_task, for example addrenv drop
+         * will post sem to hpwork, so we have to call before restore context
+         */
+
+        addrenv_switch(tcb);
+        tcb = this_task();
+#endif
         /* No context switch occurs in SYS_restore_context, or the
          * context switch has been completed, so there is no
          * need to update scheduler parameters.
@@ -285,9 +293,6 @@ uint32_t *arm_syscall(uint32_t *regs)
 
         restore_critical_section(tcb, cpu);
         regs = tcb->xcp.regs;
-#ifdef CONFIG_ARCH_ADDRENV
-        addrenv_switch(tcb);
-#endif
         break;
 
       /* R0=SYS_task_start:  This a user task start
diff --git a/arch/arm/src/armv7-r/arm_syscall.c 
b/arch/arm/src/armv7-r/arm_syscall.c
index bd2fa08862f..286b8e5a64e 100644
--- a/arch/arm/src/armv7-r/arm_syscall.c
+++ b/arch/arm/src/armv7-r/arm_syscall.c
@@ -270,7 +270,10 @@ uint32_t *arm_syscall(uint32_t *regs)
         nxsched_switch_context(*running_task, tcb);
 
       case SYS_restore_context:
-
+#ifdef CONFIG_ARCH_ADDRENV
+        addrenv_switch(tcb);
+        tcb = this_task();
+#endif
         /* No context switch occurs in SYS_restore_context, or the
          * context switch has been completed, so there is no
          * need to update scheduler parameters.
@@ -282,9 +285,6 @@ uint32_t *arm_syscall(uint32_t *regs)
 
         restore_critical_section(tcb, cpu);
         regs = tcb->xcp.regs;
-#ifdef CONFIG_ARCH_ADDRENV
-        addrenv_switch(tcb);
-#endif
         break;
 
       /* R0=SYS_task_start:  This a user task start
diff --git a/arch/arm64/src/common/arm64_doirq.c 
b/arch/arm64/src/common/arm64_doirq.c
index 267e736f266..2c89c09a863 100644
--- a/arch/arm64/src/common/arm64_doirq.c
+++ b/arch/arm64/src/common/arm64_doirq.c
@@ -128,6 +128,7 @@ uint64_t *arm64_doirq(int irq, uint64_t * regs)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
 
       /* Update scheduler parameters */
diff --git a/arch/arm64/src/common/arm64_syscall.c 
b/arch/arm64/src/common/arm64_syscall.c
index ab1a67f4660..8e4335a1aed 100644
--- a/arch/arm64/src/common/arm64_syscall.c
+++ b/arch/arm64/src/common/arm64_syscall.c
@@ -196,11 +196,18 @@ uint64_t *arm64_syscall(uint64_t *regs)
         restore_critical_section(tcb, cpu);
 #ifdef CONFIG_ARCH_ADDRENV
         addrenv_switch(tcb);
+        tcb = this_task();
+        *running_task = tcb;
 #endif
         break;
 
       case SYS_switch_context:
 
+#ifdef CONFIG_ARCH_ADDRENV
+        addrenv_switch(tcb);
+        tcb = this_task();
+#endif
+
         /* Update scheduler parameters */
 
         nxsched_switch_context(*running_task, tcb);
@@ -209,9 +216,6 @@ uint64_t *arm64_syscall(uint64_t *regs)
         /* Restore the cpu lock */
 
         restore_critical_section(tcb, cpu);
-#ifdef CONFIG_ARCH_ADDRENV
-        addrenv_switch(tcb);
-#endif
         break;
 
 #ifdef CONFIG_BUILD_KERNEL
diff --git a/arch/avr/src/avr32/avr_doirq.c b/arch/avr/src/avr32/avr_doirq.c
index ec34bd9871b..39e3361d705 100644
--- a/arch/avr/src/avr32/avr_doirq.c
+++ b/arch/avr/src/avr32/avr_doirq.c
@@ -107,6 +107,7 @@ uint32_t *avr_doirq(int irq, uint32_t *regs)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
 
       /* Update scheduler parameters. */
diff --git a/arch/avr/src/avr32/avr_switchcontext.c 
b/arch/avr/src/avr32/avr_switchcontext.c
index 7947762244a..fc641c74ba4 100644
--- a/arch/avr/src/avr32/avr_switchcontext.c
+++ b/arch/avr/src/avr32/avr_switchcontext.c
@@ -88,6 +88,7 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
       /* Update scheduler parameters */
 
diff --git a/arch/avr/src/common/avr_exit.c b/arch/avr/src/common/avr_exit.c
index 4d19bb03745..8abca623d37 100644
--- a/arch/avr/src/common/avr_exit.c
+++ b/arch/avr/src/common/avr_exit.c
@@ -67,10 +67,6 @@ void up_exit(int status)
 
   tcb = this_task();
 
-  /* Adjusts time slice for SCHED_RR & SCHED_SPORADIC cases */
-
-  g_running_tasks[this_cpu()] = tcb;
-
 #ifdef CONFIG_ARCH_ADDRENV
   /* Make sure that the address environment for the previously running
    * task is closed down gracefully (data caches dump, MMU flushed) and
@@ -79,8 +75,13 @@ void up_exit(int status)
    */
 
   addrenv_switch(tcb);
+  tcb = this_task();
 #endif
 
+  /* Adjusts time slice for SCHED_RR & SCHED_SPORADIC cases */
+
+  g_running_tasks[this_cpu()] = tcb;
+
   /* Then switch contexts */
 
   avr_fullcontextrestore(tcb->xcp.regs);
diff --git a/arch/hc/src/common/hc_doirq.c b/arch/hc/src/common/hc_doirq.c
index 4df650fb39f..5f172d6fdef 100644
--- a/arch/hc/src/common/hc_doirq.c
+++ b/arch/hc/src/common/hc_doirq.c
@@ -107,6 +107,7 @@ uint8_t *hc_doirq(int irq, uint8_t *regs)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
 
       /* Update scheduler parameters. */
diff --git a/arch/hc/src/common/hc_exit.c b/arch/hc/src/common/hc_exit.c
index 3732c4b1d3c..4e882b5c7e9 100644
--- a/arch/hc/src/common/hc_exit.c
+++ b/arch/hc/src/common/hc_exit.c
@@ -66,10 +66,6 @@ void up_exit(int status)
 
   tcb = this_task();
 
-  /* Adjusts time slice for SCHED_RR & SCHED_SPORADIC cases */
-
-  g_running_tasks[this_cpu()] = tcb;
-
 #ifdef CONFIG_ARCH_ADDRENV
   /* Make sure that the address environment for the previously running
    * task is closed down gracefully (data caches dump, MMU flushed) and
@@ -78,8 +74,13 @@ void up_exit(int status)
    */
 
   addrenv_switch(tcb);
+  tcb = this_task();
 #endif
 
+  /* Adjusts time slice for SCHED_RR & SCHED_SPORADIC cases */
+
+  g_running_tasks[this_cpu()] = tcb;
+
   /* Then switch contexts */
 
   hc_fullcontextrestore(tcb->xcp.regs);
diff --git a/arch/hc/src/common/hc_switchcontext.c 
b/arch/hc/src/common/hc_switchcontext.c
index 61587fcf09e..76a90302b48 100644
--- a/arch/hc/src/common/hc_switchcontext.c
+++ b/arch/hc/src/common/hc_switchcontext.c
@@ -91,6 +91,7 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
       /* Update scheduler parameters */
 
diff --git a/arch/mips/src/mips32/mips_doirq.c 
b/arch/mips/src/mips32/mips_doirq.c
index b059db0a18b..a9a1de21ab4 100644
--- a/arch/mips/src/mips32/mips_doirq.c
+++ b/arch/mips/src/mips32/mips_doirq.c
@@ -116,6 +116,7 @@ uint32_t *mips_doirq(int irq, uint32_t *regs)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
 
       /* Update scheduler parameters. */
diff --git a/arch/misoc/src/lm32/lm32_doirq.c b/arch/misoc/src/lm32/lm32_doirq.c
index 6958c061526..d22a2bf33be 100644
--- a/arch/misoc/src/lm32/lm32_doirq.c
+++ b/arch/misoc/src/lm32/lm32_doirq.c
@@ -101,6 +101,7 @@ uint32_t *lm32_doirq(int irq, uint32_t *regs)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
 
       /* Update scheduler parameters. */
diff --git a/arch/misoc/src/minerva/minerva_doirq.c 
b/arch/misoc/src/minerva/minerva_doirq.c
index 8f4b316d297..266d65e2ee8 100644
--- a/arch/misoc/src/minerva/minerva_doirq.c
+++ b/arch/misoc/src/minerva/minerva_doirq.c
@@ -100,6 +100,7 @@ uint32_t *minerva_doirq(int irq, uint32_t * regs)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
 
       /* Update scheduler parameters. */
diff --git a/arch/or1k/src/common/or1k_exit.c b/arch/or1k/src/common/or1k_exit.c
index 3923f58d36b..a3ddcccf29a 100644
--- a/arch/or1k/src/common/or1k_exit.c
+++ b/arch/or1k/src/common/or1k_exit.c
@@ -68,10 +68,6 @@ void up_exit(int status)
 
   tcb = this_task();
 
-  /* Adjusts time slice for SCHED_RR & SCHED_SPORADIC cases */
-
-  g_running_tasks[this_cpu()] = tcb;
-
 #ifdef CONFIG_ARCH_ADDRENV
   /* Make sure that the address environment for the previously running
    * task is closed down gracefully (data caches dump, MMU flushed) and
@@ -80,8 +76,13 @@ void up_exit(int status)
    */
 
   addrenv_switch(tcb);
+  tcb = this_task();
 #endif
 
+  /* Adjusts time slice for SCHED_RR & SCHED_SPORADIC cases */
+
+  g_running_tasks[this_cpu()] = tcb;
+
   /* Then switch contexts */
 
   or1k_fullcontextrestore(tcb->xcp.regs);
diff --git a/arch/or1k/src/common/or1k_switchcontext.c 
b/arch/or1k/src/common/or1k_switchcontext.c
index 1927d1a6ca5..5303c630292 100644
--- a/arch/or1k/src/common/or1k_switchcontext.c
+++ b/arch/or1k/src/common/or1k_switchcontext.c
@@ -95,6 +95,7 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
       /* Update scheduler parameters */
 
diff --git a/arch/renesas/src/common/renesas_doirq.c 
b/arch/renesas/src/common/renesas_doirq.c
index 5380e230268..b45863907ec 100644
--- a/arch/renesas/src/common/renesas_doirq.c
+++ b/arch/renesas/src/common/renesas_doirq.c
@@ -110,6 +110,7 @@ uint32_t *renesas_doirq(int irq, uint32_t * regs)
            */
 
           addrenv_switch(tcb);
+          tcb = this_task();
 #endif
 
           /* Update scheduler parameters. */
diff --git a/arch/renesas/src/common/renesas_exit.c 
b/arch/renesas/src/common/renesas_exit.c
index feed938f70b..04b6057fcc8 100644
--- a/arch/renesas/src/common/renesas_exit.c
+++ b/arch/renesas/src/common/renesas_exit.c
@@ -66,10 +66,6 @@ void up_exit(int status)
 
   tcb = this_task();
 
-  /* Adjusts time slice for SCHED_RR & SCHED_SPORADIC cases */
-
-  g_running_tasks[this_cpu()] = tcb;
-
 #ifdef CONFIG_ARCH_ADDRENV
   /* Make sure that the address environment for the previously running
    * task is closed down gracefully (data caches dump, MMU flushed) and
@@ -78,8 +74,13 @@ void up_exit(int status)
    */
 
   addrenv_switch(tcb);
+  tcb = this_task();
 #endif
 
+  /* Adjusts time slice for SCHED_RR & SCHED_SPORADIC cases */
+
+  g_running_tasks[this_cpu()] = tcb;
+
   /* Then switch contexts */
 
   renesas_fullcontextrestore(tcb->xcp.regs);
diff --git a/arch/renesas/src/common/renesas_switchcontext.c 
b/arch/renesas/src/common/renesas_switchcontext.c
index 96bdf4e4803..f93d47dde52 100644
--- a/arch/renesas/src/common/renesas_switchcontext.c
+++ b/arch/renesas/src/common/renesas_switchcontext.c
@@ -91,6 +91,7 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
       /* Update scheduler parameters */
 
diff --git a/arch/risc-v/src/common/riscv_doirq.c 
b/arch/risc-v/src/common/riscv_doirq.c
index 1be918f906c..ee74b12f7ec 100644
--- a/arch/risc-v/src/common/riscv_doirq.c
+++ b/arch/risc-v/src/common/riscv_doirq.c
@@ -124,6 +124,7 @@ uintreg_t *riscv_doirq(int irq, uintreg_t *regs)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
 
       /* Update scheduler parameters */
diff --git a/arch/risc-v/src/common/supervisor/riscv_perform_syscall.c 
b/arch/risc-v/src/common/supervisor/riscv_perform_syscall.c
index 31271ac5eb8..16b700fc759 100644
--- a/arch/risc-v/src/common/supervisor/riscv_perform_syscall.c
+++ b/arch/risc-v/src/common/supervisor/riscv_perform_syscall.c
@@ -68,6 +68,7 @@ void *riscv_perform_syscall(uintreg_t *regs)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
       /* Update scheduler parameters */
 
diff --git a/arch/sparc/src/sparc_v8/sparc_v8_doirq.c 
b/arch/sparc/src/sparc_v8/sparc_v8_doirq.c
index f45dc30a7ed..c818c1268c8 100644
--- a/arch/sparc/src/sparc_v8/sparc_v8_doirq.c
+++ b/arch/sparc/src/sparc_v8/sparc_v8_doirq.c
@@ -111,6 +111,7 @@ uint32_t *sparc_doirq(int irq, uint32_t *regs)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
 
       /* Update scheduler parameters. */
diff --git a/arch/tricore/src/common/tricore_doirq.c 
b/arch/tricore/src/common/tricore_doirq.c
index 02da6543d69..87ff8b4bb24 100644
--- a/arch/tricore/src/common/tricore_doirq.c
+++ b/arch/tricore/src/common/tricore_doirq.c
@@ -89,6 +89,7 @@ IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
 
       /* Update scheduler parameters */
diff --git a/arch/x86/src/common/x86_exit.c b/arch/x86/src/common/x86_exit.c
index 1e3045bb607..bf19a41f8a9 100644
--- a/arch/x86/src/common/x86_exit.c
+++ b/arch/x86/src/common/x86_exit.c
@@ -67,12 +67,6 @@ void up_exit(int status)
 
   tcb = this_task();
 
-  /* Adjusts time slice for SCHED_RR & SCHED_SPORADIC cases
-   * NOTE: the API also adjusts the global IRQ control for SMP
-   */
-
-  g_running_tasks[this_cpu()] = tcb;
-
 #ifdef CONFIG_ARCH_ADDRENV
   /* Make sure that the address environment for the previously running
    * task is closed down gracefully (data caches dump, MMU flushed) and
@@ -81,8 +75,15 @@ void up_exit(int status)
    */
 
   addrenv_switch(tcb);
+  tcb = this_task();
 #endif
 
+  /* Adjusts time slice for SCHED_RR & SCHED_SPORADIC cases
+   * NOTE: the API also adjusts the global IRQ control for SMP
+   */
+
+  g_running_tasks[this_cpu()] = tcb;
+
   /* Then switch contexts */
 
   x86_fullcontextrestore(tcb->xcp.regs);
diff --git a/arch/x86/src/common/x86_switchcontext.c 
b/arch/x86/src/common/x86_switchcontext.c
index e604a0b685a..ca3abb53b3c 100644
--- a/arch/x86/src/common/x86_switchcontext.c
+++ b/arch/x86/src/common/x86_switchcontext.c
@@ -91,6 +91,7 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
       /* Update scheduler parameters */
 
diff --git a/arch/x86/src/qemu/qemu_handlers.c 
b/arch/x86/src/qemu/qemu_handlers.c
index a15c25b4a80..ed6a553e956 100644
--- a/arch/x86/src/qemu/qemu_handlers.c
+++ b/arch/x86/src/qemu/qemu_handlers.c
@@ -121,6 +121,7 @@ static uint32_t *common_handler(int irq, uint32_t *regs)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
 
       /* Update scheduler parameters */
diff --git a/arch/x86_64/src/common/x86_64_exit.c 
b/arch/x86_64/src/common/x86_64_exit.c
index 8e74d349efa..22d13b74975 100644
--- a/arch/x86_64/src/common/x86_64_exit.c
+++ b/arch/x86_64/src/common/x86_64_exit.c
@@ -66,16 +66,6 @@ void up_exit(int status)
 
   tcb = this_task();
 
-  /* Adjusts time slice for SCHED_RR & SCHED_SPORADIC cases
-   * NOTE: the API also adjusts the global IRQ control for SMP
-   */
-
-  g_running_tasks[this_cpu()] = tcb;
-
-  /* Context switch, rearrange MMU */
-
-  x86_64_restore_auxstate(tcb);
-
 #ifdef CONFIG_ARCH_ADDRENV
   /* Make sure that the address environment for the previously running
    * task is closed down gracefully (data caches dump, MMU flushed) and
@@ -84,8 +74,19 @@ void up_exit(int status)
    */
 
   addrenv_switch(tcb);
+  tcb = this_task();
 #endif
 
+  /* Adjusts time slice for SCHED_RR & SCHED_SPORADIC cases
+   * NOTE: the API also adjusts the global IRQ control for SMP
+   */
+
+  g_running_tasks[this_cpu()] = tcb;
+
+  /* Context switch, rearrange MMU */
+
+  x86_64_restore_auxstate(tcb);
+
   /* Restore the cpu lock */
 
   restore_critical_section(tcb, this_cpu());
diff --git a/arch/x86_64/src/common/x86_64_switchcontext.c 
b/arch/x86_64/src/common/x86_64_switchcontext.c
index a72c94b724b..18b62baa2c6 100644
--- a/arch/x86_64/src/common/x86_64_switchcontext.c
+++ b/arch/x86_64/src/common/x86_64_switchcontext.c
@@ -97,6 +97,7 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
 
       /* Restore the cpu lock */
diff --git a/arch/x86_64/src/intel64/intel64_handlers.c 
b/arch/x86_64/src/intel64/intel64_handlers.c
index a19e8ce9331..61949c8abcb 100644
--- a/arch/x86_64/src/intel64/intel64_handlers.c
+++ b/arch/x86_64/src/intel64/intel64_handlers.c
@@ -102,6 +102,7 @@ static uint64_t *common_handler(int irq, uint64_t *regs)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
 
       /* Update scheduler parameters */
diff --git a/arch/xtensa/src/common/xtensa_irqdispatch.c 
b/arch/xtensa/src/common/xtensa_irqdispatch.c
index ee8c3a735b7..b1e992d237f 100644
--- a/arch/xtensa/src/common/xtensa_irqdispatch.c
+++ b/arch/xtensa/src/common/xtensa_irqdispatch.c
@@ -93,6 +93,7 @@ uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
 
       /* Update scheduler parameters */
diff --git a/arch/z80/src/common/z80_doirq.c b/arch/z80/src/common/z80_doirq.c
index 2956c19f0ab..4c60e7b19da 100644
--- a/arch/z80/src/common/z80_doirq.c
+++ b/arch/z80/src/common/z80_doirq.c
@@ -93,6 +93,7 @@ FAR chipreg_t *z80_doirq(uint8_t irq, FAR chipreg_t *regs)
            */
 
           addrenv_switch(tcb);
+          tcb = this_task();
 #endif
 
           /* Update scheduler parameters */
diff --git a/arch/z80/src/common/z80_exit.c b/arch/z80/src/common/z80_exit.c
index e6db9d5aa38..0a6922c37b3 100644
--- a/arch/z80/src/common/z80_exit.c
+++ b/arch/z80/src/common/z80_exit.c
@@ -67,11 +67,6 @@ void up_exit(int status)
    */
 
   tcb = this_task();
-  sinfo("New Active Task TCB=%p\n", tcb);
-
-  /* Adjusts time slice for SCHED_RR & SCHED_SPORADIC cases */
-
-  g_running_tasks[this_cpu()] = tcb;
 
 #ifdef CONFIG_ARCH_ADDRENV
   /* Make sure that the address environment for the previously running
@@ -81,8 +76,15 @@ void up_exit(int status)
    */
 
   addrenv_switch(tcb);
+  tcb = this_task();
 #endif
 
+  sinfo("New Active Task TCB=%p\n", tcb);
+
+  /* Adjusts time slice for SCHED_RR & SCHED_SPORADIC cases */
+
+  g_running_tasks[this_cpu()] = tcb;
+
   /* Then switch contexts */
 
   RESTORE_USERCONTEXT(tcb);
diff --git a/arch/z80/src/common/z80_switchcontext.c 
b/arch/z80/src/common/z80_switchcontext.c
index 42370fca64a..19d3656be7b 100644
--- a/arch/z80/src/common/z80_switchcontext.c
+++ b/arch/z80/src/common/z80_switchcontext.c
@@ -94,6 +94,7 @@ void up_switch_context(FAR struct tcb_s *tcb, FAR struct 
tcb_s *rtcb)
        */
 
       addrenv_switch(tcb);
+      tcb = this_task();
 #endif
 
       /* Update scheduler parameters */

Reply via email to