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:
Ben Gras
2009-05-12 11:35:01 +00:00
parent ebe050dbe2
commit e3ca89c0be
7 changed files with 87 additions and 40 deletions
+17 -7
View File
@@ -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",
+26 -13
View 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;