Get rid of static spare pages after VM startup.

This commit is contained in:
Cristiano Giuffrida 2010-07-20 21:59:27 +00:00
parent 40b4e71db2
commit 0d984b36ef
4 changed files with 95 additions and 3 deletions

View file

@ -30,6 +30,9 @@ struct proc *p;
p->p_seg.p_cr3 = m_ptr->SVMCTL_PTROOT;
p->p_seg.p_cr3_v = (u32_t *) m_ptr->SVMCTL_PTROOT_V;
p->p_misc_flags |= MF_FULLVM;
if(p == ptproc) {
write_cr3(p->p_seg.p_cr3);
}
} else {
p->p_seg.p_cr3 = 0;
p->p_seg.p_cr3_v = NULL;

View file

@ -88,7 +88,9 @@ int kernmappings = 0;
/* Page table that contains pointers to all page directories. */
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
/*===========================================================================*
@ -750,13 +752,18 @@ PUBLIC void pt_init(phys_bytes usedlimit)
I386_PAGE_SIZE*SPAREPAGES, &sparepages_ph)) != OK)
panic("pt_init: sys_umap failed: %d", r);
missing_spares = 0;
assert(STATIC_SPAREPAGES < SPAREPAGES);
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].phys = sparepages_ph + s*I386_PAGE_SIZE;
}
missing_spares = 0;
/* global bit and 4MB pages available? */
global_bit_ok = _cpufeature(_CPUF_I386_PGE);
bigpage_ok = _cpufeature(_CPUF_I386_PSE);
@ -918,6 +925,84 @@ PUBLIC void pt_init(phys_bytes usedlimit)
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 *

View file

@ -262,6 +262,9 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
mem_init(mem_chunks);
meminit_done = 1;
/* Architecture-dependent memory initialization. */
pt_init_mem();
/* Give these processes their own page table. */
for (ip = &image[0]; ip < &image[NR_BOOT_PROCS]; ip++) {
int s;

View file

@ -97,6 +97,7 @@ _PROTOTYPE( int handle_memory, (struct vmproc *vmp, vir_bytes mem,
/* $(ARCH)/pagetable.c */
_PROTOTYPE( void pt_init, (phys_bytes limit) );
_PROTOTYPE( void pt_init_mem, (void) );
_PROTOTYPE( void pt_check, (struct vmproc *vmp) );
_PROTOTYPE( int pt_new, (pt_t *pt) );
_PROTOTYPE( void pt_free, (pt_t *pt) );