summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vm/vm_mmap.c')
-rw-r--r--sys/vm/vm_mmap.c204
1 files changed, 177 insertions, 27 deletions
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 697baf6..ff0e79c 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -38,7 +38,7 @@
* from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
*
* @(#)vm_mmap.c 8.4 (Berkeley) 1/12/94
- * $Id: vm_mmap.c,v 1.43 1996/05/19 07:36:49 dyson Exp $
+ * $Id: vm_mmap.c,v 1.44 1996/05/31 00:38:00 dyson Exp $
*/
/*
@@ -72,6 +72,7 @@
#include <vm/vm_extern.h>
#include <vm/vm_kern.h>
#include <vm/vm_page.h>
+#include <vm/loadaout.h>
#ifndef _SYS_SYSPROTO_H_
struct sbrk_args {
@@ -689,10 +690,10 @@ mincore(p, uap, retval)
if (m) {
mincoreinfo = MINCORE_INCORE;
if (m->dirty ||
- pmap_is_modified(VM_PAGE_TO_PHYS(m)))
+ pmap_tc_modified(m))
mincoreinfo |= MINCORE_MODIFIED_OTHER;
if ((m->flags & PG_REFERENCED) ||
- pmap_is_referenced(VM_PAGE_TO_PHYS(m)))
+ pmap_tc_referenced(VM_PAGE_TO_PHYS(m)))
mincoreinfo |= MINCORE_REFERENCED_OTHER;
}
}
@@ -844,7 +845,7 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
vm_ooffset_t foff;
{
boolean_t fitit;
- vm_object_t object, object2;
+ vm_object_t object;
struct vnode *vp = NULL;
objtype_t type;
int rv = KERN_SUCCESS;
@@ -916,29 +917,13 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
flags |= MAP_SHARED;
}
- object2 = NULL;
docow = 0;
if ((flags & (MAP_ANON|MAP_SHARED)) == 0) {
- docow = MAP_COPY_ON_WRITE;
- if (objsize < size) {
- object2 = vm_object_allocate( OBJT_DEFAULT,
- OFF_TO_IDX(size - (foff & ~PAGE_MASK)));
- object2->backing_object = object;
- object2->backing_object_offset = foff;
- TAILQ_INSERT_TAIL(&object->shadow_head,
- object2, shadow_list);
- ++object->shadow_count;
- } else {
- docow |= MAP_COPY_NEEDED;
- }
+ docow = MAP_COPY_ON_WRITE|MAP_COPY_NEEDED;
}
- if (object2)
- rv = vm_map_find(map, object2, 0, addr, size, fitit,
- prot, maxprot, docow);
- else
- rv = vm_map_find(map, object, foff, addr, size, fitit,
- prot, maxprot, docow);
+ rv = vm_map_find(map, object, foff, addr, size, fitit,
+ prot, maxprot, docow);
if (rv != KERN_SUCCESS) {
@@ -947,10 +932,7 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
* object if it's an unnamed anonymous mapping
* or named anonymous without other references.
*/
- if (object2)
- vm_object_deallocate(object2);
- else
- vm_object_deallocate(object);
+ vm_object_deallocate(object);
goto out;
}
@@ -985,3 +967,171 @@ out:
return (EINVAL);
}
}
+
+#ifdef notyet
+/*
+ * Efficient mapping of a .text+.data+.bss object
+ */
+int
+vm_mapaout(map, baseaddr, vp, foff, textsize, datasize, bsssize, addr)
+ vm_map_t map;
+ vm_offset_t baseaddr;
+ struct vnode *vp;
+ vm_ooffset_t foff;
+ register vm_size_t textsize, datasize, bsssize;
+ vm_offset_t *addr;
+{
+ vm_object_t object;
+ int rv;
+ vm_pindex_t objpsize;
+ struct proc *p = curproc;
+
+ vm_size_t totalsize;
+ vm_size_t textend;
+ struct vattr vat;
+ int error;
+
+ textsize = round_page(textsize);
+ datasize = round_page(datasize);
+ bsssize = round_page(bsssize);
+ totalsize = textsize + datasize + bsssize;
+
+ vm_map_lock(map);
+ /*
+ * If baseaddr == -1, then we need to search for space. Otherwise,
+ * we need to be loaded into a certain spot.
+ */
+ if (baseaddr != (vm_offset_t) -1) {
+ if (vm_map_findspace(map, baseaddr, totalsize, addr)) {
+ goto outnomem;
+ }
+
+ if(*addr != baseaddr) {
+ goto outnomem;
+ }
+ } else {
+ baseaddr = round_page(p->p_vmspace->vm_daddr + MAXDSIZ);
+ if (vm_map_findspace(map, baseaddr, totalsize, addr)) {
+ goto outnomem;
+ }
+ }
+
+ if (foff & PAGE_MASK) {
+ vm_map_unlock(map);
+ return EINVAL;
+ }
+
+ /*
+ * get the object size to allocate
+ */
+ error = VOP_GETATTR(vp, &vat, p->p_ucred, p);
+ if (error) {
+ vm_map_unlock(map);
+ return error;
+ }
+ objpsize = OFF_TO_IDX(round_page(vat.va_size));
+
+ /*
+ * Alloc/reference the object
+ */
+ object = vm_pager_allocate(OBJT_VNODE, vp,
+ objpsize, VM_PROT_ALL, foff);
+ if (object == NULL) {
+ goto outnomem;
+ }
+
+ /*
+ * Insert .text into the map
+ */
+ textend = *addr + textsize;
+ rv = vm_map_insert(map, object, foff,
+ *addr, textend,
+ VM_PROT_READ|VM_PROT_EXECUTE, VM_PROT_ALL,
+ MAP_COPY_ON_WRITE|MAP_COPY_NEEDED);
+ if (rv != KERN_SUCCESS) {
+ vm_object_deallocate(object);
+ goto out;
+ }
+
+ /*
+ * Insert .data into the map, if there is any to map.
+ */
+ if (datasize != 0) {
+ object->ref_count++;
+ rv = vm_map_insert(map, object, foff + textsize,
+ textend, textend + datasize,
+ VM_PROT_ALL, VM_PROT_ALL,
+ MAP_COPY_ON_WRITE|MAP_COPY_NEEDED);
+ if (rv != KERN_SUCCESS) {
+ --object->ref_count;
+ vm_map_delete(map, *addr, textend);
+ goto out;
+ }
+ }
+
+ /*
+ * Preload the page tables
+ */
+ pmap_object_init_pt(map->pmap, *addr,
+ object, (vm_pindex_t) OFF_TO_IDX(foff),
+ textsize + datasize, 1);
+
+ /*
+ * Get the space for bss.
+ */
+ if (bsssize != 0) {
+ rv = vm_map_insert(map, NULL, 0,
+ textend + datasize,
+ *addr + totalsize,
+ VM_PROT_ALL, VM_PROT_ALL, 0);
+ }
+ if (rv != KERN_SUCCESS) {
+ vm_map_delete(map, *addr, textend + datasize + bsssize);
+ }
+
+out:
+ vm_map_unlock(map);
+ switch (rv) {
+ case KERN_SUCCESS:
+ return 0;
+ case KERN_INVALID_ADDRESS:
+ case KERN_NO_SPACE:
+ return ENOMEM;
+ case KERN_PROTECTION_FAILURE:
+ return EACCES;
+ default:
+ return EINVAL;
+ }
+outnomem:
+ vm_map_unlock(map);
+ return ENOMEM;
+}
+
+
+int
+mapaout(struct proc *p, struct mapaout_args *uap, int *retval)
+{
+
+ register struct filedesc *fdp = p->p_fd;
+ struct file *fp;
+ struct vnode *vp;
+ int rtval;
+
+ if (((unsigned) uap->fd) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[uap->fd]) == NULL)
+ return (EBADF);
+ if (fp->f_type != DTYPE_VNODE)
+ return (EINVAL);
+
+ vp = (struct vnode *) fp->f_data;
+ if ((vp->v_type != VREG) && (vp->v_type != VCHR))
+ return (EINVAL);
+
+ rtval = vm_mapaout( &p->p_vmspace->vm_map,
+ uap->addr, vp, uap->offset,
+ uap->textsize, uap->datasize, uap->bsssize,
+ (vm_offset_t *)retval);
+
+ return rtval;
+}
+#endif
OpenPOWER on IntegriCloud