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

commit bfa56a95d99e4a902cb9107d7dcb3dc6546702c1
Author: Marco Casaroli <[email protected]>
AuthorDate: Mon Oct 19 22:06:44 2026 +0200

    arch/risc-v: Flush all harts in up_addrenv_mprot().
    
    up_addrenv_mprot() changed the page entries and then ran sfence.vma
    and fence.i on the local hart only.  On SMP, another hart can run a
    thread of the same process: it kept the old permissions in its TLB,
    and its instruction fetch could miss code written to the pages before
    they became executable.
    
    With CONFIG_SMP, now each hart runs sfence.vma and fence.i, through
    nxsched_smp_call().  Without SMP the local fence.i stays.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 arch/risc-v/src/common/riscv_addrenv_perms.c | 32 ++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/arch/risc-v/src/common/riscv_addrenv_perms.c 
b/arch/risc-v/src/common/riscv_addrenv_perms.c
index cea004db7c8..3f40d9f195e 100644
--- a/arch/risc-v/src/common/riscv_addrenv_perms.c
+++ b/arch/risc-v/src/common/riscv_addrenv_perms.c
@@ -32,6 +32,7 @@
 #include <nuttx/addrenv.h>
 #include <nuttx/arch.h>
 #include <nuttx/pgalloc.h>
+#include <nuttx/sched.h>
 
 #include <arch/barriers.h>
 
@@ -50,6 +51,16 @@
  * Private Functions
  ****************************************************************************/
 
+#ifdef CONFIG_SMP
+static int flush_hart(FAR void *arg)
+{
+  UNUSED(arg);
+  mmu_invalidate_tlbs();
+  UP_ISB();
+  return OK;
+}
+#endif
+
 static uintptr_t get_pgtable(uintptr_t l1vaddr, uintptr_t vaddr)
 {
   uintptr_t lnvaddr;
@@ -131,10 +142,27 @@ static int modify_region(uintptr_t vstart, uintptr_t 
vend, uintptr_t setmask)
       mmu_ln_restore(RV_MMU_PT_LEVELS, lnvaddr, vaddr, entry);
     }
 
-  /* When all is set and done, flush the data caches */
+  /* Make the new entries and the code in the pages visible to instruction
+   * fetch: sfence.vma and fence.i act on one hart only.
+   */
 
-  UP_ISB();
   UP_DMB();
+#ifdef CONFIG_SMP
+  {
+    cpu_set_t cpus;
+    int cpu;
+
+    CPU_ZERO(&cpus);
+    for (cpu = 0; cpu < CONFIG_SMP_NCPUS; cpu++)
+      {
+        CPU_SET(cpu, &cpus);
+      }
+
+    nxsched_smp_call(cpus, flush_hart, NULL);
+  }
+#else
+  UP_ISB();
+#endif
 
   return OK;
 }

Reply via email to