struct thread *fault_page(struct thread *image) { uint32_t cr2; /* Get faulting address from register CR2 */ cr2 = cpu_get_cr2(); /* If in kernelspace, panic */ if ((image->cs & 0x3) == 0) { /* i.e. if it was kernelmode */ debug_printf("page fault at %x, ip = %x, frame %x, esp = %x\n", cr2, image->eip, page_get(cr2), image->esp); debug_panic("page fault exception"); } if (cr2 >= image->stack && cr2 < image->stack + SEGSZ) { /* allocate stack */ mem_alloc(cr2 & ~0xFFF, PAGESZ, PF_PRES | PF_RW | PF_USER); return image; } else { /* fault */ debug_printf("%d: %s: page fault at %x, ip = %x, frame %x\n", image->proc->pid, image->proc->name, cr2, image->eip, page_get(cr2)); debug_printf("user stack: %x - %x\n", image->stack, image->stack + SEGSZ); debug_printf("user stack dump: (ebp = %x)\n", image->ebp); debug_dumpi((void*) image->useresp, 30); process_freeze(image->proc); return thread_send(image, image->proc->pid, PORT_PAGE, NULL); } }
void TRAP_pfault(interrupt_frame f) { vm_trap_frame_t vtf; // vm_disable_paging(); vtf.fault_addr = cpu_get_cr2(); vtf.reason = (f.f_errno & PFE_PRESENT)? VM_PFAULT_NO_PERMISSION : VM_PFAULT_NO_PRESENT; vtf.in_kernel = !(f.f_errno & PFE_US); vtf.operation = (f.f_errno & PFE_WR)? VM_WRITE : VM_READ; vtf.preempted_addr = f.f_eip; kprintf("CIPL: %i\n", CIPL); vm_trap_pfault(&vtf); }
void fault_page(struct thread *image) { uint32_t cr2; /* Get faulting address from register CR2 */ cr2 = cpu_get_cr2(); /* If in kernelspace, panic */ if ((image->cs & 0x3) == 0) { /* i.e. if it was kernelmode */ debug_printf("page fault at %x, ip = %x, frame %x, esp = %x\n", cr2, image->eip, page_get(cr2), image->esp); debug_panic("page fault exception"); } /* fault */ thread_save(image); image->fault_addr = cr2; image->fault = FV_PAGE; image->state = TS_PAUSED; // add to fault queue fault_push(image); }