diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 4f7643b0cff..aa888e8331a 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -153,6 +153,12 @@ config XTENSA_MMU_DOUBLE_MAP This option specifies that the memory is mapped in two distinct region, cached and uncached. + config XTENSA_INVALIDATE_MEM_DOMAIN_TLB_ON_SWAP + bool + help + This invalidates all TLBs referred by the incoming thread's + memory domain when swapping page tables. + endif # XTENSA_MMU config XTENSA_SYSCALL_USE_HELPER diff --git a/arch/xtensa/core/ptables.c b/arch/xtensa/core/ptables.c index b6d81e21db1..ec8295f6144 100644 --- a/arch/xtensa/core/ptables.c +++ b/arch/xtensa/core/ptables.c @@ -1095,6 +1095,19 @@ void xtensa_swap_update_page_tables(struct k_thread *incoming) &(incoming->mem_domain_info.mem_domain->arch); xtensa_set_paging(domain->asid, ptables); + +#ifdef CONFIG_XTENSA_INVALIDATE_MEM_DOMAIN_TLB_ON_SWAP + struct k_mem_domain *mem_domain = incoming->mem_domain_info.mem_domain; + + for (int idx = 0; idx < mem_domain->num_partitions; idx++) { + struct k_mem_partition *part = &mem_domain->partitions[idx]; + uintptr_t end = part->start + part->size; + + for (uintptr_t addr = part->start; addr < end; addr += CONFIG_MMU_PAGE_SIZE) { + xtensa_dtlb_vaddr_invalidate((void *)addr); + } + } +#endif } #endif /* CONFIG_USERSPACE */