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…
Reference in a new issue