From: kettenis Date: Tue, 18 May 2021 09:14:49 +0000 (+0000) Subject: Remove the no-op instruction cache flush/wb/inv operations and replace them X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=a177c6b81a3ae8747833ac143bf883b7d6f03d32;p=openbsd Remove the no-op instruction cache flush/wb/inv operations and replace them with a FENCE.I instruction which does exactly what we need to synchronize the I-Cache with the D-Cache. ok mlarkin@, jsg@ --- diff --git a/sys/arch/riscv64/include/cpufunc.h b/sys/arch/riscv64/include/cpufunc.h index 33a781b9afd..884a1ed642a 100644 --- a/sys/arch/riscv64/include/cpufunc.h +++ b/sys/arch/riscv64/include/cpufunc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpufunc.h,v 1.3 2021/05/12 01:20:52 jsg Exp $ */ +/* $OpenBSD: cpufunc.h,v 1.4 2021/05/18 09:14:49 kettenis Exp $ */ /*- * Copyright (c) 2014 Andrew Turner @@ -93,10 +93,6 @@ extern void (*cpu_dcache_wbinv_range)(paddr_t, psize_t); extern void (*cpu_dcache_inv_range)(paddr_t, psize_t); extern void (*cpu_dcache_wb_range)(paddr_t, psize_t); -#define cpu_idcache_wbinv_range(a, s) -#define cpu_icache_sync_range(a, s) -#define cpu_icache_sync_range_checked(a, s) - static __inline void load_satp(uint64_t val) { diff --git a/sys/arch/riscv64/riscv64/pmap.c b/sys/arch/riscv64/riscv64/pmap.c index 312c96e5bd5..bc2687a29c1 100644 --- a/sys/arch/riscv64/riscv64/pmap.c +++ b/sys/arch/riscv64/riscv64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.10 2021/05/15 14:05:35 deraadt Exp $ */ +/* $OpenBSD: pmap.c,v 1.11 2021/05/18 09:14:49 kettenis Exp $ */ /* * Copyright (c) 2019-2020 Brian Bamsch @@ -448,7 +448,7 @@ 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 = 0; + int need_sync; if (pa & PMAP_NOCACHE) cache = PMAP_CACHE_CI; @@ -517,12 +517,10 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags) 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) + fence_i(); } - if (need_sync && (pm == pmap_kernel() || (curproc && - curproc->p_vmspace->vm_map.pmap == pm))) - cpu_icache_sync_range(va & ~PAGE_MASK, PAGE_SIZE); - error = 0; out: pmap_unlock(pm); @@ -629,8 +627,6 @@ _pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, int flags, int cache) pmap_pte_insert(pted); tlb_flush(pm, va & ~PAGE_MASK); - if (cache == PMAP_CACHE_CI || cache == PMAP_CACHE_DEV) - cpu_idcache_wbinv_range(va & ~PAGE_MASK, PAGE_SIZE); } void @@ -1574,43 +1570,7 @@ pmap_init(void) void pmap_proc_iflush(struct process *pr, vaddr_t va, vsize_t len) { - struct pmap *pm = vm_map_pmap(&pr->ps_vmspace->vm_map); - vaddr_t kva = zero_page + cpu_number() * PAGE_SIZE; - paddr_t pa; - vsize_t clen; - vsize_t off; - - /* - * If we're caled for the current processes, we can simply - * flush the data cache to the point of unification and - * invalidate the instruction cache. - */ - if (pr == curproc->p_p) { - cpu_icache_sync_range(va, len); - return; - } - - /* - * Flush and invalidate through an aliased mapping. This - * assumes the instruction cache is PIPT. That is only true - * for some of the hardware we run on. - */ - while (len > 0) { - /* add one to always round up to the next page */ - clen = round_page(va + 1) - va; - if (clen > len) - clen = len; - - off = va - trunc_page(va); - if (pmap_extract(pm, trunc_page(va), &pa)) { - pmap_kenter_pa(kva, pa, PROT_READ|PROT_WRITE); - cpu_icache_sync_range(kva + off, clen); - pmap_kremove_pg(kva); - } - - len -= clen; - va += clen; - } + fence_i(); } void @@ -1715,7 +1675,7 @@ 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 = 0; + int need_sync; int retcode = 0; pmap_lock(pm); @@ -1805,7 +1765,7 @@ pmap_fault_fixup(pmap_t pm, vaddr_t va, vm_prot_t ftype) need_sync = ((pg->pg_flags & PG_PMAP_EXE) == 0); atomic_setbits_int(&pg->pg_flags, PG_PMAP_EXE); if (need_sync) - cpu_icache_sync_range(va & ~PAGE_MASK, PAGE_SIZE); + fence_i(); } retcode = 1;