diff options
-rw-r--r-- | sys/amd64/amd64/pmap.c | 11 | ||||
-rw-r--r-- | sys/i386/i386/pmap.c | 11 | ||||
-rw-r--r-- | sys/i386/ibcs2/imgact_coff.c | 5 | ||||
-rw-r--r-- | sys/i386/linux/imgact_linux.c | 5 | ||||
-rw-r--r-- | sys/kern/imgact_aout.c | 9 | ||||
-rw-r--r-- | sys/kern/imgact_elf.c | 6 | ||||
-rw-r--r-- | sys/kern/imgact_gzip.c | 6 | ||||
-rw-r--r-- | sys/kern/kern_exec.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 48 | ||||
-rw-r--r-- | sys/vm/pmap.h | 3 | ||||
-rw-r--r-- | sys/vm/vm_extern.h | 4 | ||||
-rw-r--r-- | sys/vm/vm_glue.c | 12 | ||||
-rw-r--r-- | sys/vm/vm_map.c | 54 |
13 files changed, 153 insertions, 25 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index d7f531b..fc83e69 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -39,7 +39,7 @@ * SUCH DAMAGE. * * from: @(#)pmap.c 7.7 (Berkeley) 5/12/91 - * $Id: pmap.c,v 1.138 1997/02/22 09:32:40 peter Exp $ + * $Id: pmap.c,v 1.139 1997/04/07 07:15:52 peter Exp $ */ /* @@ -94,6 +94,8 @@ #include <vm/vm_pageout.h> #include <vm/vm_pager.h> +#include <sys/user.h> + #include <machine/pcb.h> #include <machine/cputypes.h> #include <machine/md_var.h> @@ -2966,6 +2968,13 @@ pmap_mincore(pmap, addr) return val; } +void +pmap_activate(struct proc *p) +{ + load_cr3(p->p_addr->u_pcb.pcb_cr3 = + vtophys(p->p_vmspace->vm_pmap.pm_pdir)); +} + #if defined(PMAP_DEBUG) pmap_pid_dump(int pid) { pmap_t pmap; diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index d7f531b..fc83e69 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -39,7 +39,7 @@ * SUCH DAMAGE. * * from: @(#)pmap.c 7.7 (Berkeley) 5/12/91 - * $Id: pmap.c,v 1.138 1997/02/22 09:32:40 peter Exp $ + * $Id: pmap.c,v 1.139 1997/04/07 07:15:52 peter Exp $ */ /* @@ -94,6 +94,8 @@ #include <vm/vm_pageout.h> #include <vm/vm_pager.h> +#include <sys/user.h> + #include <machine/pcb.h> #include <machine/cputypes.h> #include <machine/md_var.h> @@ -2966,6 +2968,13 @@ pmap_mincore(pmap, addr) return val; } +void +pmap_activate(struct proc *p) +{ + load_cr3(p->p_addr->u_pcb.pcb_cr3 = + vtophys(p->p_vmspace->vm_pmap.pm_pdir)); +} + #if defined(PMAP_DEBUG) pmap_pid_dump(int pid) { pmap_t pmap; diff --git a/sys/i386/ibcs2/imgact_coff.c b/sys/i386/ibcs2/imgact_coff.c index 7cbe5d4..3012603 100644 --- a/sys/i386/ibcs2/imgact_coff.c +++ b/sys/i386/ibcs2/imgact_coff.c @@ -26,7 +26,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: imgact_coff.c,v 1.22 1997/03/23 03:34:09 bde Exp $ + * $Id: imgact_coff.c,v 1.23 1997/04/01 08:39:01 bde Exp $ */ #include <sys/param.h> @@ -299,7 +299,7 @@ exec_coff_imgact(imgp) const struct aouthdr *ahdr; const struct scnhdr *scns; int i; - struct vmspace *vmspace = imgp->proc->p_vmspace; + struct vmspace *vmspace; int nscns; int error; unsigned long text_offset = 0, text_address = 0, text_size = 0; @@ -339,6 +339,7 @@ exec_coff_imgact(imgp) } exec_new_vmspace(imgp); + vmspace = imgp->proc->p_vmspace; for (i = 0; i < nscns; i++) { diff --git a/sys/i386/linux/imgact_linux.c b/sys/i386/linux/imgact_linux.c index 2351c84..4aae9f5 100644 --- a/sys/i386/linux/imgact_linux.c +++ b/sys/i386/linux/imgact_linux.c @@ -28,7 +28,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: imgact_linux.c,v 1.20 1997/02/22 09:38:18 peter Exp $ + * $Id: imgact_linux.c,v 1.21 1997/04/01 08:39:05 bde Exp $ */ #ifndef LKM @@ -65,7 +65,7 @@ exec_linux_imgact(imgp) struct image_params *imgp; { const struct exec *a_out = (const struct exec *) imgp->image_header; - struct vmspace *vmspace = imgp->proc->p_vmspace; + struct vmspace *vmspace; vm_offset_t vmaddr; unsigned long virtual_offset, file_offset; vm_offset_t buffer; @@ -122,6 +122,7 @@ exec_linux_imgact(imgp) * Destroy old process VM and create a new one (with a new stack) */ exec_new_vmspace(imgp); + vmspace = imgp->proc->p_vmspace; /* * Check if file_offset page aligned,. diff --git a/sys/kern/imgact_aout.c b/sys/kern/imgact_aout.c index 4adbd05..a229720 100644 --- a/sys/kern/imgact_aout.c +++ b/sys/kern/imgact_aout.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: imgact_aout.c,v 1.33 1997/02/22 09:38:55 peter Exp $ */ #include "opt_rlimit.h" @@ -55,7 +55,7 @@ exec_aout_imgact(imgp) struct image_params *imgp; { const struct exec *a_out = (const struct exec *) imgp->image_header; - struct vmspace *vmspace = imgp->proc->p_vmspace; + struct vmspace *vmspace; vm_offset_t vmaddr; unsigned long virtual_offset; unsigned long file_offset; @@ -147,6 +147,11 @@ exec_aout_imgact(imgp) exec_new_vmspace(imgp); /* + * The vm space can be changed by exec_new_vmspace + */ + vmspace = imgp->proc->p_vmspace; + + /* * Map text/data read/execute */ vmaddr = virtual_offset; diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 0934705..706ce37 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -26,7 +26,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: imgact_elf.c,v 1.17 1997/03/23 03:36:16 bde Exp $ + * $Id: imgact_elf.c,v 1.18 1997/04/01 10:41:48 bde Exp $ */ #include "opt_rlimit.h" @@ -470,7 +470,7 @@ exec_elf_imgact(struct image_params *imgp) const Elf32_Ehdr *hdr = (const Elf32_Ehdr *) imgp->image_header; const Elf32_Phdr *phdr, *mapped_phdr = NULL; Elf32_Auxargs *elf_auxargs = NULL; - struct vmspace *vmspace = imgp->proc->p_vmspace; + struct vmspace *vmspace; vm_prot_t prot = 0; u_long text_size = 0, data_size = 0; u_long text_addr = 0, data_addr = 0; @@ -527,6 +527,8 @@ exec_elf_imgact(struct image_params *imgp) exec_new_vmspace(imgp); + vmspace = imgp->proc->p_vmspace; + for (i = 0; i < hdr->e_phnum; i++) { switch(phdr[i].p_type) { diff --git a/sys/kern/imgact_gzip.c b/sys/kern/imgact_gzip.c index 9a3237f..e92db9b 100644 --- a/sys/kern/imgact_gzip.c +++ b/sys/kern/imgact_gzip.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id$ + * $Id: imgact_gzip.c,v 1.28 1997/02/22 09:38:57 peter Exp $ * * This module handles execution of a.out files which have been run through * "gzip". This saves diskspace, but wastes cpu-cycles and VM. @@ -149,7 +149,7 @@ static int do_aout_hdr(struct imgact_gzip * gz) { int error; - struct vmspace *vmspace = gz->ip->proc->p_vmspace; + struct vmspace *vmspace; vm_offset_t vmaddr; /* @@ -227,6 +227,8 @@ do_aout_hdr(struct imgact_gzip * gz) */ exec_new_vmspace(gz->ip); + vmspace = gz->ip->proc->p_vmspace; + vmaddr = gz->virtual_offset; error = vm_mmap(&vmspace->vm_map, diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 8c88134..9c6f111 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: kern_exec.c,v 1.58 1997/04/11 23:37:23 dyson Exp $ + * $Id: kern_exec.c,v 1.59 1997/04/12 04:07:50 dyson Exp $ */ #include <sys/param.h> @@ -58,6 +58,8 @@ #include <vm/vm_kern.h> #include <vm/vm_extern.h> +#include <sys/user.h> + #include <machine/reg.h> static int *exec_copyout_strings __P((struct image_params *)); diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 1c78b26..f6be206 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_fork.c 8.6 (Berkeley) 4/8/94 - * $Id: kern_fork.c,v 1.33 1997/04/07 07:16:01 peter Exp $ + * $Id: kern_fork.c,v 1.34 1997/04/07 09:38:39 peter Exp $ */ #include "opt_ktrace.h" @@ -98,7 +98,7 @@ vfork(p, uap, retval) struct vfork_args *uap; int retval[]; { - return (fork1(p, (RFFDG|RFPROC|RFPPWAIT), retval)); + return (fork1(p, (RFFDG|RFPROC|RFPPWAIT|RFMEM), retval)); } /* ARGSUSED */ @@ -129,12 +129,52 @@ fork1(p1, flags, retval) fle_p ep ; ep = fork_list; - if ((flags & RFPROC) == 0) - return (EINVAL); + if ((flags & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG)) return (EINVAL); /* + * Here we don't create a new process, but we divorce + * certain parts of a process from itself. + */ + if ((flags & RFPROC) == 0) { + + /* + * Divorce the memory, if it is shared, essentially + * this changes shared memory amongst threads, into + * COW locally. + */ + if ((flags & RFMEM) == 0) { + if (p1->p_vmspace->vm_refcnt > 1) { + vmspace_unshare(p1); + } + } + + /* + * Close all file descriptors. + */ + if (flags & RFCFDG) { + struct filedesc *fdtmp; + fdtmp = fdinit(p1); + fdfree(p1); + p1->p_fd = fdtmp; + } + + /* + * Unshare file descriptors (from parent.) + */ + if (flags & RFFDG) { + if (p1->p_fd->fd_refcnt > 1) { + struct filedesc *newfd; + newfd = fdcopy(p1); + fdfree(p1); + p1->p_fd = newfd; + } + } + return (0); + } + + /* * Although process entries are dynamically created, we still keep * a global limit on the maximum number we will create. Don't allow * a nonprivileged user to use the last process; don't let root diff --git a/sys/vm/pmap.h b/sys/vm/pmap.h index 64a7063..7a7233f 100644 --- a/sys/vm/pmap.h +++ b/sys/vm/pmap.h @@ -61,7 +61,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id$ + * $Id: pmap.h,v 1.19 1997/02/22 09:48:04 peter Exp $ */ /* @@ -129,6 +129,7 @@ void pmap_new_proc __P((struct proc *p)); void pmap_dispose_proc __P((struct proc *p)); void pmap_swapout_proc __P((struct proc *p)); void pmap_swapin_proc __P((struct proc *p)); +void pmap_activate __P((struct proc *p)); #endif /* KERNEL */ diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h index 795cfc4..4d6169c 100644 --- a/sys/vm/vm_extern.h +++ b/sys/vm/vm_extern.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)vm_extern.h 8.2 (Berkeley) 1/12/94 - * $Id: vm_extern.h,v 1.32 1997/04/06 02:30:56 dyson Exp $ + * $Id: vm_extern.h,v 1.33 1997/04/07 07:16:04 peter Exp $ */ #ifndef _VM_EXTERN_H_ @@ -88,6 +88,8 @@ void vm_set_page_size __P((void)); void vmmeter __P((void)); struct vmspace *vmspace_alloc __P((vm_offset_t, vm_offset_t, int)); struct vmspace *vmspace_fork __P((struct vmspace *)); +void vmspace_exec __P((struct proc *)); +void vmspace_unshare __P((struct proc *)); void vmspace_free __P((struct vmspace *)); void vnode_pager_setsize __P((struct vnode *, vm_ooffset_t)); void vnode_pager_umount __P((struct mount *)); diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c index 2116a0e..b49b25f 100644 --- a/sys/vm/vm_glue.c +++ b/sys/vm/vm_glue.c @@ -59,7 +59,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_glue.c,v 1.61 1997/02/22 09:48:17 peter Exp $ + * $Id: vm_glue.c,v 1.62 1997/04/07 07:16:04 peter Exp $ */ #include "opt_rlimit.h" @@ -211,14 +211,16 @@ vm_fork(p1, p2, flags) pmap_t pvp; vm_object_t upobj; + if (flags & RFMEM) { + p2->p_vmspace = p1->p_vmspace; + p1->p_vmspace->vm_refcnt++; + } + while ((cnt.v_free_count + cnt.v_cache_count) < cnt.v_free_min) { VM_WAIT; } - if (flags & RFMEM) { - p2->p_vmspace = p1->p_vmspace; - p1->p_vmspace->vm_refcnt++; - } else { + if ((flags & RFMEM) == 0) { p2->p_vmspace = vmspace_fork(p1->p_vmspace); if (p1->p_vmspace->vm_shm) diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 7a1de30..beb4c40 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -61,7 +61,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_map.c,v 1.74 1997/04/06 03:04:31 dyson Exp $ + * $Id: vm_map.c,v 1.75 1997/04/07 07:16:05 peter Exp $ */ /* @@ -2231,6 +2231,58 @@ vmspace_fork(vm1) } /* + * Unshare the specified VM space for exec. If other processes are + * mapped to it, then create a new one. The new vmspace is null. + */ + +void +vmspace_exec(struct proc *p) { + struct vmspace *oldvmspace = p->p_vmspace; + struct vmspace *newvmspace; + vm_map_t map = &p->p_vmspace->vm_map; + + newvmspace = vmspace_alloc(map->min_offset, map->max_offset, + map->entries_pageable); + bcopy(&oldvmspace->vm_startcopy, &newvmspace->vm_startcopy, + (caddr_t) (newvmspace + 1) - (caddr_t) &newvmspace->vm_startcopy); + /* + * This code is written like this for prototype purposes. The + * goal is to avoid running down the vmspace here, but let the + * other process's that are still using the vmspace to finally + * run it down. Even though there is little or no chance of blocking + * here, it is a good idea to keep this form for future mods. + */ + vm_map_reference(&oldvmspace->vm_map); + vmspace_free(oldvmspace); + p->p_vmspace = newvmspace; + if (p == curproc) + pmap_activate(p); + vm_map_deallocate(&oldvmspace->vm_map); +} + +/* + * Unshare the specified VM space for forcing COW. This + * is called by rfork, for the (RFMEM|RFPROC) == 0 case. + */ + +void +vmspace_unshare(struct proc *p) { + struct vmspace *oldvmspace = p->p_vmspace; + struct vmspace *newvmspace; + + if (oldvmspace->vm_refcnt == 1) + return; + newvmspace = vmspace_fork(oldvmspace); + vm_map_reference(&oldvmspace->vm_map); + vmspace_free(oldvmspace); + p->p_vmspace = newvmspace; + if (p == curproc) + pmap_activate(p); + vm_map_deallocate(&oldvmspace->vm_map); +} + + +/* * vm_map_lookup: * * Finds the VM object, offset, and |