Module Name:    src
Committed By:   rin
Date:           Thu Sep 10 04:31:55 UTC 2020

Modified Files:
        src/sys/arch/powerpc/ibm4xx: pmap.c

Log Message:
Real fix for pmap_procwr(), attempted in revs 1.85 and 1.87:
http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/arch/powerpc/ibm4xx/pmap.c#rev1.85
http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/arch/powerpc/ibm4xx/pmap.c#rev1.87

ibm4xx has VIPT icache and operations in pmap_procwr() should be done with
DMMU enabled (write back dcache into memory and invalidate icache).

When p == curproc, this is trivial. However, p != curproc needs a special
care; we cannot rely upon TLB miss handler in user context. Therefore,
extract pa and operate against it.

Note that va below VM_MIN_KERNEL_ADDRESS (== 2GB at the moment) is reserved
for direct mapping.

Tested by gdb with WIP software single stepping for ibm4xx.


To generate a diff of this commit:
cvs rdiff -u -r1.93 -r1.94 src/sys/arch/powerpc/ibm4xx/pmap.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/powerpc/ibm4xx/pmap.c
diff -u src/sys/arch/powerpc/ibm4xx/pmap.c:1.93 src/sys/arch/powerpc/ibm4xx/pmap.c:1.94
--- src/sys/arch/powerpc/ibm4xx/pmap.c:1.93	Thu Sep 10 03:32:46 2020
+++ src/sys/arch/powerpc/ibm4xx/pmap.c	Thu Sep 10 04:31:55 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.93 2020/09/10 03:32:46 rin Exp $	*/
+/*	$NetBSD: pmap.c,v 1.94 2020/09/10 04:31:55 rin Exp $	*/
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.93 2020/09/10 03:32:46 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.94 2020/09/10 04:31:55 rin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -1160,42 +1160,72 @@ pmap_deactivate(struct lwp *l)
 void
 pmap_procwr(struct proc *p, vaddr_t va, size_t len)
 {
-	struct pmap *pm = p->p_vmspace->vm_map.pmap;
-	int msr, ctx, opid, step;
 
-	step = CACHELINESIZE;
+	if (__predict_true(p == curproc)) {
+		struct pmap *pm = p->p_vmspace->vm_map.pmap;
+		int msr, ctx, opid;
 
-	/*
-	 * Need to turn off IMMU and switch to user context.
-	 * (icbi uses DMMU).
-	 */
-	if (!(ctx = pm->pm_ctx)) {
-		/* No context -- assign it one */
-		ctx_alloc(pm);
-		ctx = pm->pm_ctx;
-	}
-	__asm volatile(
-		"mfmsr %0;"
-		"li %1, %7;"
-		"andc %1,%0,%1;"
-		"mtmsr %1;"
-		"isync;"
-		"mfpid %1;"
-		"mtpid %2;"
-		"isync;"
+		/*
+		 * Take it easy! TLB miss handler takes care of us.
+		 */
+
+		/*
+	 	 * Need to turn off IMMU and switch to user context.
+		 * (icbi uses DMMU).
+		 */
+
+		if (!(ctx = pm->pm_ctx)) {
+			/* No context -- assign it one */
+			ctx_alloc(pm);
+			ctx = pm->pm_ctx;
+		}
+
+		__asm volatile(
+			"mfmsr %0;"
+			"li %1,0x20;"		/* Turn off IMMU */
+			"andc %1,%0,%1;"
+			"ori %1,%1,0x10;"	/* Turn on DMMU for sure */
+			"mtmsr %1;"
+			"isync;"
+			"mfpid %1;"
+			"mtpid %2;"
+			"isync;"
 		"1:"
-		"dcbst 0,%3;"
-		"icbi 0,%3;"
-		"add %3,%3,%5;"
-		"addc. %4,%4,%6;"
-		"bge 1b;"
-		"sync;"
-		"mtpid %1;"
-		"mtmsr %0;"
-		"isync;"
-		: "=&r" (msr), "=&r" (opid)
-		: "r" (ctx), "r" (va), "r" (len), "r" (step), "r" (-step),
-		  "K" (PSL_IR | PSL_DR));
+			"dcbst 0,%3;"
+			"icbi 0,%3;"
+			"add %3,%3,%5;"
+			"sub. %4,%4,%5;"
+			"bge 1b;"
+			"sync;"
+			"mtpid %1;"
+			"mtmsr %0;"
+			"isync;"
+			: "=&r" (msr), "=&r" (opid)
+			: "r" (ctx), "r" (va), "r" (len), "r" (CACHELINESIZE));
+	} else {
+		struct pmap *pm = p->p_vmspace->vm_map.pmap;
+		paddr_t pa;
+		vaddr_t tva, eva;
+		int tlen;
+
+		/*
+		 * For p != curproc, we cannot rely upon TLB miss handler in
+		 * user context. Therefore, extract pa and operate againt it.
+		 *
+		 * Note that va below VM_MIN_KERNEL_ADDRESS is reserved for
+		 * direct mapping.
+		 */
+
+		for (tva = va; len > 0; tva = eva, len -= tlen) {
+			eva = uimin(tva + len, trunc_page(tva + PAGE_SIZE));
+			tlen = eva - tva;
+			if (!pmap_extract(pm, tva, &pa)) {
+				/* XXX should be already unmapped */
+				continue;
+			}
+			__syncicache((void *)pa, tlen);
+		}
+	}
 }
 
 static inline void

Reply via email to