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_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;
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) );
|
||||
|
|
Loading…
Reference in a new issue