]> Zhao Yanbai Git Server - minix.git/commitdiff
further messing with page fault handling
authorBen Gras <ben@minix3.org>
Fri, 29 May 2009 18:47:31 +0000 (18:47 +0000)
committerBen Gras <ben@minix3.org>
Fri, 29 May 2009 18:47:31 +0000 (18:47 +0000)
kernel/arch/i386/exception.c
kernel/arch/i386/memory.c
kernel/arch/i386/mpx386.s
kernel/arch/i386/proto.h
kernel/proc.c
kernel/system/do_vmctl.c
servers/vm/i386/vm.c

index 0e137755df5caa57cc32662c65dab2a3d30d8550..b28d7d03b85d181133f8405737c565434100a22b 100755 (executable)
@@ -18,32 +18,48 @@ extern u32_t vm_copy_from_p, vm_copy_to_p, vm_copy_cr3;
 extern u32_t catchrange_lo, catchrange_hi;
 
 u32_t pagefault_cr2, pagefault_count = 0;
+vir_bytes *old_eip_ptr = NULL, *old_eax_ptr = NULL;
 
-void pagefault(struct proc *pr, int trap_errno)
+void pagefault(vir_bytes old_eip, struct proc *pr, int trap_errno)
 {
        int s;
        vir_bytes ph;
        u32_t pte;
+       int procok = 0, pcok = 0, rangeok = 0;
+
+       vmassert(old_eip_ptr);
+       vmassert(old_eax_ptr);
+
+       vmassert(*old_eip_ptr == old_eip);
+       vmassert(old_eip_ptr != &old_eip);
 
        vmassert(pagefault_count == 1);
 
-       if((iskernelp(pr) || k_reenter) && catch_pagefaults
-               && (pr->p_reg.pc > (vir_bytes) _memcpy_k &&
-                  pr->p_reg.pc < (vir_bytes) _memcpy_k_fault) &&
-                  pagefault_cr2 >= catchrange_lo &&
-                  pagefault_cr2 < catchrange_hi) {
-               kprintf("handling pagefault during copy\n");
-               pr->p_reg.pc = (vir_bytes) _memcpy_k_fault;
-               pr->p_reg.retreg = pagefault_cr2;
-               pagefault_count = 0;
-               return;
+       if(catch_pagefaults &&
+               (rangeok = (pagefault_cr2 >= catchrange_lo &&
+                  pagefault_cr2 < catchrange_hi))) {
+               vir_bytes test_eip;
+               test_eip = k_reenter ? old_eip : pr->p_reg.pc;
+               if((pcok = ((test_eip > (vir_bytes) _memcpy_k) &&
+                  (test_eip < (vir_bytes) _memcpy_k_fault)))) {
+                       kprintf("handling pagefault during copy\n");
+                       pagefault_count = 0;
+
+                       *old_eip_ptr = _memcpy_k_fault;
+                       *old_eax_ptr = pagefault_cr2;
+
+                       return;
+               }
        }
 
-       proc_stacktrace(pr);
+       kprintf("kernel stacktrace in pagefault: "); 
+       util_stacktrace();
 
        if(catch_pagefaults) {
-               printf("k_reenter: %d addr: 0x%lx range: 0x%lx-0x%lx\n",
-                       k_reenter, pagefault_cr2, catchrange_lo, catchrange_hi);
+               kprintf("procok: %d pcok: %d rangeok: %d\n",
+                       procok, pcok, rangeok);
+               printf("k_reenter: %d addr: 0x%lx range: 0x%lx-0x%lx pc: 0x%lx\n",
+                       k_reenter, pagefault_cr2, catchrange_lo, catchrange_hi, pr->p_reg.pc);
        }
 
        /* System processes that don't have their own page table can't
@@ -150,7 +166,7 @@ struct proc *t;
   }
 
   if(vec_nr == PAGE_FAULT_VECTOR) {
-               pagefault(saved_proc, trap_errno);
+               pagefault(old_eip, saved_proc, trap_errno);
                return;
   }
 
@@ -214,7 +230,7 @@ PUBLIC void proc_stacktrace(struct proc *proc)
        while(v_bp) {
 
 #define PRCOPY(pr, pv, v, n) \
-  (iskernelp(pr) ? (memcpy(v, pv, n), OK) : \
+  (iskernelp(pr) ? (memcpy((char *) v, (char *) pv, n), OK) : \
      data_copy(pr->p_endpoint, pv, SYSTEM, (vir_bytes) (v), n))
 
                if(PRCOPY(proc, v_bp, &v_hbp, sizeof(v_hbp)) != OK) {
index c747932d6a40a1d9f7c44bca101fcc7dd8ebc809..ea725e3a7faca0367924122b5af82a6b27df57de 100644 (file)
@@ -723,7 +723,6 @@ u32_t read_cr3(void)
                                kprintf("kernel: pde %d 0x%lx for proc %d\n", \
                                        pde_index, pdeval, PROC->p_endpoint); \
                        }                                               \
-                       if(copyverbose) { kprintf("installing pde val 0x%lx from pde index %d of proc %d into my pde\n", pdeval, pde_index, PROC->p_endpoint); }        \
                } else {                                                \
                        pdeval = (LINADDR & I386_VM_ADDR_MASK_4MB) |    \
                                I386_VM_BIGPAGE | I386_VM_PRESENT |     \
@@ -745,7 +744,7 @@ int lin_lin_copy(struct proc *srcproc, vir_bytes srclinaddr, u8_t *vsrc,
        int srcseg,
        struct proc *dstproc, vir_bytes dstlinaddr, u8_t *vdst,
        int dstseg,
-       vir_bytes bytes, int copyverbose)
+       vir_bytes bytes)
 {
        u32_t addr;
        int procslot;
@@ -780,8 +779,6 @@ int lin_lin_copy(struct proc *srcproc, vir_bytes srclinaddr, u8_t *vsrc,
                vir_bytes srcoffset, dstoffset;
                vir_bytes chunk = bytes;
 
-               FIXME("copyverbose");
-
                /* Set up 4MB ranges. */
                CREATEPDE(srcproc, srcptr, srclinaddr, srcoffset,
                        freepdes[FREEPDE_SRC], vsrc, srcseg, chunk, bytes);
@@ -850,7 +847,6 @@ int vm_phys_memset(phys_bytes ph, u8_t c, phys_bytes bytes)
                vir_bytes chunk = bytes;
                u8_t *ptr;
                u32_t offset;
-               int copyverbose = 0;
                CREATEPDE(((struct proc *) NULL), ptr, ph,
                        offset, freepdes[FREEPDE_MEMSET], 0, 0, chunk, bytes);
                /* We can memset as many bytes as we have remaining,
@@ -957,20 +953,11 @@ int vmcheck;                      /* if nonzero, can return VMSUSPEND */
   if(vm_running) {
        int r;
        struct proc *target, *caller;
-       int verbose = 0;
-
-               if(procs[_SRC_] && procs[_DST_] && 
-                 procs[_SRC_]->p_endpoint == PM_PROC_NR &&
-                 (procs[_DST_]->p_endpoint == INIT_PROC_NR ||
-                 procs[_DST_]->p_endpoint == 35549) &&
-                 bytes == sizeof(message)) {
-                       verbose = 1;
-               }
 
        if((r=lin_lin_copy(procs[_SRC_], phys_addr[_SRC_],
                 (u8_t *) src_addr->offset, src_addr->segment,
                procs[_DST_], phys_addr[_DST_], (u8_t *) dst_addr->offset,
-               dst_addr->segment, bytes, verbose)) != OK) {
+               dst_addr->segment, bytes)) != OK) {
                if(r != EFAULT_SRC && r != EFAULT_DST)
                        minix_panic("lin_lin_copy failed", r);
                if(!vmcheck) {
@@ -1002,17 +989,6 @@ int vmcheck;                      /* if nonzero, can return VMSUSPEND */
                NOREC_RETURN(virtualcopy, VMSUSPEND);
        }
 
-       if(verbose) {
-               static int count = 0;
-               message *m;
-               kprintf("lin_lin_copy: PM to %d: %d bytes copy OK\n",
-                       procs[_DST_]->p_endpoint, bytes);
-               if(count++ < 10) {
-                       vm_print(procs[_SRC_]->p_seg.p_cr3);
-                       vm_print(procs[_DST_]->p_seg.p_cr3);
-               }
-       }
-
        NOREC_RETURN(virtualcopy, OK);
   }
 
index 844d93d87b3d8131f91853989a8bce9aec809a5a..61b849c8d08cacffc8396db50316508dac199985 100755 (executable)
@@ -76,6 +76,8 @@ begbss:
 .define        save
 .define        _pagefault_cr2
 .define _pagefault_count
+.define _old_eip_ptr
+.define _old_eax_ptr
 
 .define errexception
 .define exception1
@@ -524,10 +526,16 @@ errexception:
  sseg  pop     (ex_number)
  sseg  pop     (trap_errno)
 exception1:                            ! Common for all exceptions.
+ sseg  mov     (_old_eax_ptr), esp     ! where will eax be saved?
+ sseg  sub     (_old_eax_ptr), PCREG-AXREG     ! here
+
        push    eax                     ! eax is scratch register
 
        mov     eax, 0+4(esp)           ! old eip
  sseg  mov     (old_eip), eax
+       mov     eax, esp
+       add     eax, 4
+ sseg  mov     (_old_eip_ptr), eax
        movzx   eax, 4+4(esp)           ! old cs
  sseg  mov     (old_cs), eax
        mov     eax, 8+4(esp)           ! old eflags
index ccb90ff86db862be37baf4a575b31b653c513028..3c9a0f36a4716f9c60ec44dfb24a1bcaabf61cdd 100644 (file)
@@ -76,6 +76,7 @@ _PROTOTYPE( void phys_outsw, (U16_t port, phys_bytes buf, size_t count) );
 _PROTOTYPE( void i386_invlpg_level0, (void) );
 _PROTOTYPE( int _memcpy_k, (void *dst, void *src, size_t n) );
 _PROTOTYPE( int _memcpy_k_fault, (void) );
+_PROTOTYPE( u32_t read_cr3, (void) );
 
 /* protect.c */
 _PROTOTYPE( void prot_init, (void)                                             );
index 02b1ade1d788831743a1e1a351d78e130168e0da..2fee24eaccfa618c6649636275cf53a02acfcde8 100755 (executable)
@@ -87,17 +87,17 @@ FORWARD _PROTOTYPE( void pick_proc, (void));
                        kprintf("error %d\n", r);       \
                  minix_panic("CopyMess: copy error", __LINE__); \
                 } \
