]> Zhao Yanbai Git Server - minix.git/commitdiff
more sanity checking. sanity checking disabled by default.
authorBen Gras <ben@minix3.org>
Tue, 12 May 2009 11:35:01 +0000 (11:35 +0000)
committerBen Gras <ben@minix3.org>
Tue, 12 May 2009 11:35:01 +0000 (11:35 +0000)
give every process a full pagetable by default now.

first step to disabling kernel page table code (processes
might not have page tables -> no address translation).

kernel/arch/i386/exception.c
kernel/arch/i386/memory.c
kernel/debug.c
kernel/debug.h
kernel/main.c
kernel/proc.h
kernel/table.c

index 1e5ba042e19b971badde69ce8be0bed2db6a1b3d..2657482deb9276e4eec3fd55e7a8525de18d13fa 100755 (executable)
@@ -36,8 +36,9 @@ void pagefault(struct proc *pr, int trap_errno)
                /* Page fault we can't / don't want to
                 * handle.
                 */
-               kprintf("pagefault for process %d ('%s'), pc = 0x%x\n",
-                       pr->p_endpoint, pr->p_name, pr->p_reg.pc);
+               kprintf("pagefault for process %d ('%s'), pc = 0x%x, addr = 0x%x, flags = 0x%x\n",
+                       pr->p_endpoint, pr->p_name, pr->p_reg.pc,
+                       pagefault_cr2, trap_errno);
                proc_stacktrace(pr);
                minix_panic("page fault in system process", pr->p_endpoint);
 
