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).
This commit is contained in:
parent
ebe050dbe2
commit
e3ca89c0be
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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" },
|
||||
|
|
Loading…
Reference in a new issue