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;
 

Reply via email to