diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-10-27 12:45:33 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-10-27 12:45:33 +0000 |
commit | 22bb604dee9e0d458d1053c6d2d38dd80ef4bb25 (patch) | |
tree | 4b205c7943d5f5e019498d6a45923b0d732a8afb /sys/arch | |
parent | a1598a19768debd07b6554921d3ba574843724a2 (diff) |
Flush cache before mapping a page as uncached. The CPU gets really upset
without this. The machine reboots and the core we were running on will
be deconfigured.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/powerpc64/powerpc64/pmap.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/sys/arch/powerpc64/powerpc64/pmap.c b/sys/arch/powerpc64/powerpc64/pmap.c index 16c2ce61f59..895e4c450a4 100644 --- a/sys/arch/powerpc64/powerpc64/pmap.c +++ b/sys/arch/powerpc64/powerpc64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.53 2020/10/26 20:59:41 kettenis Exp $ */ +/* $OpenBSD: pmap.c,v 1.54 2020/10/27 12:45:32 kettenis Exp $ */ /* * Copyright (c) 2015 Martin Pieuchot @@ -145,6 +145,7 @@ struct pte_desc { #define PTED_VA_EXEC_M 0x40 void pmap_pted_syncicache(struct pte_desc *); +void pmap_flush_page(struct vm_page *); struct slb_desc { LIST_ENTRY(slb_desc) slbd_list; @@ -1077,6 +1078,9 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags) atomic_setbits_int(&pg->pg_flags, PG_PMAP_REF); if (flags & PROT_WRITE) atomic_setbits_int(&pg->pg_flags, PG_PMAP_MOD); + + if ((pg->pg_flags & PG_DEV) == 0 && cache != PMAP_CACHE_WB) + pmap_flush_page(pg); } pte_insert(pted); @@ -1441,6 +1445,19 @@ pmap_zero_page(struct vm_page *pg) } void +pmap_flush_page(struct vm_page *pg) +{ + paddr_t pa = VM_PAGE_TO_PHYS(pg); + paddr_t va = zero_page + cpu_number() * PAGE_SIZE; + int offset; + + pmap_kenter_pa(va, pa, PROT_READ | PROT_WRITE); + for (offset = 0; offset < PAGE_SIZE; offset += cacheline_size) + __asm volatile ("dcbf 0, %0" :: "r"(va + offset)); + pmap_kremove(va, PAGE_SIZE); +} + +void pmap_copy_page(struct vm_page *srcpg, struct vm_page *dstpg) { paddr_t srcpa = VM_PAGE_TO_PHYS(srcpg); |