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