You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2026/10/22 10:40:12 UTC
(nuttx) 05/08: arch/risc-v: Flush all harts in up_addrenv_mprot().
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 <ma...@gmail.com>
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 <ma...@gmail.com>
---
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;
}