-               vm_suspend(dp, dp);                             \
+               minix_panic("parameters unknown", NO_NUM);      \
                (dp)->p_vmrequest.saved.msgcopy.dst = (dp);     \
                (dp)->p_vmrequest.saved.msgcopy.dst_v = (vir_bytes) dm; \
+               (dp)->p_vmrequest.saved.msgcopy.msgbuf.m_source = e; \
+               (dp)->p_vmrequest.type = VMSTYPE_MSGCOPY; \
                if(data_copy((sp)->p_endpoint,  \
                        (vir_bytes) (sm), SYSTEM,       \
                        (vir_bytes) &(dp)->p_vmrequest.saved.msgcopy.msgbuf, \
                        sizeof(message)) != OK) {               \
                                minix_panic("CopyMess: data_copy failed", __LINE__);\
                        }                               \
-                       (dp)->p_vmrequest.saved.msgcopy.msgbuf.m_source = e; \
-                       (dp)->p_vmrequest.type = VMSTYPE_MSGCOPY; \
        }
 
 #define CopyMess(s,sp,sm,dp,dm) do {                   \
index 9fa261827042f249ae14f71c5c06d8e594e3e2e1..fa2a30dfc35b8a07fba98d05bc810aeb0a979875 100644 (file)
@@ -43,8 +43,11 @@ register message *m_ptr;     /* pointer to request message */
                if(!RTS_ISSET(rp, VMREQUEST))
                        minix_panic("do_vmctl: no VMREQUEST set", NO_NUM);
 
