From 0b49f4e199b32fa9998095c3106fbb10e94b9ab3 Mon Sep 17 00:00:00 2001 From: jca Date: Sun, 13 Nov 2022 16:14:06 +0000 Subject: [PATCH] Sync data and instruction cache before entering an executable page Adapted from kettenis' fix for arm64/pmap.c. Since we haven't been able to reliably reproduce the clang crashes that affect base and ports, it not yet known whether riscv64 was badly affected by this misordering. Time will tell. ok kettenis@ --- sys/arch/riscv64/riscv64/pmap.c | 34 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/sys/arch/riscv64/riscv64/pmap.c b/sys/arch/riscv64/riscv64/pmap.c index 51ede2aa75a..6b1a45b755f 100644 --- a/sys/arch/riscv64/riscv64/pmap.c +++ b/sys/arch/riscv64/riscv64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.26 2022/11/03 23:30:55 jca Exp $ */ +/* $OpenBSD: pmap.c,v 1.27 2022/11/13 16:14:06 jca Exp $ */ /* * Copyright (c) 2019-2020 Brian Bamsch @@ -511,7 +511,6 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags) struct vm_page *pg; int error; int cache = PMAP_CACHE_WB; - int need_sync; if (pa & PMAP_NOCACHE) cache = PMAP_CACHE_CI; @@ -567,6 +566,12 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags) pmap_enter_pv(pted, pg); /* only managed mem */ } + if (pg != NULL && (flags & PROT_EXEC)) { + if ((pg->pg_flags & PG_PMAP_EXE) == 0) + icache_flush(); + atomic_setbits_int(&pg->pg_flags, PG_PMAP_EXE); + } + /* * Insert into table, if this mapping said it needed to be mapped * now. @@ -577,13 +582,6 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags) tlb_flush_page(pm, va & ~PAGE_MASK); - if (pg != NULL && (flags & PROT_EXEC)) { - need_sync = ((pg->pg_flags & PG_PMAP_EXE) == 0); - atomic_setbits_int(&pg->pg_flags, PG_PMAP_EXE); - if (need_sync) - icache_flush(); - } - error = 0; out: pmap_unlock(pm); @@ -1669,7 +1667,6 @@ pmap_fault_fixup(pmap_t pm, vaddr_t va, vm_prot_t ftype) struct vm_page *pg; paddr_t pa; pt_entry_t *pl3 = NULL; - int need_sync; int retcode = 0; pmap_lock(pm); @@ -1744,24 +1741,23 @@ pmap_fault_fixup(pmap_t pm, vaddr_t va, vm_prot_t ftype) goto done; } - /* We actually made a change, so flush it and sync. */ - pmap_pte_update(pted, pl3); - - /* Flush tlb. */ - tlb_flush_page(pm, va & ~PAGE_MASK); - /* * If this is a page that can be executed, make sure to invalidate * the instruction cache if the page has been modified or not used * yet. */ if (pted->pted_va & PROT_EXEC) { - need_sync = ((pg->pg_flags & PG_PMAP_EXE) == 0); - atomic_setbits_int(&pg->pg_flags, PG_PMAP_EXE); - if (need_sync) + if ((pg->pg_flags & PG_PMAP_EXE) == 0) icache_flush(); + atomic_setbits_int(&pg->pg_flags, PG_PMAP_EXE); } + /* We actually made a change, so flush it and sync. */ + pmap_pte_update(pted, pl3); + + /* Flush tlb. */ + tlb_flush_page(pm, va & ~PAGE_MASK); + retcode = 1; done: pmap_unlock(pm); -- 2.20.1