Module Name: src Committed By: martin Date: Thu Nov 14 12:07:12 UTC 2013
Modified Files: src/sys/kern: exec_elf.c kern_exec.c kern_proc.c src/sys/rump/librump/rumpkern: vm.c src/sys/sys: exec.h src/sys/uvm: uvm_extern.h uvm_map.c Log Message: As discussed on tech-kern: make TOPDOWN-VM runtime selectable per process (offer MD code or emulations to override it). To generate a diff of this commit: cvs rdiff -u -r1.50 -r1.51 src/sys/kern/exec_elf.c cvs rdiff -u -r1.363 -r1.364 src/sys/kern/kern_exec.c cvs rdiff -u -r1.189 -r1.190 src/sys/kern/kern_proc.c cvs rdiff -u -r1.144 -r1.145 src/sys/rump/librump/rumpkern/vm.c cvs rdiff -u -r1.141 -r1.142 src/sys/sys/exec.h cvs rdiff -u -r1.184 -r1.185 src/sys/uvm/uvm_extern.h cvs rdiff -u -r1.326 -r1.327 src/sys/uvm/uvm_map.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/kern/exec_elf.c diff -u src/sys/kern/exec_elf.c:1.50 src/sys/kern/exec_elf.c:1.51 --- src/sys/kern/exec_elf.c:1.50 Mon Nov 11 15:22:11 2013 +++ src/sys/kern/exec_elf.c Thu Nov 14 12:07:11 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: exec_elf.c,v 1.50 2013/11/11 15:22:11 martin Exp $ */ +/* $NetBSD: exec_elf.c,v 1.51 2013/11/14 12:07:11 martin Exp $ */ /*- * Copyright (c) 1994, 2000, 2005 The NetBSD Foundation, Inc. @@ -57,7 +57,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.50 2013/11/11 15:22:11 martin Exp $"); +__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.51 2013/11/14 12:07:11 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_pax.h" @@ -422,14 +422,15 @@ elf_load_file(struct lwp *l, struct exec p = l->l_proc; KASSERT(p->p_vmspace); - if (__predict_true(p->p_vmspace != proc0.p_vmspace)) + if (__predict_true(p->p_vmspace != proc0.p_vmspace)) { use_topdown = p->p_vmspace->vm_map.flags & VM_MAP_TOPDOWN; - else + } else { #ifdef __USING_TOPDOWN_VM - use_topdown = true; + use_topdown = epp->ep_flags & EXEC_TOPDOWN_VM; #else use_topdown = false; #endif + } /* * 1. open file Index: src/sys/kern/kern_exec.c diff -u src/sys/kern/kern_exec.c:1.363 src/sys/kern/kern_exec.c:1.364 --- src/sys/kern/kern_exec.c:1.363 Thu Sep 12 19:01:38 2013 +++ src/sys/kern/kern_exec.c Thu Nov 14 12:07:11 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_exec.c,v 1.363 2013/09/12 19:01:38 christos Exp $ */ +/* $NetBSD: kern_exec.c,v 1.364 2013/11/14 12:07:11 martin Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -59,7 +59,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.363 2013/09/12 19:01:38 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.364 2013/11/14 12:07:11 martin Exp $"); #include "opt_exec.h" #include "opt_execfmt.h" @@ -112,6 +112,15 @@ __KERNEL_RCSID(0, "$NetBSD: kern_exec.c, #include <compat/common/compat_util.h> +#ifndef MD_TOPDOWN_INIT +#error MD_TOPDOWN_INIT fehlt +#ifdef __USING_TOPDOWN_VM +#define MD_TOPDOWN_INIT(epp) (epp)->ep_flags |= EXEC_TOPDOWN_VM +#else +#define MD_TOPDOWN_INIT(epp) +#endif +#endif + static int exec_sigcode_map(struct proc *, const struct emul *); #ifdef DEBUG_EXEC @@ -653,6 +662,7 @@ execve_loadvm(struct lwp *l, const char data->ed_pack.ep_vmcmds.evs_used = 0; data->ed_pack.ep_vap = &data->ed_attr; data->ed_pack.ep_flags = 0; + MD_TOPDOWN_INIT(&data->ed_pack); data->ed_pack.ep_emul_root = NULL; data->ed_pack.ep_interp = NULL; data->ed_pack.ep_esch = NULL; @@ -933,10 +943,12 @@ execve_runproc(struct lwp *l, struct exe */ if (is_spawn) uvmspace_spawn(l, data->ed_pack.ep_vm_minaddr, - data->ed_pack.ep_vm_maxaddr); + data->ed_pack.ep_vm_maxaddr, + data->ed_pack.ep_flags & EXEC_TOPDOWN_VM); else uvmspace_exec(l, data->ed_pack.ep_vm_minaddr, - data->ed_pack.ep_vm_maxaddr); + data->ed_pack.ep_vm_maxaddr, + data->ed_pack.ep_flags & EXEC_TOPDOWN_VM); /* record proc's vnode, for use by procfs and others */ if (p->p_textvp) Index: src/sys/kern/kern_proc.c diff -u src/sys/kern/kern_proc.c:1.189 src/sys/kern/kern_proc.c:1.190 --- src/sys/kern/kern_proc.c:1.189 Fri Oct 25 15:52:57 2013 +++ src/sys/kern/kern_proc.c Thu Nov 14 12:07:11 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_proc.c,v 1.189 2013/10/25 15:52:57 martin Exp $ */ +/* $NetBSD: kern_proc.c,v 1.190 2013/11/14 12:07:11 martin Exp $ */ /*- * Copyright (c) 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.189 2013/10/25 15:52:57 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.190 2013/11/14 12:07:11 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_kstack.h" @@ -483,7 +483,13 @@ proc0_init(void) * share proc0's vmspace, and thus, the kernel pmap. */ uvmspace_init(&vmspace0, pmap_kernel(), round_page(VM_MIN_ADDRESS), - trunc_page(VM_MAX_ADDRESS)); + trunc_page(VM_MAX_ADDRESS), +#ifdef __USING_TOPDOWN_VM + true +#else + false +#endif + ); /* Initialize signal state for proc0. XXX IPL_SCHED */ mutex_init(&p->p_sigacts->sa_mutex, MUTEX_DEFAULT, IPL_SCHED); Index: src/sys/rump/librump/rumpkern/vm.c diff -u src/sys/rump/librump/rumpkern/vm.c:1.144 src/sys/rump/librump/rumpkern/vm.c:1.145 --- src/sys/rump/librump/rumpkern/vm.c:1.144 Tue Apr 30 16:03:44 2013 +++ src/sys/rump/librump/rumpkern/vm.c Thu Nov 14 12:07:11 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: vm.c,v 1.144 2013/04/30 16:03:44 pooka Exp $ */ +/* $NetBSD: vm.c,v 1.145 2013/11/14 12:07:11 martin Exp $ */ /* * Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved. @@ -41,7 +41,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.144 2013/04/30 16:03:44 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.145 2013/11/14 12:07:11 martin Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -363,7 +363,8 @@ uvm_init(void) } void -uvmspace_init(struct vmspace *vm, struct pmap *pmap, vaddr_t vmin, vaddr_t vmax) +uvmspace_init(struct vmspace *vm, struct pmap *pmap, vaddr_t vmin, vaddr_t vmax, + bool topdown) { vm->vm_map.pmap = pmap_kernel(); Index: src/sys/sys/exec.h diff -u src/sys/sys/exec.h:1.141 src/sys/sys/exec.h:1.142 --- src/sys/sys/exec.h:1.141 Wed Oct 30 23:32:30 2013 +++ src/sys/sys/exec.h Thu Nov 14 12:07:11 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: exec.h,v 1.141 2013/10/30 23:32:30 joerg Exp $ */ +/* $NetBSD: exec.h,v 1.142 2013/11/14 12:07:11 martin Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -226,6 +226,7 @@ struct exec_package { #define EXEC_DESTR 0x0010 /* destructive ops performed */ #define EXEC_32 0x0020 /* 32-bit binary emulation */ #define EXEC_FORCEAUX 0x0040 /* always use ELF AUX vector */ +#define EXEC_TOPDOWN_VM 0x0080 /* may use top-down VM layout */ struct exec_vmcmd { int (*ev_proc)(struct lwp *, struct exec_vmcmd *); Index: src/sys/uvm/uvm_extern.h diff -u src/sys/uvm/uvm_extern.h:1.184 src/sys/uvm/uvm_extern.h:1.185 --- src/sys/uvm/uvm_extern.h:1.184 Sat Sep 1 00:26:37 2012 +++ src/sys/uvm/uvm_extern.h Thu Nov 14 12:07:11 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_extern.h,v 1.184 2012/09/01 00:26:37 matt Exp $ */ +/* $NetBSD: uvm_extern.h,v 1.185 2013/11/14 12:07:11 martin Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -643,11 +643,11 @@ bool uvm_map_checkprot(struct vm_map * vaddr_t, vm_prot_t); int uvm_map_protect(struct vm_map *, vaddr_t, vaddr_t, vm_prot_t, bool); -struct vmspace *uvmspace_alloc(vaddr_t, vaddr_t); +struct vmspace *uvmspace_alloc(vaddr_t, vaddr_t, bool); void uvmspace_init(struct vmspace *, struct pmap *, - vaddr_t, vaddr_t); -void uvmspace_exec(struct lwp *, vaddr_t, vaddr_t); -void uvmspace_spawn(struct lwp *, vaddr_t, vaddr_t); + vaddr_t, vaddr_t, bool); +void uvmspace_exec(struct lwp *, vaddr_t, vaddr_t, bool); +void uvmspace_spawn(struct lwp *, vaddr_t, vaddr_t, bool); struct vmspace *uvmspace_fork(struct vmspace *); void uvmspace_addref(struct vmspace *); void uvmspace_free(struct vmspace *); Index: src/sys/uvm/uvm_map.c diff -u src/sys/uvm/uvm_map.c:1.326 src/sys/uvm/uvm_map.c:1.327 --- src/sys/uvm/uvm_map.c:1.326 Fri Oct 25 20:25:25 2013 +++ src/sys/uvm/uvm_map.c Thu Nov 14 12:07:11 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_map.c,v 1.326 2013/10/25 20:25:25 martin Exp $ */ +/* $NetBSD: uvm_map.c,v 1.327 2013/11/14 12:07:11 martin Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.326 2013/10/25 20:25:25 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.327 2013/11/14 12:07:11 martin Exp $"); #include "opt_ddb.h" #include "opt_uvmhist.h" @@ -3927,13 +3927,13 @@ uvm_map_checkprot(struct vm_map *map, va * - refcnt set to 1, rest must be init'd by caller */ struct vmspace * -uvmspace_alloc(vaddr_t vmin, vaddr_t vmax) +uvmspace_alloc(vaddr_t vmin, vaddr_t vmax, bool topdown) { struct vmspace *vm; UVMHIST_FUNC("uvmspace_alloc"); UVMHIST_CALLED(maphist); vm = pool_cache_get(&uvm_vmspace_cache, PR_WAITOK); - uvmspace_init(vm, NULL, vmin, vmax); + uvmspace_init(vm, NULL, vmin, vmax, topdown); UVMHIST_LOG(maphist,"<- done (vm=0x%x)", vm,0,0,0); return (vm); } @@ -3945,15 +3945,14 @@ uvmspace_alloc(vaddr_t vmin, vaddr_t vma * - refcnt set to 1, rest must be init'd by caller */ void -uvmspace_init(struct vmspace *vm, struct pmap *pmap, vaddr_t vmin, vaddr_t vmax) +uvmspace_init(struct vmspace *vm, struct pmap *pmap, vaddr_t vmin, + vaddr_t vmax, bool topdown) { UVMHIST_FUNC("uvmspace_init"); UVMHIST_CALLED(maphist); memset(vm, 0, sizeof(*vm)); uvm_map_setup(&vm->vm_map, vmin, vmax, VM_MAP_PAGEABLE -#ifdef __USING_TOPDOWN_VM - | VM_MAP_TOPDOWN -#endif + | (topdown ? VM_MAP_TOPDOWN : 0) ); if (pmap) pmap_reference(pmap); @@ -4016,7 +4015,7 @@ uvmspace_unshare(struct lwp *l) */ void -uvmspace_spawn(struct lwp *l, vaddr_t start, vaddr_t end) +uvmspace_spawn(struct lwp *l, vaddr_t start, vaddr_t end, bool topdown) { struct proc *p = l->l_proc; struct vmspace *nvm; @@ -4025,7 +4024,7 @@ uvmspace_spawn(struct lwp *l, vaddr_t st cpu_vmspace_exec(l, start, end); #endif - nvm = uvmspace_alloc(start, end); + nvm = uvmspace_alloc(start, end, topdown); kpreempt_disable(); p->p_vmspace = nvm; pmap_activate(l); @@ -4037,7 +4036,7 @@ uvmspace_spawn(struct lwp *l, vaddr_t st */ void -uvmspace_exec(struct lwp *l, vaddr_t start, vaddr_t end) +uvmspace_exec(struct lwp *l, vaddr_t start, vaddr_t end, bool topdown) { struct proc *p = l->l_proc; struct vmspace *nvm, *ovm = p->p_vmspace; @@ -4053,11 +4052,14 @@ uvmspace_exec(struct lwp *l, vaddr_t sta * see if more than one process is using this vmspace... */ - if (ovm->vm_refcnt == 1) { + if (ovm->vm_refcnt == 1 + && topdown == ((ovm->vm_map.flags & VM_MAP_TOPDOWN) != 0)) { /* * if p is the only process using its vmspace then we can safely * recycle that vmspace for the program that is being exec'd. + * But only if TOPDOWN matches the requested value for the new + * vm space! */ #ifdef SYSVSHM @@ -4099,7 +4101,7 @@ uvmspace_exec(struct lwp *l, vaddr_t sta * for p */ - nvm = uvmspace_alloc(start, end); + nvm = uvmspace_alloc(start, end, topdown); /* * install new vmspace and drop our ref to the old one. @@ -4203,7 +4205,8 @@ uvmspace_fork(struct vmspace *vm1) vm_map_lock(old_map); - vm2 = uvmspace_alloc(vm_map_min(old_map), vm_map_max(old_map)); + vm2 = uvmspace_alloc(vm_map_min(old_map), vm_map_max(old_map), + vm1->vm_map.flags & VM_MAP_TOPDOWN); memcpy(&vm2->vm_startcopy, &vm1->vm_startcopy, (char *) (vm1 + 1) - (char *) &vm1->vm_startcopy); new_map = &vm2->vm_map; /* XXX */