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; }