@@ -78,6 +79,8 @@ u32_t old_eflags;
 {
 /* An exception or unexpected interrupt has occurred. */
 
+struct proc *t;
+
   struct ex_s {
        char *msg;
        int signum;
@@ -105,6 +108,13 @@ u32_t old_eflags;
   register struct ex_s *ep;
   struct proc *saved_proc;
 
+#if DEBUG_SCHED_CHECK
+  for (t = BEG_PROC_ADDR; t < END_PROC_ADDR; ++t) {
+       if(t->p_magic != PMAGIC)
+               kprintf("entry %d broken\n", t->p_nr);
+  }
+#endif
+
   /* Save proc_ptr, because it may be changed by debug statements. */
   saved_proc = proc_ptr;       
 
@@ -115,17 +125,17 @@ u32_t old_eflags;
        return;
   }
 
+  if(vec_nr == PAGE_FAULT_VECTOR) {
+               pagefault(saved_proc, trap_errno);
+               return;
+  }
+
   /* If an exception occurs while running a process, the k_reenter variable 
    * will be zero. Exceptions in interrupt handlers or system traps will make 
    * k_reenter larger than zero.
    */
   if (k_reenter == 0 && ! iskernelp(saved_proc)) {
        {
-               switch(vec_nr) {
-                       case PAGE_FAULT_VECTOR:
-                               pagefault(saved_proc, trap_errno);
-                               return;
-               }
 
                kprintf(
 "exception for process %d, endpoint %d ('%s'), pc = 0x%x:0x%x, sp = 0x%x:0x%x\n",
index 7a3317ab73566a1d1a676d8585928127e94030ce..90be74d8def72bbb15c93ba363b5da8148a67c1b 100644 (file)
@@ -22,6 +22,8 @@ PUBLIC u32_t kernel_cr3;
 extern u32_t cswitch;
 u32_t last_cr3 = 0;
 
+#define HASPT(procptr) ((procptr)->p_seg.p_cr3 != 0)
+
 FORWARD _PROTOTYPE( void phys_put32, (phys_bytes addr, u32_t value)    );
 FORWARD _PROTOTYPE( u32_t phys_get32, (phys_bytes addr)                        );
 FORWARD _PROTOTYPE( void vm_set_cr3, (u32_t value)                     );
@@ -46,11 +48,12 @@ PUBLIC void vm_init(void)
        unsigned pages;
        struct proc* rp;
        struct proc *sys = proc_addr(SYSTEM);
+       static int init_done = 0;
 
        if (!vm_size)
                minix_panic("i386_vm_init: no space for page tables", NO_NUM);
 
-       if(vm_running)
+       if(init_done)
                return;
 
        /* Align page directory */
@@ -97,14 +100,15 @@ PUBLIC void vm_init(void)
                phys_put32(vm_dir_base + p*I386_VM_PT_ENT_SIZE, entry);
        }
 
-       /* Set this cr3 in all currently running processes for
-        * future context switches.
-        */
-       for (rp=BEG_PROC_ADDR; rp<END_PROC_ADDR; rp++) {
-               u32_t mycr3;
-               if(isemptyp(rp)) continue;
-               rp->p_seg.p_cr3 = vm_dir_base;
-       }
+
+       /* Set this cr3 in all currently running processes for
+        * future context switches.
+        */
+       for (rp=BEG_PROC_ADDR; rp<END_PROC_ADDR; rp++) {
+               u32_t mycr3;
+               if(isemptyp(rp)) continue;
+               rp->p_seg.p_cr3 = vm_dir_base;
+       }
 
        kernel_cr3 = vm_dir_base;
 
@@ -115,6 +119,7 @@ PUBLIC void vm_init(void)
        level0(vm_enable_paging);
 
        /* Don't do this init in the future. */
+       init_done = 1;
        vm_running = 1;
 }
 
@@ -312,6 +317,11 @@ PUBLIC int vm_lookup(struct proc *proc, vir_bytes virtual, vir_bytes *physical,
        vmassert(physical);
        vmassert(!(proc->p_rts_flags & SLOT_FREE));
 
+       if(!HASPT(proc)) {
+               *physical = virtual;
+               return OK;
+       }
+
        /* Retrieve page directory entry. */
        root = (u32_t *) proc->p_seg.p_cr3;
        vmassert(!((u32_t) root % I386_PAGE_SIZE));
@@ -428,7 +438,9 @@ PUBLIC int vm_contiguous(struct proc *targetproc, u32_t vir_buf, size_t bytes)
 
        vmassert(targetproc);
        vmassert(bytes > 0);
-       vmassert(vm_running);
+
+       if(!HASPT(targetproc))
+               return 1;
 
        /* Start and end at page boundary to make logic simpler. */
        po = vir_buf % I386_PAGE_SIZE;
@@ -488,8 +500,8 @@ PUBLIC int vm_checkrange(struct proc *caller, struct proc *target,
        u32_t flags, po, v;
        int r;
 
-       vmassert(vm_running);
-
+       if(!HASPT(target))
+               return OK;
 
        /* If caller has had a reply to this request, return it. */
        if(RTS_ISSET(caller, VMREQUEST)) {
@@ -760,8 +772,9 @@ int vmcheck;                        /* if nonzero, can return VMSUSPEND */
   if(vmcheck && procs[_DST_])
        CHECKRANGE_OR_SUSPEND(procs[_DST_], phys_addr[_DST_], bytes, 1);
 
+#define NOPT(p) (!(p) || !HASPT(p))
   /* Now copy bytes between physical addresseses. */
-  if(!vm_running || (procs[_SRC_] == NULL && procs[_DST_] == NULL)) {
+  if(NOPT(procs[_SRC_]) && NOPT(procs[_DST_])) {
        /* Without vm, address ranges actually are physical. */
        phys_copy(phys_addr[_SRC_], phys_addr[_DST_], (phys_bytes) bytes);
        r = OK;
index 0a5a4723e798856012cd37f114e8c8e66621e430..12cd8aa64242d6aa6d6220033db7eccfc16be93d 100644 (file)
@@ -20,14 +20,14 @@ check_runqueues_f(char *file, int line)
 {
   int q, l = 0;
   register struct proc *xp;
+
+  if(!intr_disabled()) {
+       minix_panic("check_runqueues called with interrupts enabled", NO_NUM);
+  }
+
 #define MYPANIC(msg) {         \
-       static char buf[100];   \
-       strcpy(buf, file);      \
-       strcat(buf, ": ");      \
-       util_nstrcat(buf, line);\
-       strcat(buf, ": ");      \
-       strcat(buf, msg);       \
-       minix_panic(buf, NO_NUM);       \
+       kprintf("check_runqueues:%s:%d: %s\n", file, line, msg); \
+       minix_panic("check_runqueues failed", NO_NUM);  \
        }
 
   for (xp = BEG_PROC_ADDR; xp < END_PROC_ADDR; ++xp) {
@@ -49,14 +49,30 @@ check_runqueues_f(char *file, int line)
                 MYPANIC("scheduling error");
     }
     for(xp = rdy_head[q]; xp != NIL_PROC; xp = xp->p_nextready) {
+       vir_bytes vxp = (vir_bytes) xp, dxp;
+       if(vxp < (vir_bytes) BEG_PROC_ADDR || vxp >= (vir_bytes) END_PROC_ADDR) {
+               MYPANIC("xp out of range");
+       }
+       dxp = vxp - (vir_bytes) BEG_PROC_ADDR;
+       if(dxp % sizeof(struct proc)) {
+               MYPANIC("xp not a real pointer");
+       }
+       if(xp->p_magic != PMAGIC) {
+               MYPANIC("magic wrong in xp");
+       }
+       if (RTS_ISSET(xp, SLOT_FREE)) {
+               kprintf("scheduling error: dead proc q %d %d\n",
+                       q, xp->p_endpoint);
+               MYPANIC("dead proc on run queue");
+       }
         if (!xp->p_ready) {
                kprintf("scheduling error: unready on runq %d proc %d\n",
                        q, xp->p_nr);
                MYPANIC("found unready process on run queue");
         }
         if (xp->p_priority != q) {
-               kprintf("scheduling error: wrong priority q %d proc %d\n",
-                       q, xp->p_nr);
+               kprintf("scheduling error: wrong priority q %d proc %d ep %d name %s\n",
+                       q, xp->p_nr, xp->p_endpoint, xp->p_name);
                MYPANIC("wrong priority");
        }
        if (xp->p_found) {
@@ -76,6 +92,8 @@ check_runqueues_f(char *file, int line)
 
   l = 0;
   for (xp = BEG_PROC_ADDR; xp < END_PROC_ADDR; ++xp) {
+       if(xp->p_magic != PMAGIC) 
+               MYPANIC("p_magic wrong in proc table");
        if (! isemptyp(xp) && xp->p_ready && ! xp->p_found) {
                kprintf("sched error: ready proc %d not on queue\n", xp->p_nr);
                MYPANIC("ready proc not on scheduling queue");
index 034a26e8270da216c132d26ed141ec178068e076..ee2539280903bdc5761fde4b51575b97628b843f 100644 (file)
  */
 #define DEBUG_ENABLE_IPC_WARNINGS      1
 #define DEBUG_STACKTRACE               1
-#define DEBUG_VMASSERT                 1
-#define DEBUG_SCHED_CHECK              1
 #define DEBUG_TIME_LOCKS               1
 
+/* Runtime sanity checking. */
+#define DEBUG_VMASSERT                 0
+#define DEBUG_SCHED_CHECK              0
+
 #endif /* DEBUG_H */
index 1ef2474aaa9a5f15a212bd05cda9a6e2d5d2f815..c2185a37eaabe0553d5dd7afb0ae7e44bb0e50d3 100755 (executable)
@@ -43,6 +43,9 @@ PUBLIC void main()
    */
   for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) {
        rp->p_rts_flags = SLOT_FREE;            /* initialize free slot */
+#if DEBUG_SCHED_CHECK
+       rp->p_magic = PMAGIC;
+#endif
        rp->p_nr = i;                           /* proc number from ptr */
        rp->p_endpoint = _ENDPOINT(0, rp->p_nr); /* generation no. 0 */
         (pproc_addr + NR_TASKS)[i] = rp;        /* proc ptr from number */
@@ -67,6 +70,7 @@ PUBLIC void main()
   for (i=0; i < NR_BOOT_PROCS; ++i) {
        int ci;
        bitchunk_t fv;
+
        ip = &image[i];                         /* process' attributes */
        rp = proc_addr(ip->proc_nr);            /* get process pointer */
        ip->endpoint = rp->p_endpoint;          /* ipc endpoint */
@@ -164,8 +168,6 @@ PUBLIC void main()
        /* Set ready. The HARDWARE task is never ready. */
        if (rp->p_nr == HARDWARE) RTS_SET(rp, NO_PRIORITY);
        RTS_UNSET(rp, SLOT_FREE); /* remove SLOT_FREE and schedule */
-
-       /* Code and data segments must be allocated in protected mode. */
        alloc_segments(rp);
   }
 
index bfc043bdbf5746660cf7524b9ea646a4fd91f26b..df90bfed4cc851e7bf0650c8ada8b49a7c9f449e 100755 (executable)
@@ -104,6 +104,8 @@ struct proc {
 
 #if DEBUG_SCHED_CHECK
   int p_ready, p_found;
+#define PMAGIC 0xC0FFEE1
+  int p_magic; /* check validity of proc pointers */
 #endif
 };
 
index a4287da33a7c4c054d15cb6a0c1f293686e01542..408819befec0fe7bf91a508da1262d6959f2b967 100755 (executable)
@@ -48,7 +48,7 @@ PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
 #define IDL_F  (SYS_PROC | PREEMPTIBLE | BILLABLE)     /* idle task */
 #define TSK_F  (SYS_PROC)                              /* kernel tasks */
 #define SRV_F  (SYS_PROC | PREEMPTIBLE)                /* system services */
-#define USR_F  (BILLABLE | PREEMPTIBLE)                /* user processes */
+#define USR_F  (BILLABLE | PREEMPTIBLE | PROC_FULLVM)  /* user processes */
 #define SVM_F  (SRV_F | PROC_FULLVM)                   /* servers with VM */
 
 /* Define system call traps for the various process types. These call masks
@@ -117,13 +117,13 @@ PUBLIC struct boot_image image[] = {
 {CLOCK,clock_task,TSK_F,  8, TASK_Q, TSK_S, TSK_T,     0, no_c,"clock" },
 {SYSTEM, sys_task,TSK_F,  8, TASK_Q, TSK_S, TSK_T,     0, no_c,"system"},
 {HARDWARE,      0,TSK_F,  8, TASK_Q, HRD_S,     0,     0, no_c,"kernel"},
-{PM_PROC_NR,    0,SRV_F, 32,      4, 0,     SRV_T, SRV_M, c(pm_c),"pm"    },
-{FS_PROC_NR,    0,SRV_F, 32,      5, 0,     SRV_T, SRV_M, c(fs_c),"vfs"   },
-{RS_PROC_NR,    0,SRV_F,  4,      4, 0,     SRV_T, SYS_M, c(rs_c),"rs"    },
-{DS_PROC_NR,    0,SRV_F,  4,      4, 0,     SRV_T, SYS_M, c(ds_c),"ds"    },
-{TTY_PROC_NR,   0,SRV_F,  4,      1, 0,     SRV_T, SYS_M,c(tty_c),"tty"   },
+{PM_PROC_NR,    0,SVM_F, 32,      4, 0,     SRV_T, SRV_M, c(pm_c),"pm"    },
+{FS_PROC_NR,    0,SVM_F, 32,      5, 0,     SRV_T, SRV_M, c(fs_c),"vfs"   },
+{RS_PROC_NR,    0,SVM_F,  4,      4, 0,     SRV_T, SYS_M, c(rs_c),"rs"    },
+{DS_PROC_NR,    0,SVM_F,  4,      4, 0,     SRV_T, SYS_M, c(ds_c),"ds"    },
+{TTY_PROC_NR,   0,SVM_F,  4,      1, 0,     SRV_T, SYS_M,c(tty_c),"tty"   },
 {MEM_PROC_NR,   0,SVM_F,  4,      3, 0,     SRV_T, SYS_M,c(mem_c),"memory"},
-{LOG_PROC_NR,   0,SRV_F,  4,      2, 0,     SRV_T, SYS_M,c(drv_c),"log"   },
+{LOG_PROC_NR,   0,SVM_F,  4,      2, 0,     SRV_T, SYS_M,c(drv_c),"log"   },
 {MFS_PROC_NR,   0,SVM_F, 32,      5, 0,     SRV_T, SRV_M, c(fs_c),"mfs"   },
 {VM_PROC_NR,    0,SRV_F, 32,      2, 0,     SRV_T, SRV_M, c(vm_c),"vm"    },
 {INIT_PROC_NR,  0,USR_F,  8, USER_Q, 0,     USR_T, USR_M, no_c,"init"  },