summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/amd64/amd64/pmap.c11
-rw-r--r--sys/i386/i386/pmap.c11
-rw-r--r--sys/i386/ibcs2/imgact_coff.c5
-rw-r--r--sys/i386/linux/imgact_linux.c5
-rw-r--r--sys/kern/imgact_aout.c9
-rw-r--r--sys/kern/imgact_elf.c6
-rw-r--r--sys/kern/imgact_gzip.c6
-rw-r--r--sys/kern/kern_exec.c4
-rw-r--r--sys/kern/kern_fork.c48
-rw-r--r--sys/vm/pmap.h3
-rw-r--r--sys/vm/vm_extern.h4
-rw-r--r--sys/vm/vm_glue.c12
-rw-r--r--sys/vm/vm_map.c54
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
OpenPOWER on IntegriCloud