Get rid of static spare pages after VM startup.
This commit is contained in:
		
							parent
							
								
									40b4e71db2
								
							
						
					
					
						commit
						0d984b36ef
					
				| @ -30,6 +30,9 @@ struct proc *p; | |||||||
| 			p->p_seg.p_cr3 = m_ptr->SVMCTL_PTROOT; | 			p->p_seg.p_cr3 = m_ptr->SVMCTL_PTROOT; | ||||||
| 			p->p_seg.p_cr3_v = (u32_t *) m_ptr->SVMCTL_PTROOT_V; | 			p->p_seg.p_cr3_v = (u32_t *) m_ptr->SVMCTL_PTROOT_V; | ||||||
| 			p->p_misc_flags |= MF_FULLVM; | 			p->p_misc_flags |= MF_FULLVM; | ||||||
|  | 			if(p == ptproc) { | ||||||
|  | 				write_cr3(p->p_seg.p_cr3); | ||||||
|  | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			p->p_seg.p_cr3 = 0; | 			p->p_seg.p_cr3 = 0; | ||||||
| 			p->p_seg.p_cr3_v = NULL; | 			p->p_seg.p_cr3_v = NULL; | ||||||
|  | |||||||
| @ -88,7 +88,9 @@ int kernmappings = 0; | |||||||
| /* Page table that contains pointers to all page directories. */ | /* Page table that contains pointers to all page directories. */ | ||||||
| u32_t page_directories_phys, *page_directories = NULL; | u32_t page_directories_phys, *page_directories = NULL; | ||||||
| 
 | 
 | ||||||
| PRIVATE char static_sparepages[I386_PAGE_SIZE*SPAREPAGES + I386_PAGE_SIZE]; | #define STATIC_SPAREPAGES 10 | ||||||
|  | 
 | ||||||
|  | PRIVATE char static_sparepages[I386_PAGE_SIZE*STATIC_SPAREPAGES + I386_PAGE_SIZE]; | ||||||
| 
 | 
 | ||||||
| #if SANITYCHECKS | #if SANITYCHECKS | ||||||
| /*===========================================================================*
 | /*===========================================================================*
 | ||||||
| @ -750,13 +752,18 @@ PUBLIC void pt_init(phys_bytes usedlimit) | |||||||
|                 I386_PAGE_SIZE*SPAREPAGES, &sparepages_ph)) != OK) |                 I386_PAGE_SIZE*SPAREPAGES, &sparepages_ph)) != OK) | ||||||
|                 panic("pt_init: sys_umap failed: %d", r); |                 panic("pt_init: sys_umap failed: %d", r); | ||||||
| 
 | 
 | ||||||
|  |         missing_spares = 0; | ||||||
|  |         assert(STATIC_SPAREPAGES < SPAREPAGES); | ||||||
|         for(s = 0; s < SPAREPAGES; s++) { |         for(s = 0; s < SPAREPAGES; s++) { | ||||||
|  |         	if(s >= STATIC_SPAREPAGES) { | ||||||
|  |         		sparepages[s].page = NULL; | ||||||
|  |         		missing_spares++; | ||||||
|  |         		continue; | ||||||
|  |         	} | ||||||
|         	sparepages[s].page = (void *) (sparepages_mem + s*I386_PAGE_SIZE); |         	sparepages[s].page = (void *) (sparepages_mem + s*I386_PAGE_SIZE); | ||||||
|         	sparepages[s].phys = sparepages_ph + s*I386_PAGE_SIZE; |         	sparepages[s].phys = sparepages_ph + s*I386_PAGE_SIZE; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 	missing_spares = 0; |  | ||||||
| 
 |  | ||||||
| 	/* global bit and 4MB pages available? */ | 	/* global bit and 4MB pages available? */ | ||||||
| 	global_bit_ok = _cpufeature(_CPUF_I386_PGE); | 	global_bit_ok = _cpufeature(_CPUF_I386_PGE); | ||||||
| 	bigpage_ok = _cpufeature(_CPUF_I386_PSE); | 	bigpage_ok = _cpufeature(_CPUF_I386_PSE); | ||||||
| @ -918,6 +925,84 @@ PUBLIC void pt_init(phys_bytes usedlimit) | |||||||
|         return; |         return; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /*===========================================================================*
 | ||||||
|  |  *                             pt_init_mem                                   * | ||||||
|  |  *===========================================================================*/ | ||||||
|  | PUBLIC void pt_init_mem() | ||||||
|  | { | ||||||
|  | /* Architecture-specific memory initialization. Make sure all the pages
 | ||||||
|  |  * shared with the kernel and VM's page tables are mapped above the stack, | ||||||
|  |  * so that we can easily transfer existing mappings for new VM instances. | ||||||
|  |  */ | ||||||
|  |         u32_t new_page_directories_phys, *new_page_directories; | ||||||
|  |         u32_t new_pt_dir_phys, *new_pt_dir; | ||||||
|  |         u32_t new_pt_phys, *new_pt;  | ||||||
|  |         pt_t *vmpt; | ||||||
|  |         int i; | ||||||
|  | 
 | ||||||
|  |         vmpt = &vmprocess->vm_pt; | ||||||
|  | 
 | ||||||
|  |         /* We should be running this when VM has been assigned a page
 | ||||||
|  |          * table and memory initialization has already been performed. | ||||||
|  |          */ | ||||||
|  |         assert(vmprocess->vm_flags & VMF_HASPT); | ||||||
|  |         assert(meminit_done); | ||||||
|  | 
 | ||||||
|  |         /* Throw away static spare pages. */ | ||||||
|  | 	vm_checkspares(); | ||||||
|  | 	for(i = 0; i < SPAREPAGES; i++) { | ||||||
|  | 		if(sparepages[i].page && (vir_bytes) sparepages[i].page | ||||||
|  | 			< vmprocess->vm_stacktop) { | ||||||
|  | 			sparepages[i].page = NULL; | ||||||
|  | 			missing_spares++; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	vm_checkspares(); | ||||||
|  | 
 | ||||||
|  |         /* Rellocate page for page directories pointers. */ | ||||||
|  | 	if(!(new_page_directories = vm_allocpage(&new_page_directories_phys, | ||||||
|  | 		VMP_PAGETABLE))) | ||||||
|  |                 panic("unable to reallocated page for page dir ptrs"); | ||||||
|  | 	assert((vir_bytes) new_page_directories >= vmprocess->vm_stacktop); | ||||||
|  | 	memcpy(new_page_directories, page_directories, I386_PAGE_SIZE); | ||||||
|  | 	page_directories = new_page_directories; | ||||||
|  | 	pagedir_pde_val = (new_page_directories_phys & I386_VM_ADDR_MASK) | | ||||||
|  | 			(pagedir_pde_val & ~I386_VM_ADDR_MASK); | ||||||
|  | 
 | ||||||
|  | 	/* Remap in kernel. */ | ||||||
|  | 	pt_mapkernel(vmpt); | ||||||
|  | 
 | ||||||
|  | 	/* Reallocate VM's page directory. */ | ||||||
|  | 	if((vir_bytes) vmpt->pt_dir < vmprocess->vm_stacktop) { | ||||||
|  | 		if(!(new_pt_dir= vm_allocpage(&new_pt_dir_phys, VMP_PAGEDIR))) { | ||||||
|  | 			panic("unable to reallocate VM's page directory"); | ||||||
|  | 		} | ||||||
|  | 		assert((vir_bytes) new_pt_dir >= vmprocess->vm_stacktop); | ||||||
|  | 		memcpy(new_pt_dir, vmpt->pt_dir, I386_PAGE_SIZE); | ||||||
|  | 		vmpt->pt_dir = new_pt_dir; | ||||||
|  | 		vmpt->pt_dir_phys = new_pt_dir_phys; | ||||||
|  | 		pt_bind(vmpt, vmprocess); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Reallocate VM's page tables. */ | ||||||
|  | 	for(i = proc_pde; i < I386_VM_DIR_ENTRIES; i++) { | ||||||
|  | 		if(!(vmpt->pt_dir[i] & I386_VM_PRESENT)) { | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 		assert(vmpt->pt_pt[i]); | ||||||
|  | 		if((vir_bytes) vmpt->pt_pt[i] >= vmprocess->vm_stacktop) { | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 		vm_checkspares(); | ||||||
|  | 		if(!(new_pt = vm_allocpage(&new_pt_phys, VMP_PAGETABLE))) | ||||||
|  | 			panic("unable to reallocate VM's page table"); | ||||||
|  | 		assert((vir_bytes) new_pt >= vmprocess->vm_stacktop); | ||||||
|  | 		memcpy(new_pt, vmpt->pt_pt[i], I386_PAGE_SIZE); | ||||||
|  | 		vmpt->pt_pt[i] = new_pt; | ||||||
|  | 		vmpt->pt_dir[i] = (new_pt_phys & I386_VM_ADDR_MASK) | | ||||||
|  | 			(vmpt->pt_dir[i] & ~I386_VM_ADDR_MASK); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| /*===========================================================================*
 | /*===========================================================================*
 | ||||||
|  *				pt_bind			     		     * |  *				pt_bind			     		     * | ||||||
|  | |||||||
| @ -262,6 +262,9 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) | |||||||
| 	mem_init(mem_chunks); | 	mem_init(mem_chunks); | ||||||
| 	meminit_done = 1; | 	meminit_done = 1; | ||||||
| 
 | 
 | ||||||
|  | 	/* Architecture-dependent memory initialization. */ | ||||||
|  | 	pt_init_mem(); | ||||||
|  | 
 | ||||||
| 	/* Give these processes their own page table. */ | 	/* Give these processes their own page table. */ | ||||||
| 	for (ip = &image[0]; ip < &image[NR_BOOT_PROCS]; ip++) { | 	for (ip = &image[0]; ip < &image[NR_BOOT_PROCS]; ip++) { | ||||||
| 		int s; | 		int s; | ||||||
|  | |||||||
| @ -97,6 +97,7 @@ _PROTOTYPE( int handle_memory, (struct vmproc *vmp, vir_bytes mem, | |||||||
| 
 | 
 | ||||||
| /* $(ARCH)/pagetable.c */ | /* $(ARCH)/pagetable.c */ | ||||||
| _PROTOTYPE( void pt_init, (phys_bytes limit)				); | _PROTOTYPE( void pt_init, (phys_bytes limit)				); | ||||||
|  | _PROTOTYPE( void pt_init_mem, (void)					); | ||||||
| _PROTOTYPE( void pt_check, (struct vmproc *vmp)				); | _PROTOTYPE( void pt_check, (struct vmproc *vmp)				); | ||||||
| _PROTOTYPE( int pt_new, (pt_t *pt)					); | _PROTOTYPE( int pt_new, (pt_t *pt)					); | ||||||
| _PROTOTYPE( void pt_free, (pt_t *pt)					); | _PROTOTYPE( void pt_free, (pt_t *pt)					); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Cristiano Giuffrida
						Cristiano Giuffrida