Module Name:    src
Committed By:   jym
Date:           Mon May  7 02:32:09 UTC 2012

Modified Files:
        src/sys/arch/i386/i386: db_memrw.c

Log Message:
Use pmap_pte_*bits macros to set/clear bits in a PTE. Remove pmap_pte_flush
calls as these operations are synchronously flushed under Xen; they should
not be cached.

XXX the code can be shared between i386 and amd64, but I will merge
them once I figure out why db_write_text() can cause page faults for
certain CPUs in long mode (code looks correct, but single stepping or
adding debug printf's makes the bug magically disappear... sigh)

Bug reported by David Laight on port-amd64@ when attempting to set
breakpoints through ddb(4).


To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 src/sys/arch/i386/i386/db_memrw.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/i386/i386/db_memrw.c
diff -u src/sys/arch/i386/i386/db_memrw.c:1.27 src/sys/arch/i386/i386/db_memrw.c:1.28
--- src/sys/arch/i386/i386/db_memrw.c:1.27	Mon May  7 02:15:34 2012
+++ src/sys/arch/i386/i386/db_memrw.c	Mon May  7 02:32:09 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: db_memrw.c,v 1.27 2012/05/07 02:15:34 jym Exp $	*/
+/*	$NetBSD: db_memrw.c,v 1.28 2012/05/07 02:32:09 jym Exp $	*/
 
 /*-
  * Copyright (c) 1996, 2000 The NetBSD Foundation, Inc.
@@ -49,7 +49,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_memrw.c,v 1.27 2012/05/07 02:15:34 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_memrw.c,v 1.28 2012/05/07 02:32:09 jym Exp $");
 
 #include "opt_xen.h"
 
@@ -97,7 +97,7 @@ db_read_bytes(vaddr_t addr, size_t size,
 static void
 db_write_text(vaddr_t addr, size_t size, const char *data)
 {
-	pt_entry_t *pte, oldpte, tmppte;
+	pt_entry_t *ppte, pte;
 	vaddr_t pgva;
 	size_t limit;
 	char *dst;
@@ -111,10 +111,10 @@ db_write_text(vaddr_t addr, size_t size,
 		/*
 		 * Get the PTE for the page.
 		 */
-		pte = kvtopte(addr);
-		oldpte = *pte;
+		ppte = kvtopte(addr);
+		pte = *ppte;
 
-		if ((oldpte & PG_V) == 0) {
+		if ((pte & PG_V) == 0) {
 			printf(" address %p not a valid page\n", dst);
 			return;
 		}
@@ -122,7 +122,7 @@ db_write_text(vaddr_t addr, size_t size,
 		/*
 		 * Get the VA for the page.
 		 */
-		if (oldpte & PG_PS)
+		if (pte & PG_PS)
 			pgva = (vaddr_t)dst & PG_LGFRAME;
 		else
 			pgva = x86_trunc_page((vaddr_t)dst);
@@ -132,7 +132,7 @@ db_write_text(vaddr_t addr, size_t size,
 		 * with this mapping and subtract it from the
 		 * total size.
 		 */
-		if (oldpte & PG_PS)
+		if (pte & PG_PS)
 			limit = NBPD_L2 - ((vaddr_t)dst & (NBPD_L2 - 1));
 		else
 			limit = PAGE_SIZE - ((vaddr_t)dst & PGOFSET);
@@ -140,9 +140,11 @@ db_write_text(vaddr_t addr, size_t size,
 			limit = size;
 		size -= limit;
 
-		tmppte = (oldpte & ~PG_KR) | PG_KW;
-		pmap_pte_set(pte, tmppte);
-		pmap_pte_flush();
+		/*
+		 * Make the kernel text page writable.
+		 */
+		pmap_pte_clearbits(ppte, PG_KR);
+		pmap_pte_setbits(ppte, PG_KW);
 		pmap_update_pg(pgva);
 		/*
 		 * MULTIPROCESSOR: no shootdown required as the PTE continues to
@@ -157,10 +159,10 @@ db_write_text(vaddr_t addr, size_t size,
 			*dst++ = *data++;
 
 		/*
-		 * Restore the old PTE.
+		 * Turn the page back to read-only.
 		 */
-		pmap_pte_set(pte, oldpte);
-		pmap_pte_flush();
+		pmap_pte_clearbits(ppte, PG_KW);
+		pmap_pte_setbits(ppte, PG_KR);
 		pmap_update_pg(pgva);
 		/*
 		 * MULTIPROCESSOR: no shootdown required as all other CPUs

Reply via email to