summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2020-10-27 12:45:33 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2020-10-27 12:45:33 +0000
commit22bb604dee9e0d458d1053c6d2d38dd80ef4bb25 (patch)
tree4b205c7943d5f5e019498d6a45923b0d732a8afb /sys/arch
parenta1598a19768debd07b6554921d3ba574843724a2 (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.c19
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);