 f51eea4b32
			
		
	
	
		f51eea4b32
		
	
	
	
	
		
			
			this patch changes the way pagefaults are delivered to VM. It adopts the same model as the out-of-quantum messages sent by kernel to a scheduler. - everytime a userspace pagefault occurs, kernel creates a message which is sent to VM on behalf of the faulting process - the process is blocked on delivery to VM in the standard IPC code instead of waiting in a spacial in-kernel queue (stack) and is not runnable until VM tell kernel that the pagefault is resolved and is free to clear the RTS_PAGEFAULT flag. - VM does not need call kernel and poll the pagefault information which saves many (1/2?) calls and kernel calls that return "no more data" - VM notification by kernel does not need to use signals - each entry in proc table is by 12 bytes smaller (~3k save)
		
			
				
	
	
		
			73 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* The kernel call implemented in this file:
 | |
|  *   m_type:	SYS_VMCTL
 | |
|  *
 | |
|  * The parameters for this kernel call are:
 | |
|  *   	SVMCTL_WHO	which process
 | |
|  *    	SVMCTL_PARAM	set this setting (VMCTL_*)
 | |
|  *    	SVMCTL_VALUE	to this value
 | |
|  */
 | |
| 
 | |
| #include "kernel/system.h"
 | |
| #include <minix/type.h>
 | |
| 
 | |
| #include "proto.h"
 | |
| 
 | |
| extern u8_t *vm_pagedirs;
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *				arch_do_vmctl				     *
 | |
|  *===========================================================================*/
 | |
| PUBLIC int arch_do_vmctl(m_ptr, p)
 | |
| register message *m_ptr;	/* pointer to request message */
 | |
| struct proc *p;
 | |
| {
 | |
|   switch(m_ptr->SVMCTL_PARAM) {
 | |
| 	case VMCTL_I386_GETCR3:
 | |
| 		/* Get process CR3. */
 | |
| 		m_ptr->SVMCTL_VALUE = p->p_seg.p_cr3;
 | |
| 		return OK;
 | |
| 	case VMCTL_I386_SETCR3:
 | |
| 		/* Set process CR3. */
 | |
| 		if(m_ptr->SVMCTL_VALUE) {
 | |
| 			p->p_seg.p_cr3 = m_ptr->SVMCTL_VALUE;
 | |
| 			p->p_misc_flags |= MF_FULLVM;
 | |
| 		} else {
 | |
| 			p->p_seg.p_cr3 = 0;
 | |
| 			p->p_misc_flags &= ~MF_FULLVM;
 | |
| 		}
 | |
| 		RTS_UNSET(p, RTS_VMINHIBIT);
 | |
| 		return OK;
 | |
| 	case VMCTL_INCSP:
 | |
| 		/* Increase process SP. */
 | |
| 		p->p_reg.sp += m_ptr->SVMCTL_VALUE;
 | |
| 		return OK;
 | |
| 	case VMCTL_I386_KERNELLIMIT:
 | |
| 	{
 | |
| 		int r;
 | |
| 		/* VM wants kernel to increase its segment. */
 | |
| 		r = prot_set_kern_seg_limit(m_ptr->SVMCTL_VALUE);
 | |
| 		return r;
 | |
| 	}
 | |
| 	case VMCTL_I386_PAGEDIRS:
 | |
| 	{
 | |
| 		vm_pagedirs = (u8_t *) m_ptr->SVMCTL_VALUE;
 | |
| 		return OK;
 | |
| 	}
 | |
| 	case VMCTL_I386_FREEPDE:
 | |
| 	{
 | |
| 		i386_freepde(m_ptr->SVMCTL_VALUE);
 | |
| 		return OK;
 | |
| 	}
 | |
| 	case VMCTL_FLUSHTLB:
 | |
| 	{
 | |
| 		reload_cr3();
 | |
| 		return OK;
 | |
| 	}
 | |
|   }
 | |
| 
 | |
| 
 | |
| 
 | |
|   printf("arch_do_vmctl: strange param %d\n", m_ptr->SVMCTL_PARAM);
 | |
|   return EINVAL;
 | |
| }
 |