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 read and modify detecti...



details:   https://anonhg.NetBSD.org/src/rev/bc2fd880a7a3
branches:  trunk
changeset: 768969:bc2fd880a7a3
user:      reinoud <reinoud%NetBSD.org@localhost>
date:      Mon Aug 29 14:59:09 2011 +0000

description:
Implement read and modify detection code

diffstat:

 sys/arch/usermode/usermode/pmap.c |  43 +++++++++++++++++++++++++++-
 sys/arch/usermode/usermode/trap.c |  59 +++++++++++++++++++++++++++-----------
 2 files changed, 83 insertions(+), 19 deletions(-)

diffs (189 lines):

diff -r 72a7f1f0b101 -r bc2fd880a7a3 sys/arch/usermode/usermode/pmap.c
--- a/sys/arch/usermode/usermode/pmap.c Mon Aug 29 14:51:17 2011 +0000
+++ b/sys/arch/usermode/usermode/pmap.c Mon Aug 29 14:59:09 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.38 2011/08/27 17:59:24 reinoud Exp $ */
+/* $NetBSD: pmap.c,v 1.39 2011/08/29 14:59:09 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.38 2011/08/27 17:59:24 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.39 2011/08/29 14:59:09 reinoud Exp $");
 
 #include "opt_memsize.h"
 #include "opt_kmempages.h"
@@ -90,6 +90,8 @@
 static void    pv_update(struct pv_entry *pv);
 static void    pmap_update_page(uintptr_t ppn);
 
+void pmap_get_current_protection(pmap_t pmap, vaddr_t va,
+       vm_prot_t *cur_prot, vm_prot_t *prot);
 static struct  pv_entry *pv_get(pmap_t pmap, uintptr_t ppn, uintptr_t lpn);
 static struct  pv_entry *pv_alloc(void);
 static void    pv_free(struct pv_entry *pv);
@@ -421,6 +423,39 @@
        return pv;
 }
 
+void
+pmap_get_current_protection(pmap_t pmap, vaddr_t va,
+       vm_prot_t *cur_prot, vm_prot_t *prot)
+{
+       struct pv_entry *pv;
+
+       uintptr_t lpn;
+
+       aprint_debug("pmap_get_current_protection pmap %p, va %p\n", pmap, (void *) va);
+#ifdef DIAGNOSTIC
+       if ((va < VM_MIN_ADDRESS) || (va >= VM_MAX_ADDRESS))
+               panic("pmap_do_enter: invalid va isued\n");
+#endif
+
+       lpn = atop(va - VM_MIN_ADDRESS);        /* V->L */
+
+       /* raise interupt level */
+       pv = pmap->pm_entries[lpn];
+       if (pv == NULL) {
+               *cur_prot = *prot = VM_PROT_NONE;
+               return;
+       }
+
+       *prot = pv->pv_prot;
+       *cur_prot = VM_PROT_NONE;
+       if (pv->pv_mmap_ppl & PROT_READ)
+               *cur_prot |= VM_PROT_READ;
+       if (pv->pv_mmap_ppl & PROT_WRITE)
+               *cur_prot |= VM_PROT_WRITE;
+       if (pv->pv_mmap_ppl & PROT_EXEC)
+               *cur_prot |= VM_PROT_EXECUTE;
+}
+
 static void
 pmap_page_activate(struct pv_entry *pv)
 {
@@ -660,6 +695,10 @@
 
        /* TODO protect against roque values */
        aprint_debug("pmap_extract: extracting va %p\n", (void *) va);
+#ifdef DIAGNOSTIC
+       if ((va < VM_MIN_ADDRESS) || (va > VM_MAX_ADDRESS))
+               panic("pmap_extract: invalid va isued\n");
+#endif
        pv = pmap->pm_entries[atop(va - VM_MIN_ADDRESS)]; /* V->L */
 
        if (pv == NULL)
diff -r 72a7f1f0b101 -r bc2fd880a7a3 sys/arch/usermode/usermode/trap.c
--- a/sys/arch/usermode/usermode/trap.c Mon Aug 29 14:51:17 2011 +0000
+++ b/sys/arch/usermode/usermode/trap.c Mon Aug 29 14:59:09 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.12 2011/08/29 13:15:54 jmcneill Exp $ */
+/* $NetBSD: trap.c,v 1.13 2011/08/29 14:59:09 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2011 Reinoud Zandijk <reinoud%netbsd.org@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.12 2011/08/29 13:15:54 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.13 2011/08/29 14:59:09 reinoud Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -49,11 +49,12 @@
 //#include <machine/userret.h>
 
 
+/* forwards and externals */
 void setup_signal_handlers(void);
 static void mem_access_handler(int sig, siginfo_t *info, void *ctx);
 
-
-static struct sigaction sa;
+extern void pmap_get_current_protection(pmap_t pmap, vaddr_t va,
+       vm_prot_t *cur_prot, vm_prot_t *prot);
 extern int errno;
 
 void
@@ -64,6 +65,8 @@
 void
 setup_signal_handlers(void)
 {
+       static struct sigaction sa;
+
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = SA_RESTART | SA_SIGINFO;
        sa.sa_sigaction = mem_access_handler;
@@ -84,7 +87,7 @@
        struct vmspace *vm;
        struct vm_map *vm_map;
        struct trapframe *tf;
-       vm_prot_t atype;
+       vm_prot_t cur_prot, prot, atype;
        vaddr_t va;
        vaddr_t onfault;
        int kmem, rv;
@@ -104,7 +107,7 @@
                onfault = (vaddr_t) pcb->pcb_onfault;
                vm = p->p_vmspace;
 
-#if 0
+#if 1
                printf("SIGSEGV or SIGBUS!\n");
                printf("\tsi_signo = %d\n", info->si_signo);
                printf("\tsi_errno = %d\n", info->si_errno);
@@ -141,17 +144,39 @@
                        panic("peeing outside the box!");
                }
 
-               /* XXX TODO determine atype?? */
-atype = PROT_READ;
-again:
-               pcb->pcb_onfault = NULL;
-               rv = uvm_fault(vm_map, (vaddr_t) va, atype);
-               pcb->pcb_onfault = (void *) onfault;
-if (rv) printf("uvm_fault rv = %d\n", rv);
-if (rv == EACCES) {
-       atype |= PROT_WRITE | PROT_EXEC;
-       goto again;
-}
+               /* determine accesstype */
+               pmap_get_current_protection(vm_map->pmap, va, &cur_prot, &prot);
+               rv = 0;
+               if ((prot == VM_PROT_NONE) && (cur_prot == VM_PROT_NONE)) {
+                       /* not mapped in yet */
+printf("was not mapped in yet --> faulting read first\n");
+                       pcb->pcb_onfault = NULL;
+                       rv = uvm_fault(vm_map, (vaddr_t) va, VM_PROT_READ);
+                       pcb->pcb_onfault = (void *) onfault;
+
+                       /* update accesstypes */
+                       pmap_get_current_protection(vm_map->pmap, va, &cur_prot, &prot);
+               }
+
+               /* if no error, its map-able */
+               if (rv == 0) {
+                       atype = VM_PROT_NONE;                   /* assume read */
+                       if (prot & PROT_EXEC)
+                               atype |= VM_PROT_EXECUTE;       /* could well be execute */
+                       if ((prot & PROT_WRITE) && (cur_prot & VM_PROT_READ))
+                               atype = VM_PROT_WRITE;  /* if it had write access */
+
+printf("%sva %p, prot = %d, cur_prot = %d ==> atype = %d\n", kmem?"kmem, ":"", (void *) va, prot, cur_prot, atype);
+                       if (atype != VM_PROT_NONE) {
+                               pcb->pcb_onfault = NULL;
+                               rv = uvm_fault(vm_map, (vaddr_t) va, atype);
+                               pcb->pcb_onfault = (void *) onfault;
+                       }
+               }
+
+               if (rv)
+                       aprint_debug("uvm_fault returned error %d\n", rv);
+
                if (rv) {
                        /* something got wrong */
                        if (kmem) {



Home | Main Index | Thread Index | Old Index