From: Ben Gras Date: Tue, 12 May 2009 11:35:01 +0000 (+0000) Subject: more sanity checking. sanity checking disabled by default. X-Git-Tag: v3.1.4~41 X-Git-Url: http://zhaoyanbai.com/repos/migration?a=commitdiff_plain;h=e3ca89c0be8d47c1c97e0c33247258792cdafb59;p=minix.git more sanity checking. sanity checking disabled by default. 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). --- diff --git a/kernel/arch/i386/exception.c b/kernel/arch/i386/exception.c index 1e5ba042e..2657482de 100755 --- a/kernel/arch/i386/exception.c +++ b/kernel/arch/i386/exception.c @@ -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", diff --git a/kernel/arch/i386/memory.c b/kernel/arch/i386/memory.c index 7a3317ab7..90be74d8d 100644 --- a/kernel/arch/i386/memory.c +++ b/kernel/arch/i386/memory.c @@ -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; rpp_seg.p_cr3 = vm_dir_base; - } + + /* Set this cr3 in all currently running processes for + * future context switches. + */ + for (rp=BEG_PROC_ADDR; rpp_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; diff --git a/kernel/debug.c b/kernel/debug.c index 0a5a4723e..12cd8aa64 100644 --- a/kernel/debug.c +++ b/kernel/debug.c @@ -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"); diff --git a/kernel/debug.h b/kernel/debug.h index 034a26e82..ee2539280 100644 --- a/kernel/debug.h +++ b/kernel/debug.h @@ -21,8 +21,10 @@ */ #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 */ diff --git a/kernel/main.c b/kernel/main.c index 1ef2474aa..c2185a37e 100755 --- a/kernel/main.c +++ b/kernel/main.c @@ -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); } diff --git a/kernel/proc.h b/kernel/proc.h index bfc043bdb..df90bfed4 100755 --- a/kernel/proc.h +++ b/kernel/proc.h @@ -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 }; diff --git a/kernel/table.c b/kernel/table.c index a4287da33..408819bef 100755 --- a/kernel/table.c +++ b/kernel/table.c @@ -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" },