Beispiel #1
0
void VirtualMemoryManager::Lock(void *ptr)
{
	if(!inited)
		return;

	LockMut(vmemMutex);

	// check that the address is within the virtual address bounds
	if((DWORD)ptr < baseAddress || (DWORD)ptr >= baseAddress + (totalPages * pageSize))
	{
		return;
	}

	// find the page(s) to free
	DWORD offset = (DWORD)ptr - baseAddress;
	unsigned long pageIndex = offset / pageSize;
	
	if(pages[pageIndex].headPage == -1)
	{
		return;
	}

	pageIndex = pages[pageIndex].headPage;

	unsigned long endPage = pageIndex + pages[pageIndex].sizeInPages;
	
	if(!pages[pageIndex].committed)
	{
		if(!PageFault(ptr))
			return;
	}

	for(unsigned long i = pageIndex; i < endPage; i++)
	{
		pages[i].locked = true;
	}
}
Beispiel #2
0
void DispatchException (struct ContextState *es)
{
	int privilege_level;
	int pf_direction;
	vm_addr pf_addr;
	
		
	if (isr_depth > 0)
		PrintException (es, "Exception in interrupt Handler", TRUE);


	if (es->return_eflags & EFLG_VM)
	{
		KPANIC ("V86 Exception");
	
		switch (es->exception)
		{
			case EXCEPTION_GP:
				EnableInterrupts();
				V86GPHandler (es);
				DisableInterrupts();
				break;
			
			default:
				PrintException (es, "#GP in V86", TRUE); 
			
		}
	}
	else if ((privilege_level = es->return_cs & 0x03) == 0)
	{	
		switch (es->exception)
		{
			case EXCEPTION_PF:
				pf_addr = GetCR2();
				
				if ((es->error_code & PF_ERRORCODE_DIRECTION) == 0)
					pf_direction = PF_DIR_READ;
				else
					pf_direction = PF_DIR_WRITE;
				
				EnableInterrupts();
					
				if (PageFault (pf_addr, pf_direction, privilege_level) != 0)
				{
					if (current_process->archproc.resume_eip != 0 &&
						current_process->archproc.resume_esp != 0)
					{
						es->return_eip = current_process->archproc.resume_eip;
						es->return_esp = current_process->archproc.resume_esp;
						current_process->archproc.resume_eip = 0;
						current_process->archproc.resume_esp = 0;
					}
					else
					{
						PrintException (es, "#PF in Kernel", TRUE);
					}
				}
				
				DisableInterrupts();
				
				break;
				
			default:
				PrintException (es, "Exception in Kernel", TRUE);
				
		}
	}
	else
	{
		switch (es->exception)
		{
			case EXCEPTION_DE:	/* Divide Error */
				current_process->usignal.sig_pending |= SIGFFPE;
				current_process->usignal.siginfo_data[SIGFPE-1].si_signo = SIGFPE;
				current_process->usignal.siginfo_data[SIGFPE-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGFPE-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_DB:  /* Debug */
				current_process->usignal.sig_pending |= SIGFTRAP;
				current_process->usignal.siginfo_data[SIGTRAP-1].si_signo = SIGTRAP;
				current_process->usignal.siginfo_data[SIGTRAP-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGTRAP-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_NMI: /* Non-Maskable Interupt */
				break;
			case EXCEPTION_BP:  /* Breakpoint */
				current_process->usignal.sig_pending |= SIGFTRAP;
				current_process->usignal.siginfo_data[SIGTRAP-1].si_signo = SIGTRAP;
				current_process->usignal.siginfo_data[SIGTRAP-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGTRAP-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_OF:  /* Overflow */
				current_process->usignal.sig_pending |= SIGFSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_signo = SIGSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_BR:  /* Boundary-Range Exceeded */
				current_process->usignal.sig_pending |= SIGFSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_signo = SIGSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_UD:  /* Undefined-Opcode */
				current_process->usignal.sig_pending |= SIGFILL;
				current_process->usignal.siginfo_data[SIGILL-1].si_signo = SIGILL;
				current_process->usignal.siginfo_data[SIGILL-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGILL-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_NM:  /* Device-Not Available */
				current_process->usignal.sig_pending |= SIGFSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_signo = SIGSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_DF:  /* Double-Fault */
				KPANIC ("DF");				
				break;
			case EXCEPTION_CSO: /* Reserved : Coprocessor Segment Overrun */
				current_process->usignal.sig_pending |= SIGFFPE;
				current_process->usignal.siginfo_data[SIGFPE-1].si_signo = SIGFPE;
				current_process->usignal.siginfo_data[SIGFPE-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGFPE-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_TS:  /* Invalid TSS */
				current_process->usignal.sig_pending |= SIGFSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_signo = SIGSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_NP:  /* Segment / Not Present */
				current_process->usignal.sig_pending |= SIGFBUS;
				current_process->usignal.siginfo_data[SIGBUS-1].si_signo = SIGBUS;
				current_process->usignal.siginfo_data[SIGBUS-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGBUS-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_SS:  /* Stack Segment */
				current_process->usignal.sig_pending |= SIGFBUS;
				current_process->usignal.siginfo_data[SIGBUS-1].si_signo = SIGBUS;
				current_process->usignal.siginfo_data[SIGBUS-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGBUS-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_GP:  /* General Protection */
				current_process->usignal.sig_pending |= SIGFSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_signo = SIGSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_PF:
				pf_addr = GetCR2();
			
				if ((es->error_code & PF_ERRORCODE_DIRECTION) == 0)
					pf_direction = PF_DIR_READ;
				else
					pf_direction = PF_DIR_WRITE;
				
				EnableInterrupts();
					
				if (PageFault (pf_addr, pf_direction, privilege_level) != 0)
				{
					current_process->usignal.sig_pending |= SIGFSEGV;
					current_process->usignal.siginfo_data[SIGSEGV-1].si_signo = SIGSEGV;
					current_process->usignal.siginfo_data[SIGSEGV-1].si_code = 0;
					current_process->usignal.siginfo_data[SIGSEGV-1].si_value.sival_int = 0;
					
					PrintException (es, "Page Fault in PL3", FALSE);
				}
			
				DisableInterrupts();
			
				break;
			case EXCEPTION_RESV: /* Reserved */
				break;
			case EXCEPTION_MF:  /* Math Fault */
				current_process->usignal.sig_pending |= SIGFFPE;
				current_process->usignal.siginfo_data[SIGFPE-1].si_signo = SIGFPE;
				current_process->usignal.siginfo_data[SIGFPE-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGFPE-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_AC:  /* Alignment Check */
				current_process->usignal.sig_pending |= SIGFSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_signo = SIGSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_value.sival_int = 0;
				break;
			case EXCEPTION_MC:  /* Machine Check */
				break;
			case EXCEPTION_XF:  /* Extended Math Fault */
				current_process->usignal.sig_pending |= SIGFFPE;
				current_process->usignal.siginfo_data[SIGFPE-1].si_signo = SIGFPE;
				current_process->usignal.siginfo_data[SIGFPE-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGFPE-1].si_value.sival_int = 0;
				break;
			default:            /* Unknown Exception */
				current_process->usignal.sig_pending |= SIGFSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_signo = SIGSEGV;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_code = 0;
				current_process->usignal.siginfo_data[SIGSEGV-1].si_value.sival_int = 0;
				break;
		}
	}
}