map in kernel in 4MB, global-bit-set 'pages' if hardware

supports it. helps performance.

broken use of region data structure for kernel mapping to be fixed.
This commit is contained in:
Ben Gras 2009-05-18 15:34:42 +00:00
parent f76d75a5ec
commit f86da99e67
2 changed files with 41 additions and 16 deletions

View file

@ -348,10 +348,12 @@ PUBLIC int proc_new(struct vmproc *vmp,
vm_assert(!(data_start % VM_PAGE_SIZE)); vm_assert(!(data_start % VM_PAGE_SIZE));
vm_assert((!text_start && !data_start) || (text_start && data_start)); vm_assert((!text_start && !data_start) || (text_start && data_start));
#if 0
if(!map_proc_kernel(vmp)) { if(!map_proc_kernel(vmp)) {
printf("VM: exec: map_proc_kernel failed\n"); printf("VM: exec: map_proc_kernel failed\n");
return ENOMEM; return ENOMEM;
} }
#endif
/* Place text at start of process. */ /* Place text at start of process. */
vmp->vm_arch.vm_seg[T].mem_phys = ABS2CLICK(vstart); vmp->vm_arch.vm_seg[T].mem_phys = ABS2CLICK(vstart);

View file

@ -384,6 +384,7 @@ PUBLIC int pt_writemap(pt_t *pt, vir_bytes v, phys_bytes physaddr,
/* Write mapping into page table. Allocate a new page table if necessary. */ /* Write mapping into page table. Allocate a new page table if necessary. */
/* Page directory and table entries for this virtual address. */ /* Page directory and table entries for this virtual address. */
int p, pages, pde; int p, pages, pde;
int finalpde;
SANITYCHECK(SCL_FUNCTIONS); SANITYCHECK(SCL_FUNCTIONS);
vm_assert(!(bytes % I386_PAGE_SIZE)); vm_assert(!(bytes % I386_PAGE_SIZE));
@ -406,13 +407,18 @@ PUBLIC int pt_writemap(pt_t *pt, vir_bytes v, phys_bytes physaddr,
PT_SANE(pt); PT_SANE(pt);
finalpde = I386_VM_PDE(v + I386_PAGE_SIZE * pages);
/* First make sure all the necessary page tables are allocated, /* First make sure all the necessary page tables are allocated,
* before we start writing in any of them, because it's a pain * before we start writing in any of them, because it's a pain
* to undo our work properly. Walk the range in page-directory-entry * to undo our work properly. Walk the range in page-directory-entry
* sized leaps. * sized leaps.
*/ */
for(pde = I386_VM_PDE(v); pde <= I386_VM_PDE(v + I386_PAGE_SIZE * pages); pde++) { for(pde = I386_VM_PDE(v); pde <= finalpde; pde++) {
vm_assert(pde >= 0 && pde < I386_VM_DIR_ENTRIES); vm_assert(pde >= 0 && pde < I386_VM_DIR_ENTRIES);
if(pt->pt_dir[pde] & I386_VM_BIGPAGE) {
vm_panic("pt_writemap: BIGPAGE found", NO_NUM);
}
if(!(pt->pt_dir[pde] & I386_VM_PRESENT)) { if(!(pt->pt_dir[pde] & I386_VM_PRESENT)) {
int r; int r;
vm_assert(!pt->pt_dir[pde]); vm_assert(!pt->pt_dir[pde]);
@ -494,6 +500,10 @@ PUBLIC int pt_new(pt_t *pt)
/* Where to start looking for free virtual address space? */ /* Where to start looking for free virtual address space? */
pt->pt_virtop = 0; pt->pt_virtop = 0;
/* Map in kernel. */
if(pt_mapkernel(pt) != OK)
vm_panic("pt_new: pt_mapkernel failed", NO_NUM);
return OK; return OK;
} }
@ -574,11 +584,11 @@ PUBLIC void pt_init(void)
vmp->vm_arch.vm_seg[D].mem_phys += ABS2CLICK(moveup); vmp->vm_arch.vm_seg[D].mem_phys += ABS2CLICK(moveup);
vmp->vm_arch.vm_seg[S].mem_phys += ABS2CLICK(moveup); vmp->vm_arch.vm_seg[S].mem_phys += ABS2CLICK(moveup);
#if 0
/* Map in kernel. */ /* Map in kernel. */
if(pt_mapkernel(newpt) != OK) if(pt_mapkernel(newpt) != OK)
vm_panic("pt_init: pt_mapkernel failed", NO_NUM); vm_panic("pt_init: pt_mapkernel failed", NO_NUM);
#if 0
/* Allocate us a page table in which to remember page directory /* Allocate us a page table in which to remember page directory
* pointers. * pointers.
*/ */
@ -705,23 +715,35 @@ PUBLIC void pt_free(pt_t *pt)
PUBLIC int pt_mapkernel(pt_t *pt) PUBLIC int pt_mapkernel(pt_t *pt)
{ {
int r; int r;
static int pde = -1; static int pde = -1, do_bigpage = 0;
int global; u32_t global = 0;
static u32_t kern_phys;
static int printed = 0;
if(global_bit_ok) global = I386_VM_GLOBAL; if(global_bit_ok) global = I386_VM_GLOBAL;
/* Any i386 page table needs to map in the kernel address space. */ /* Any i386 page table needs to map in the kernel address space. */
vm_assert(vmproc[VMP_SYSTEM].vm_flags & VMF_INUSE); vm_assert(vmproc[VMP_SYSTEM].vm_flags & VMF_INUSE);
if(pde == -1) { if(pde == -1 && bigpage_ok) {
int pde1, pde2; int pde1, pde2;
pde1 = I386_VM_PDE(KERNEL_TEXT); pde1 = I386_VM_PDE(KERNEL_TEXT);
pde2 = I386_VM_PDE(KERNEL_DATA+KERNEL_DATA_LEN); pde2 = I386_VM_PDE(KERNEL_DATA+KERNEL_DATA_LEN);
vm_assert(pde1 == pde2); if(pde1 != pde2) {
printf("VM: pt_mapkernel: kernel too big?");
bigpage_ok = 0;
} else {
kern_phys = KERNEL_TEXT & I386_VM_ADDR_MASK_4MB;
pde = pde1; pde = pde1;
do_bigpage = 1;
vm_assert(pde >= 0); vm_assert(pde >= 0);
} }
}
if(do_bigpage) {
pt->pt_dir[pde] = kern_phys |
I386_VM_BIGPAGE|I386_VM_PRESENT|I386_VM_WRITE|global;
} else {
/* Map in text. flags: don't write, supervisor only */ /* Map in text. flags: don't write, supervisor only */
if((r=pt_writemap(pt, KERNEL_TEXT, KERNEL_TEXT, KERNEL_TEXT_LEN, if((r=pt_writemap(pt, KERNEL_TEXT, KERNEL_TEXT, KERNEL_TEXT_LEN,
I386_VM_PRESENT|global, 0)) != OK) I386_VM_PRESENT|global, 0)) != OK)
@ -731,6 +753,7 @@ PUBLIC int pt_mapkernel(pt_t *pt)
if((r=pt_writemap(pt, KERNEL_DATA, KERNEL_DATA, KERNEL_DATA_LEN, if((r=pt_writemap(pt, KERNEL_DATA, KERNEL_DATA, KERNEL_DATA_LEN,
I386_VM_PRESENT|I386_VM_WRITE|global, 0)) != OK) I386_VM_PRESENT|I386_VM_WRITE|global, 0)) != OK)
return r; return r;
}
return OK; return OK;
} }