-               printf("kernel: vm request sent by: %s / %d about %d\n",
-                       rp->p_name, rp->p_endpoint, rp->p_vmrequest.who);
+               printf("kernel: vm request sent by: %s / %d about %d; 0x%lx-0x%lx, wr %d\n",
+                       rp->p_name, rp->p_endpoint, rp->p_vmrequest.who,
+                       rp->p_vmrequest.start,
+                       rp->p_vmrequest.start + rp->p_vmrequest.length,
+                       rp->p_vmrequest.writeflag);
 
                /* Reply with request fields. */
                m_ptr->SVMCTL_MRG_ADDR = (char *) rp->p_vmrequest.start;
index 43d6db1c37712f507b5fdd64fd1fd4ffa4c5c5d8..6ff14ddb3a1b4a0a7ec310e52ae04753c3541112 100644 (file)
  *===========================================================================*/
 PUBLIC vir_bytes arch_map2vir(struct vmproc *vmp, vir_bytes addr)
 {
-       vir_bytes bottom = CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys);
+       vir_bytes textstart = CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_phys);
+       vir_bytes datastart = CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys);
 
-       vm_assert(bottom <= addr);
+       /* Could be a text address. */
+       vm_assert(datastart <= addr || textstart <= addr);
 
-       return addr - bottom;
+       return addr - datastart;
 }
 
 /*===========================================================================*