Module Name: src Committed By: reinoud Date: Tue Jan 3 21:28:50 UTC 2012
Modified Files: src/sys/arch/usermode/conf: GENERIC.i386 std.usermode src/sys/arch/usermode/include: vmparam.h src/sys/arch/usermode/usermode: pmap.c trap.c Log Message: Rework NetBSD/usermode pmap fixing some oddities that were left over from earlier times when we were forced to run PIE executables and were forced to use a KVM above the kernel. To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/sys/arch/usermode/conf/GENERIC.i386 cvs rdiff -u -r1.9 -r1.10 src/sys/arch/usermode/conf/std.usermode cvs rdiff -u -r1.12 -r1.13 src/sys/arch/usermode/include/vmparam.h cvs rdiff -u -r1.91 -r1.92 src/sys/arch/usermode/usermode/pmap.c cvs rdiff -u -r1.51 -r1.52 src/sys/arch/usermode/usermode/trap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/usermode/conf/GENERIC.i386 diff -u src/sys/arch/usermode/conf/GENERIC.i386:1.1 src/sys/arch/usermode/conf/GENERIC.i386:1.2 --- src/sys/arch/usermode/conf/GENERIC.i386:1.1 Tue Dec 20 21:01:39 2011 +++ src/sys/arch/usermode/conf/GENERIC.i386 Tue Jan 3 21:28:50 2012 @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC.i386,v 1.1 2011/12/20 21:01:39 jmcneill Exp $ +# $NetBSD: GENERIC.i386,v 1.2 2012/01/03 21:28:50 reinoud Exp $ machine usermode include "arch/usermode/conf/GENERIC.common" @@ -6,12 +6,12 @@ include "arch/i386/conf/majors.i386" no options EXEC_ELF64 -options TEXTADDR=0x0f000000 # 1.5 Gb? -options KVMSIZE=0x008000000 - +options TEXTADDR=0x40000000 # 1 Gb `phys ram' / total space +options KVMSIZE= 0x10000000 # KVM space reserved in VM map, 256 Mb +options NKMEMPAGES_MAX=32768 # 128 Mb max makeoptions COPTS+="-m32" makeoptions LD="ld -melf_i386" #options INCLUDE_CONFIG_FILE -#ident "GENERIC32-$Revision: 1.1 $" +#ident "GENERIC32-$Revision: 1.2 $" Index: src/sys/arch/usermode/conf/std.usermode diff -u src/sys/arch/usermode/conf/std.usermode:1.9 src/sys/arch/usermode/conf/std.usermode:1.10 --- src/sys/arch/usermode/conf/std.usermode:1.9 Tue Dec 20 21:01:39 2011 +++ src/sys/arch/usermode/conf/std.usermode Tue Jan 3 21:28:50 2012 @@ -1,15 +1,13 @@ -# $NetBSD: std.usermode,v 1.9 2011/12/20 21:01:39 jmcneill Exp $ +# $NetBSD: std.usermode,v 1.10 2012/01/03 21:28:50 reinoud Exp $ include "conf/std" -options HZ=100 +options HZ=20 options EXEC_ELF32 options EXEC_ELF64 options EXEC_SCRIPT # Defaults -options NKMEMPAGES=4096 -#options NKMEMPAGES_MAX_DEFAULT=2048 options syscall_debug defflag opt_xen.h DO_NOT_DEFINE Index: src/sys/arch/usermode/include/vmparam.h diff -u src/sys/arch/usermode/include/vmparam.h:1.12 src/sys/arch/usermode/include/vmparam.h:1.13 --- src/sys/arch/usermode/include/vmparam.h:1.12 Sun Dec 25 21:10:00 2011 +++ src/sys/arch/usermode/include/vmparam.h Tue Jan 3 21:28:50 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: vmparam.h,v 1.12 2011/12/25 21:10:00 reinoud Exp $ */ +/* $NetBSD: vmparam.h,v 1.13 2012/01/03 21:28:50 reinoud Exp $ */ /*- * Copyright (c) 2007 Jared D. McNeill <jmcne...@invisible.ca> @@ -35,14 +35,14 @@ #define __USE_TOPDOWN_VM extern paddr_t kmem_k_start, kmem_k_end; -extern paddr_t kmem_ext_start, kmem_ext_end; +extern paddr_t kmem_kvm_start, kmem_kvm_end; extern paddr_t kmem_user_start, kmem_user_end; -#define VM_MIN_KERNEL_ADDRESS kmem_k_start -#define VM_MAX_KERNEL_ADDRESS kmem_ext_end #define VM_MIN_ADDRESS kmem_user_start -#define VM_MAXUSER_ADDRESS kmem_user_end #define VM_MAX_ADDRESS kmem_user_end +#define VM_MAXUSER_ADDRESS kmem_user_end +#define VM_MIN_KERNEL_ADDRESS kmem_kvm_start +#define VM_MAX_KERNEL_ADDRESS kmem_kvm_end #define VM_PHYSSEG_STRAT VM_PSTRAT_BIGFIRST #define VM_PHYSSEG_MAX 1 @@ -51,6 +51,9 @@ extern paddr_t kmem_user_start, kmem_use #define USRSTACK VM_MAXUSER_ADDRESS +/* override the default pager_map size, there is little KVA */ +#define PAGER_MAP_DEFAULT_SIZE (4 * 1024 * 1024) + #if defined(__i386__) #define PAGE_SHIFT 12 #define PAGE_SIZE (1 << PAGE_SHIFT) Index: src/sys/arch/usermode/usermode/pmap.c diff -u src/sys/arch/usermode/usermode/pmap.c:1.91 src/sys/arch/usermode/usermode/pmap.c:1.92 --- src/sys/arch/usermode/usermode/pmap.c:1.91 Tue Jan 3 12:16:16 2012 +++ src/sys/arch/usermode/usermode/pmap.c Tue Jan 3 21:28:50 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.91 2012/01/03 12:16:16 reinoud Exp $ */ +/* $NetBSD: pmap.c,v 1.92 2012/01/03 21:28:50 reinoud Exp $ */ /*- * Copyright (c) 2011 Reinoud Zandijk <rein...@netbsd.org> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.91 2012/01/03 12:16:16 reinoud Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.92 2012/01/03 21:28:50 reinoud Exp $"); #include "opt_memsize.h" #include "opt_kmempages.h" @@ -85,7 +85,6 @@ static pmap_t active_pmap = NULL; static char mem_name[20] = ""; static int mem_fh; -static void *mem_uvm; /* keeps all memory managed by UVM */ static int phys_npages = 0; static int pm_nentries = 0; @@ -115,31 +114,29 @@ extern void setup_signal_handlers(void); /* exposed (to signal handler f.e.) */ vaddr_t kmem_k_start, kmem_k_end; -vaddr_t kmem_ext_start, kmem_ext_end; +vaddr_t kmem_kvm_start, kmem_kvm_end; vaddr_t kmem_user_start, kmem_user_end; -vaddr_t kmem_ext_cur_start, kmem_ext_cur_end; +vaddr_t kmem_kvm_cur_start, kmem_kvm_cur_end; /* amount of physical memory */ -int physmem; +uint physmem; int num_pv_entries = 0; int num_pmaps = 0; #define SPARSE_MEMFILE -static uint8_t mem_kvm[KVMSIZE + 2*PAGE_SIZE]; void pmap_bootstrap(void) { struct pmap *pmap; - paddr_t totmem_len; + paddr_t DRAM_cfg; paddr_t fpos, file_len; paddr_t pv_fpos, tlb_fpos, pm_l1_fpos, pm_fpos; paddr_t wlen; - paddr_t user_len, barrier_len; + paddr_t barrier_len; paddr_t pv_table_size; vaddr_t free_start, free_end; - vaddr_t mpos; paddr_t pa; vaddr_t va; uintptr_t pg, l1; @@ -163,33 +160,23 @@ pmap_bootstrap(void) thunk_printf_debug("1st end of data at %p\n", &end); thunk_printf_debug("CUR end data at %p\n", thunk_sbrk(0)); + barrier_len = 2 * 1024 * 1024; + /* calculate kernel section (R-X) */ kmem_k_start = (vaddr_t) PAGE_SIZE * (atop(_start) ); kmem_k_end = (vaddr_t) PAGE_SIZE * (atop(&etext) + 1); - /* calculate total available memory space */ - totmem_len = (vaddr_t) TEXTADDR; - - /* calculate the number of available pages */ - physmem = totmem_len / PAGE_SIZE; - - /* calculate memory lengths */ - barrier_len = 2 * 1024 * 1024; - user_len = kmem_k_start - vm_min_addr - barrier_len; - - /* devide memory */ - mem_uvm = (void *) vm_min_addr; - mpos = vm_min_addr; + /* calculate total available memory space & available pages */ + DRAM_cfg = (vaddr_t) TEXTADDR; + physmem = DRAM_cfg / PAGE_SIZE; + + /* kvm at the top */ + kmem_kvm_end = kmem_k_start - barrier_len; + kmem_kvm_start = kmem_kvm_end - KVMSIZE; /* claim an area for userland (---/R--/RW-/RWX) */ - kmem_user_start = mpos; - mpos += user_len; - kmem_user_end = mpos; - - /* calculate KVM section (RW-) */ - kmem_ext_start = round_page((vaddr_t) mem_kvm); - mpos += KVMSIZE; - kmem_ext_end = mpos; + kmem_user_start = vm_min_addr; + kmem_user_end = kmem_kvm_start - barrier_len; /* print summary */ aprint_verbose("\nMemory summary\n"); @@ -197,26 +184,31 @@ pmap_bootstrap(void) aprint_verbose("\tkmem_user_end\t%p\n", (void *) kmem_user_end); aprint_verbose("\tkmem_k_start\t%p\n", (void *) kmem_k_start); aprint_verbose("\tkmem_k_end\t%p\n", (void *) kmem_k_end); - aprint_verbose("\tkmem_ext_start\t%p\n", (void *) kmem_ext_start); - aprint_verbose("\tkmem_ext_end\t%p\n", (void *) kmem_ext_end); + aprint_verbose("\tkmem_kvm_start\t%p\n", (void *) kmem_kvm_start); + aprint_verbose("\tkmem_kvm_end\t%p\n", (void *) kmem_kvm_end); - aprint_verbose("\ttotmem_len\t%10d\n", (int) totmem_len); + aprint_verbose("\tDRAM_cfg\t%10d\n", (int) DRAM_cfg); aprint_verbose("\tkvmsize\t\t%10d\n", (int) KVMSIZE); - aprint_verbose("\tuser_len\t%10d\n", (int) user_len); + aprint_verbose("\tuser_len\t%10d\n", + (int) (kmem_user_end - kmem_user_start)); aprint_verbose("\n\n"); /* protect user memory UVM area (---) */ - err = thunk_munmap(mem_uvm, kmem_user_end - vm_min_addr); + err = thunk_munmap((void *) kmem_user_start, + kmem_k_start - kmem_user_start); if (err) panic("pmap_bootstrap: userland uvm space protection " "failed (%d)\n", thunk_geterrno()); - /* protect kvm UVM area (---) */ - err = thunk_munmap((void *) kmem_ext_start, KVMSIZE); +#if 0 + /* protect kvm UVM area if separate (---) */ + err = thunk_munmap((void *) kmem_kvm_start, + kmem_kvm_end - kmem_kvm_start); if (err) panic("pmap_bootstrap: kvm uvm space protection " "failed (%d)\n", thunk_geterrno()); +#endif thunk_printf_debug("Creating memory mapped backend\n"); @@ -230,7 +222,7 @@ pmap_bootstrap(void) panic("pmap_bootstrap: can't unlink %s", mem_name); /* file_len is the backing store length, nothing to do with placement */ - file_len = totmem_len; + file_len = DRAM_cfg; #ifdef SPARSE_MEMFILE { @@ -270,7 +262,7 @@ pmap_bootstrap(void) fpos = 0; free_start = fpos; /* in physical space ! */ free_end = file_len; /* in physical space ! */ - kmem_ext_cur_start = kmem_ext_start; + kmem_kvm_cur_start = kmem_kvm_start; /* calculate pv table size */ phys_npages = (free_end - free_start) / PAGE_SIZE; @@ -280,7 +272,7 @@ pmap_bootstrap(void) (uint64_t) pv_table_size/1024, (uintptr_t) phys_npages); /* calculate number of pmap entries needed for a complete map */ - pm_nentries = (VM_MAX_KERNEL_ADDRESS - VM_MIN_ADDRESS) / PAGE_SIZE; + pm_nentries = (kmem_k_start - VM_MIN_ADDRESS) / PAGE_SIZE; pm_entries_size = round_page(pm_nentries * sizeof(struct pv_entry *)); thunk_printf_debug("tlb va->pa lookup table is %"PRIu64" KB for " "%d logical pages\n", pm_entries_size/1024, pm_nentries); @@ -291,12 +283,12 @@ pmap_bootstrap(void) /* claim pv table */ pv_fpos = fpos; - pv_table = (struct pv_entry *) kmem_ext_cur_start; + pv_table = (struct pv_entry *) kmem_kvm_cur_start; addr = thunk_mmap(pv_table, pv_table_size, THUNK_PROT_READ | THUNK_PROT_WRITE, THUNK_MAP_FILE | THUNK_MAP_FIXED | THUNK_MAP_SHARED, mem_fh, pv_fpos); - if (addr != (void *) kmem_ext_start) + if (addr != (void *) pv_table) panic("pmap_bootstrap: can't map in pv table\n"); memset(pv_table, 0, pv_table_size); /* test and clear */ @@ -304,11 +296,11 @@ pmap_bootstrap(void) thunk_printf_debug("pv_table initialiased correctly, mmap works\n"); /* advance */ - kmem_ext_cur_start += pv_table_size; + kmem_kvm_cur_start += pv_table_size; fpos += pv_table_size; /* set up tlb space */ - tlb = (struct pv_entry **) kmem_ext_cur_start; + tlb = (struct pv_entry **) kmem_kvm_cur_start; tlb_fpos = fpos; addr = thunk_mmap(tlb, pm_entries_size, THUNK_PROT_READ | THUNK_PROT_WRITE, @@ -322,7 +314,7 @@ pmap_bootstrap(void) thunk_printf_debug("kernel tlb entries initialized correctly\n"); /* advance */ - kmem_ext_cur_start += pm_entries_size; + kmem_kvm_cur_start += pm_entries_size; fpos += pm_entries_size; /* set up kernel pmap and add a l1 map */ @@ -330,7 +322,7 @@ pmap_bootstrap(void) memset(pmap, 0, sizeof(*pmap)); pmap->pm_count = 1; /* reference */ pmap->pm_flags = PM_ACTIVE; /* kernel pmap is allways active */ - pmap->pm_l1 = (struct pmap_l2 **) kmem_ext_cur_start; + pmap->pm_l1 = (struct pmap_l2 **) kmem_kvm_cur_start; pm_l1_fpos = fpos; addr = thunk_mmap(pmap->pm_l1, pm_l1_size, @@ -345,12 +337,12 @@ pmap_bootstrap(void) thunk_printf_debug("kernel pmap l1 table initialiased correctly\n"); /* advance for l1 tables */ - kmem_ext_cur_start += round_page(pm_l1_size); + kmem_kvm_cur_start += round_page(pm_l1_size); fpos += round_page(pm_l1_size); /* followed by the pm entries */ pm_fpos = fpos; - kernel_pm_entries = (struct pv_entry **) kmem_ext_cur_start; + kernel_pm_entries = (struct pv_entry **) kmem_kvm_cur_start; addr = thunk_mmap(kernel_pm_entries, pm_entries_size, THUNK_PROT_READ | THUNK_PROT_WRITE, THUNK_MAP_FILE | THUNK_MAP_FIXED | THUNK_MAP_SHARED, @@ -361,7 +353,7 @@ pmap_bootstrap(void) memset(kernel_pm_entries, 0, pm_entries_size); /* test and clear */ /* advance for the statically allocated pm_entries */ - kmem_ext_cur_start += pm_entries_size; + kmem_kvm_cur_start += pm_entries_size; fpos += pm_entries_size; /* put pointers in the l1 to point to the pv_entry space */ @@ -371,8 +363,8 @@ pmap_bootstrap(void) ((vaddr_t) kernel_pm_entries + l1 * PMAP_L2_SIZE); } - /* kmem used [kmem_ext_start - kmem_ext_cur_start] */ - kmem_ext_cur_end = kmem_ext_cur_start; + /* kmem used [kmem_kvm_start - kmem_kvm_cur_start] */ + kmem_kvm_cur_end = kmem_kvm_cur_start; /* manually enter the mappings into the kernel map */ for (pg = 0; pg < pv_table_size; pg += PAGE_SIZE) { @@ -401,7 +393,6 @@ pmap_bootstrap(void) thunk_printf_debug("kernel pmap entries mem added to the kernel pmap\n"); /* add file space to uvm's FREELIST */ - /* XXX really from 0? or from fpos to have better stats */ uvm_page_physload(atop(0), atop(free_end), atop(free_start + fpos), /* mark used till fpos */ @@ -412,7 +403,7 @@ pmap_bootstrap(void) aprint_verbose("\t%"PRIu64" MB of physical pages left\n", (uint64_t) (free_end - (free_start + fpos))/1024/1024); aprint_verbose("\t%"PRIu64" MB of kmem left\n", - (uint64_t) (kmem_ext_end - kmem_ext_cur_end)/1024/1024); + (uint64_t) (kmem_kvm_end - kmem_kvm_cur_end)/1024/1024); setup_signal_handlers(); } @@ -426,8 +417,10 @@ pmap_init(void) void pmap_virtual_space(vaddr_t *vstartp, vaddr_t *vendp) { - *vstartp = kmem_ext_cur_start; /* min to map in */ - *vendp = kmem_ext_end; /* max available */ + if (vstartp) + *vstartp = kmem_kvm_cur_start; /* min to map in */ + if (vendp) + *vendp = kmem_kvm_end - PAGE_SIZE; /* max available */ } static void @@ -598,9 +591,10 @@ static void pmap_set_pv(pmap_t pmap, uint lpn, struct pv_entry *pv) { struct pmap_l2 *l2tbl; - int l1 = lpn / PMAP_L2_NENTRY; + int l1 = lpn / PMAP_L2_NENTRY; int l2 = lpn % PMAP_L2_NENTRY; +if (lpn >= pm_nentries) panic("peeing outside box\n"); l2tbl = pmap->pm_l1[l1]; if (!l2tbl) { l2tbl = pmap->pm_l1[l1] = pool_get(&pmap_l2_pool, PR_WAITOK); @@ -613,9 +607,10 @@ static struct pv_entry * pmap_lookup_pv(pmap_t pmap, uint lpn) { struct pmap_l2 *l2tbl; - int l1 = lpn / PMAP_L2_NENTRY; + int l1 = lpn / PMAP_L2_NENTRY; int l2 = lpn % PMAP_L2_NENTRY; +if (lpn >= pm_nentries) panic("peeing outside box\n"); l2tbl = pmap->pm_l1[l1]; if (l2tbl) return l2tbl->pm_l2[l2]; @@ -1352,10 +1347,10 @@ pmap_growkernel(vaddr_t maxkvaddr) { thunk_printf_debug("pmap_growkernel: till %p (adding %"PRIu64" KB)\n", (void *) maxkvaddr, - (uint64_t) (maxkvaddr - kmem_ext_cur_end)/1024); - if (maxkvaddr > kmem_ext_end) - return kmem_ext_end; - kmem_ext_cur_end = maxkvaddr; - return kmem_ext_cur_end; + (uint64_t) (maxkvaddr - kmem_kvm_cur_end)/1024); + if (maxkvaddr > kmem_kvm_end) + return kmem_kvm_end; + kmem_kvm_cur_end = maxkvaddr; + return kmem_kvm_cur_end; } Index: src/sys/arch/usermode/usermode/trap.c diff -u src/sys/arch/usermode/usermode/trap.c:1.51 src/sys/arch/usermode/usermode/trap.c:1.52 --- src/sys/arch/usermode/usermode/trap.c:1.51 Tue Jan 3 12:05:00 2012 +++ src/sys/arch/usermode/usermode/trap.c Tue Jan 3 21:28:50 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.51 2012/01/03 12:05:00 reinoud Exp $ */ +/* $NetBSD: trap.c,v 1.52 2012/01/03 21:28:50 reinoud Exp $ */ /*- * Copyright (c) 2011 Reinoud Zandijk <rein...@netbsd.org> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.51 2012/01/03 12:05:00 reinoud Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.52 2012/01/03 21:28:50 reinoud Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -278,7 +278,7 @@ pagefault(void) lwp_errno = thunk_geterrno(); vm_map = &vm->vm_map; - from_kernel = (pc >= VM_MIN_KERNEL_ADDRESS); + from_kernel = (pc >= kmem_k_start); if (from_kernel && (va >= VM_MIN_KERNEL_ADDRESS)) vm_map = kernel_map;