Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/usermode/usermode Implement TBL functionality by re...
details: https://anonhg.NetBSD.org/src/rev/a3f7eb3b9beb
branches: trunk
changeset: 769418:a3f7eb3b9beb
user: reinoud <reinoud%NetBSD.org@localhost>
date: Fri Sep 09 12:28:05 2011 +0000
description:
Implement TBL functionality by remembering if its mapped in or not before
guessing and adjusting access types.
While here, when we hit a read-access fault and reference the page, also mark
it for executable when its permissions permit it. Distinguising between the
two is neigh impossible as we need to guess/derive the access the process
tried to have to the memory: we dont know if its a read/write/exec try.
Also clean up some debug messages.
diffstat:
sys/arch/usermode/usermode/pmap.c | 41 +++++++++++++++++++++++++++++---------
1 files changed, 31 insertions(+), 10 deletions(-)
diffs (120 lines):
diff -r 8dc51a592537 -r a3f7eb3b9beb sys/arch/usermode/usermode/pmap.c
--- a/sys/arch/usermode/usermode/pmap.c Fri Sep 09 12:21:57 2011 +0000
+++ b/sys/arch/usermode/usermode/pmap.c Fri Sep 09 12:28:05 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.57 2011/09/06 09:37:41 reinoud Exp $ */
+/* $NetBSD: pmap.c,v 1.58 2011/09/09 12:28:05 reinoud Exp $ */
/*-
* Copyright (c) 2011 Reinoud Zandijk <reinoud%NetBSD.org@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.57 2011/09/06 09:37:41 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.58 2011/09/09 12:28:05 reinoud Exp $");
#include "opt_memsize.h"
#include "opt_kmempages.h"
@@ -52,11 +52,13 @@
uint8_t pv_vflags; /* per mapping flags */
#define PV_WIRED 0x01 /* wired mapping */
#define PV_UNMANAGED 0x02 /* entered by pmap_kenter_ */
+#define PV_MAPPEDIN 0x04 /* is actually mapped */
uint8_t pv_pflags; /* per phys page flags */
#define PV_REFERENCED 0x01
#define PV_MODIFIED 0x02
};
+
/* this is a guesstimate of 16KB/process on amd64, or around 680+ mappings */
#define PM_MIN_NENTRIES ((int) (16*1024 / sizeof(pv_entry)))
struct pmap {
@@ -484,7 +486,7 @@
/* not known! then it must be UVM's work */
if (pv == NULL) {
-aprint_debug("no mapping yet\n");
+ aprint_debug("%s: no mapping yet\n", __func__);
*atype = VM_PROT_READ; /* assume it was a read */
return false;
}
@@ -502,6 +504,16 @@
return true;
}
+ /* if its not mapped in, we have a TBL fault */
+ if ((pv->pv_vflags & PV_MAPPEDIN) == 0) {
+ if (pv->pv_mmap_ppl != THUNK_PROT_NONE) {
+ printf("%s: tlb fault page lpn %"PRIiPTR"\n", __func__,
+ pv->pv_lpn);
+ pmap_page_activate(pv);
+ return true;
+ }
+ }
+
/* determine pmap access type (mmap doesnt need to be 1:1 on VM_PROT_) */
prot = pv->pv_prot;
cur_prot = VM_PROT_NONE;
@@ -514,7 +526,8 @@
diff = prot & (prot ^ cur_prot);
-aprint_debug("prot = %d, cur_prot = %d, diff = %d\n", prot, cur_prot, diff);
+ aprint_debug("%s: prot = %d, cur_prot = %d, diff = %d\n",
+ __func__, prot, cur_prot, diff);
*atype = VM_PROT_READ; /* assume its a read error */
if (diff & VM_PROT_READ) {
if ((ppv->pv_pflags & PV_REFERENCED) == 0) {
@@ -543,9 +556,9 @@
*atype = VM_PROT_WRITE; /* assume its a write error */
if (diff & VM_PROT_WRITE) {
if (prot & VM_PROT_WRITE) {
-aprint_debug("should be allowed to write\n");
+ /* should be allowed to write */
if ((ppv->pv_pflags & PV_MODIFIED) == 0) {
-aprint_debug("was marked unmodified\n");
+ /* was marked unmodified */
ppv->pv_pflags |= PV_MODIFIED;
pmap_update_page(ppn);
return true;
@@ -574,6 +587,10 @@
if (addr != (void *) va)
panic("pmap_page_activate: mmap failed (expected %p got %p): %d",
(void *)va, addr, thunk_geterrno());
+
+ pv->pv_vflags &= ~PV_MAPPEDIN;
+ if (pv->pv_mmap_ppl != THUNK_PROT_NONE)
+ pv->pv_vflags |= PV_MAPPEDIN;
}
static void
@@ -590,6 +607,7 @@
(void *) va, (void *) pa, pv->pv_mmap_ppl, (void *) addr);
if (addr != (void *) va)
panic("pmap_page_deactivate: mmap failed");
+ pv->pv_vflags &= ~PV_MAPPEDIN;
}
static void
@@ -608,13 +626,16 @@
/* create referenced/modified emulation */
if ((pv->pv_prot & VM_PROT_WRITE) &&
- (pflags & PV_REFERENCED) && (pflags & PV_MODIFIED))
+ (pflags & PV_REFERENCED) && (pflags & PV_MODIFIED)) {
mmap_ppl = THUNK_PROT_READ | THUNK_PROT_WRITE;
- else if ((pv->pv_prot & (VM_PROT_READ | VM_PROT_EXECUTE)) &&
- (pflags & PV_REFERENCED))
+ } else if ((pv->pv_prot & (VM_PROT_READ | VM_PROT_EXECUTE)) &&
+ (pflags & PV_REFERENCED)) {
mmap_ppl = THUNK_PROT_READ;
- else
+ if (pv->pv_prot & VM_PROT_EXECUTE)
+ mmap_ppl |= THUNK_PROT_EXEC;
+ } else {
mmap_ppl = THUNK_PROT_NONE;
+ }
/* unmanaged pages are special; they dont track r/m */
if (vflags & PV_UNMANAGED)
Home |
Main Index |
Thread Index |
Old Index