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).
/* 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);
{
/* An exception or unexpected interrupt has occurred. */
+struct proc *t;
+
struct ex_s {
char *msg;
int signum;
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;
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",
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) );
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 */
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;
level0(vm_enable_paging);
/* Don't do this init in the future. */
+ init_done = 1;
vm_running = 1;
}
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));
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;
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)) {
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;
{
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) {
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) {
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");
*/
#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 */
*/
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 */
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 */
/* 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);
}
#if DEBUG_SCHED_CHECK
int p_ready, p_found;
+#define PMAGIC 0xC0FFEE1
+ int p_magic; /* check validity of proc pointers */
#endif
};
#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
{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" },