add: dprintf("page_fault: enabling interrupts\n"); if (!kernel_startup) dprintf("page_fault, but interrupts are disabled. touching address %p from eip %p\n", cr2, frame.eip);
context: i386_handle_trap(struct iframe frame){	int ret = B_HANDLED_INTERRUPT;	struct thread *thread = thread_get_current_thread();	if (thread) {		i386_push_iframe(thread, &frame);		thread->arch_info.current_iframe = &frame;	}//	if(frame.vector != 0x20)//		dprintf("i386_handle_trap: vector 0x%x, ip 0x%x, cpu %d\n", frame.vector, frame.eip, smp_get_current_cpu());	switch(frame.vector) {		case 8:			ret = i386_double_fault(frame.error_code);			break;		case 13:			ret = i386_general_protection_fault(frame.error_code);			break;		case 14: {			unsigned int cr2;			addr newip;			asm ("movl %%cr2, %0" : "=r" (cr2) );			// get the old interrupt enable/disable state and restore to that			if(frame.flags & 0x200) {//				dprintf("page_fault: enabling interrupts\n");				enable_interrupts();			}			ret = vm_page_fault(cr2, frame.eip,				(frame.error_code & 0x2) != 0,				(frame.error_code & 0x4) != 0,				&newip);			if(newip != 0) {				// the page fault handler wants us to modify the iframe to set the				// IP the cpu will return to to be this ip				frame.eip = newip;			}			break;		}		case 99: {			uint64 retcode;			unsigned int args[MAX_ARGS];			int rc;			thread_atkernel_entry();#if 0{			int i;			dprintf("i386_handle_trap: syscall %d, count %d, ptr 0x%x\n", frame.eax, frame.ecx, frame.edx);			dprintf(" call stack:\n");			for(i=0; i<frame.ecx; i++)				dprintf("\t0x%x\n", ((unsigned int *)frame.edx)[i]);}#endif			/*			** syscall interface works as such:			** eax has syscall #			** ecx has number of args (0-16)			** edx has pointer to buffer containing args from first to last			** each is verified to make sure someone doesn't try to clobber it			*/			if(frame.ecx <= MAX_ARGS) {				if((addr)frame.edx >= KERNEL_BASE && (addr)frame.edx <= KERNEL_TOP) {					retcode =  ERR_VM_BAD_USER_MEMORY;				} else {					rc = user_memcpy(args, (void *)frame.edx, frame.ecx * sizeof(unsigned int));					if(rc < 0)						retcode = ERR_VM_BAD_USER_MEMORY;					else						ret = syscall_dispatcher(frame.eax, (void *)args, &retcode);				}			} else {				// want to pass too many args into the system				retcode = EINVAL;			}			frame.eax = retcode & 0xffffffff;			frame.edx = retcode >> 32;			break;		}		default:			if(frame.vector >= 0x20) {				interrupt_ack(frame.vector); // ack the 8239 (if applicable)				ret = int_io_interrupt_handler(frame.vector);			} else {				panic("i386_handle_trap: unhandled cpu trap 0x%x at ip 0x%x!\n", frame.vector, frame.eip);				ret = B_HANDLED_INTERRUPT;			}			break;	}		if (ret == B_INVOKE_SCHEDULER) {		int state = disable_interrupts();		GRAB_THREAD_LOCK();		resched();		RELEASE_THREAD_LOCK();		restore_interrupts(state);	}	if (frame.cs == USER_CODE_SEG || frame.vector == 99) {		thread_atkernel_exit();	}	//	dprintf("0x%x cpu %d!\n", thread_get_current_thread_id(), smp_get_current_cpu());	if (thread)		i386_pop_iframe(thread);}