Deleted Added
full compact
vm_mmap.c (17313) vm_mmap.c (17334)
1/*
2 * Copyright (c) 1988 University of Utah.
3 * Copyright (c) 1991, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * the Systems Programming Group of the University of Utah Computer
8 * Science Department.

--- 24 unchanged lines hidden (view full) ---

33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
39 *
40 * @(#)vm_mmap.c 8.4 (Berkeley) 1/12/94
1/*
2 * Copyright (c) 1988 University of Utah.
3 * Copyright (c) 1991, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * the Systems Programming Group of the University of Utah Computer
8 * Science Department.

--- 24 unchanged lines hidden (view full) ---

33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
39 *
40 * @(#)vm_mmap.c 8.4 (Berkeley) 1/12/94
41 * $Id: vm_mmap.c,v 1.47 1996/07/27 17:21:41 dyson Exp $
41 * $Id: vm_mmap.c,v 1.48 1996/07/28 02:54:09 davidg Exp $
42 */
43
44/*
45 * Mapped file (mmap) interface to VM
46 */
47
48#include <sys/param.h>
49#include <sys/systm.h>

--- 17 unchanged lines hidden (view full) ---

67#include <vm/pmap.h>
68#include <vm/vm_map.h>
69#include <vm/vm_object.h>
70#include <vm/vm_pager.h>
71#include <vm/vm_pageout.h>
72#include <vm/vm_extern.h>
73#include <vm/vm_kern.h>
74#include <vm/vm_page.h>
42 */
43
44/*
45 * Mapped file (mmap) interface to VM
46 */
47
48#include <sys/param.h>
49#include <sys/systm.h>

--- 17 unchanged lines hidden (view full) ---

67#include <vm/pmap.h>
68#include <vm/vm_map.h>
69#include <vm/vm_object.h>
70#include <vm/vm_pager.h>
71#include <vm/vm_pageout.h>
72#include <vm/vm_extern.h>
73#include <vm/vm_kern.h>
74#include <vm/vm_page.h>
75#include <vm/default_pager.h>
76
77#ifndef _SYS_SYSPROTO_H_
78struct sbrk_args {
79 int incr;
80};
81#endif
82
83/* ARGSUSED */

--- 601 unchanged lines hidden (view full) ---

685 pindex);
686 /*
687 * if the page is resident, then gather information about
688 * it.
689 */
690 if (m) {
691 mincoreinfo = MINCORE_INCORE;
692 if (m->dirty ||
75
76#ifndef _SYS_SYSPROTO_H_
77struct sbrk_args {
78 int incr;
79};
80#endif
81
82/* ARGSUSED */

--- 601 unchanged lines hidden (view full) ---

684 pindex);
685 /*
686 * if the page is resident, then gather information about
687 * it.
688 */
689 if (m) {
690 mincoreinfo = MINCORE_INCORE;
691 if (m->dirty ||
693 pmap_tc_modified(m))
692 pmap_is_modified(VM_PAGE_TO_PHYS(m)))
694 mincoreinfo |= MINCORE_MODIFIED_OTHER;
695 if ((m->flags & PG_REFERENCED) ||
693 mincoreinfo |= MINCORE_MODIFIED_OTHER;
694 if ((m->flags & PG_REFERENCED) ||
696 pmap_tc_referenced(VM_PAGE_TO_PHYS(m)))
695 pmap_is_referenced(VM_PAGE_TO_PHYS(m)))
697 mincoreinfo |= MINCORE_REFERENCED_OTHER;
698 }
699 }
700
701 /*
702 * calculate index into user supplied byte vector
703 */
704 vecindex = OFF_TO_IDX(addr - first_addr);

--- 135 unchanged lines hidden (view full) ---

840 register vm_offset_t *addr;
841 register vm_size_t size;
842 vm_prot_t prot, maxprot;
843 register int flags;
844 caddr_t handle; /* XXX should be vp */
845 vm_ooffset_t foff;
846{
847 boolean_t fitit;
696 mincoreinfo |= MINCORE_REFERENCED_OTHER;
697 }
698 }
699
700 /*
701 * calculate index into user supplied byte vector
702 */
703 vecindex = OFF_TO_IDX(addr - first_addr);

--- 135 unchanged lines hidden (view full) ---

839 register vm_offset_t *addr;
840 register vm_size_t size;
841 vm_prot_t prot, maxprot;
842 register int flags;
843 caddr_t handle; /* XXX should be vp */
844 vm_ooffset_t foff;
845{
846 boolean_t fitit;
848 vm_object_t object;
847 vm_object_t object, object2;
849 struct vnode *vp = NULL;
850 objtype_t type;
851 int rv = KERN_SUCCESS;
852 vm_ooffset_t objsize;
853 int docow;
854 struct proc *p = curproc;
855
856 if (size == 0)

--- 21 unchanged lines hidden (view full) ---

878 fitit = FALSE;
879 (void) vm_map_remove(map, *addr, *addr + size);
880 }
881
882 /*
883 * Lookup/allocate object.
884 */
885 if (flags & MAP_ANON) {
848 struct vnode *vp = NULL;
849 objtype_t type;
850 int rv = KERN_SUCCESS;
851 vm_ooffset_t objsize;
852 int docow;
853 struct proc *p = curproc;
854
855 if (size == 0)

--- 21 unchanged lines hidden (view full) ---

877 fitit = FALSE;
878 (void) vm_map_remove(map, *addr, *addr + size);
879 }
880
881 /*
882 * Lookup/allocate object.
883 */
884 if (flags & MAP_ANON) {
885 type = OBJT_SWAP;
886 /*
887 * Unnamed anonymous regions always start at 0.
888 */
886 /*
887 * Unnamed anonymous regions always start at 0.
888 */
889 if (handle == 0) {
889 if (handle == 0)
890 foff = 0;
890 foff = 0;
891 type = OBJT_DEFAULT;
892 } else {
893 type = OBJT_SWAP;
894 }
895 } else {
896 vp = (struct vnode *) handle;
897 if (vp->v_type == VCHR) {
898 type = OBJT_DEVICE;
899 handle = (caddr_t) vp->v_rdev;
900 } else {
901 struct vattr vat;
902 int error;
903
904 error = VOP_GETATTR(vp, &vat, p->p_ucred, p);
905 if (error)
906 return (error);
907 objsize = round_page(vat.va_size);
908 type = OBJT_VNODE;
909 }
910 }
891 } else {
892 vp = (struct vnode *) handle;
893 if (vp->v_type == VCHR) {
894 type = OBJT_DEVICE;
895 handle = (caddr_t) vp->v_rdev;
896 } else {
897 struct vattr vat;
898 int error;
899
900 error = VOP_GETATTR(vp, &vat, p->p_ucred, p);
901 if (error)
902 return (error);
903 objsize = round_page(vat.va_size);
904 type = OBJT_VNODE;
905 }
906 }
907 object = vm_pager_allocate(type, handle, OFF_TO_IDX(objsize), prot, foff);
908 if (object == NULL)
909 return (type == OBJT_DEVICE ? EINVAL : ENOMEM);
911
910
912 if (type != OBJT_DEFAULT) {
913 object = vm_pager_allocate(type, handle,
914 OFF_TO_IDX(objsize), prot, foff);
915 if (object == NULL)
916 return (type == OBJT_DEVICE ? EINVAL : ENOMEM);
917 } else {
918 object = NULL;
919 }
920
921 /*
922 * Force device mappings to be shared.
923 */
924 if (type == OBJT_DEVICE) {
925 flags &= ~(MAP_PRIVATE|MAP_COPY);
926 flags |= MAP_SHARED;
927 }
928
911 /*
912 * Force device mappings to be shared.
913 */
914 if (type == OBJT_DEVICE) {
915 flags &= ~(MAP_PRIVATE|MAP_COPY);
916 flags |= MAP_SHARED;
917 }
918
919 object2 = NULL;
929 docow = 0;
930 if ((flags & (MAP_ANON|MAP_SHARED)) == 0) {
920 docow = 0;
921 if ((flags & (MAP_ANON|MAP_SHARED)) == 0) {
931 docow = MAP_COPY_ON_WRITE|MAP_COPY_NEEDED;
922 docow = MAP_COPY_ON_WRITE;
923 if (objsize < size) {
924 object2 = vm_object_allocate( OBJT_DEFAULT,
925 OFF_TO_IDX(size - (foff & ~PAGE_MASK)));
926 object2->backing_object = object;
927 object2->backing_object_offset = foff;
928 TAILQ_INSERT_TAIL(&object->shadow_head,
929 object2, shadow_list);
930 ++object->shadow_count;
931 } else {
932 docow |= MAP_COPY_NEEDED;
933 }
932 }
933
934 }
935
934 rv = vm_map_find(map, object, foff, addr, size, fitit,
935 prot, maxprot, docow);
936 if (object2)
937 rv = vm_map_find(map, object2, 0, addr, size, fitit,
938 prot, maxprot, docow);
939 else
940 rv = vm_map_find(map, object, foff, addr, size, fitit,
941 prot, maxprot, docow);
936
942
943
937 if (rv != KERN_SUCCESS) {
938 /*
939 * Lose the object reference. Will destroy the
940 * object if it's an unnamed anonymous mapping
941 * or named anonymous without other references.
942 */
944 if (rv != KERN_SUCCESS) {
945 /*
946 * Lose the object reference. Will destroy the
947 * object if it's an unnamed anonymous mapping
948 * or named anonymous without other references.
949 */
943 vm_object_deallocate(object);
950 if (object2)
951 vm_object_deallocate(object2);
952 else
953 vm_object_deallocate(object);
944 goto out;
945 }
946
947 /*
948 * "Pre-fault" resident pages.
949 */
950 if ((type == OBJT_VNODE) && (map->pmap != NULL)) {
951 pmap_object_init_pt(map->pmap, *addr,

--- 18 unchanged lines hidden (view full) ---

970 case KERN_NO_SPACE:
971 return (ENOMEM);
972 case KERN_PROTECTION_FAILURE:
973 return (EACCES);
974 default:
975 return (EINVAL);
976 }
977}
954 goto out;
955 }
956
957 /*
958 * "Pre-fault" resident pages.
959 */
960 if ((type == OBJT_VNODE) && (map->pmap != NULL)) {
961 pmap_object_init_pt(map->pmap, *addr,

--- 18 unchanged lines hidden (view full) ---

980 case KERN_NO_SPACE:
981 return (ENOMEM);
982 case KERN_PROTECTION_FAILURE:
983 return (EACCES);
984 default:
985 return (EINVAL);
986 }
987}
978
979#ifdef notyet
980/*
981 * Efficient mapping of a .text+.data+.bss object
982 */
983int
984vm_mapaout(map, baseaddr, vp, foff, textsize, datasize, bsssize, addr)
985 vm_map_t map;
986 vm_offset_t baseaddr;
987 struct vnode *vp;
988 vm_ooffset_t foff;
989 register vm_size_t textsize, datasize, bsssize;
990 vm_offset_t *addr;
991{
992 vm_object_t object;
993 int rv;
994 vm_pindex_t objpsize;
995 struct proc *p = curproc;
996
997 vm_size_t totalsize;
998 vm_size_t textend;
999 struct vattr vat;
1000 int error;
1001
1002 textsize = round_page(textsize);
1003 datasize = round_page(datasize);
1004 bsssize = round_page(bsssize);
1005 totalsize = textsize + datasize + bsssize;
1006
1007 vm_map_lock(map);
1008 /*
1009 * If baseaddr == -1, then we need to search for space. Otherwise,
1010 * we need to be loaded into a certain spot.
1011 */
1012 if (baseaddr != (vm_offset_t) -1) {
1013 if (vm_map_findspace(map, baseaddr, totalsize, addr)) {
1014 goto outnomem;
1015 }
1016
1017 if(*addr != baseaddr) {
1018 goto outnomem;
1019 }
1020 } else {
1021 baseaddr = round_page(p->p_vmspace->vm_daddr + MAXDSIZ);
1022 if (vm_map_findspace(map, baseaddr, totalsize, addr)) {
1023 goto outnomem;
1024 }
1025 }
1026
1027 if (foff & PAGE_MASK) {
1028 vm_map_unlock(map);
1029 return EINVAL;
1030 }
1031
1032 if ((vp->v_object != 0) &&
1033 ((((vm_object_t)vp->v_object)->flags & OBJ_DEAD) == 0)) {
1034 object = vp->v_object;
1035 vm_object_reference(object);
1036 } else {
1037 /*
1038 * get the object size to allocate
1039 */
1040 error = VOP_GETATTR(vp, &vat, p->p_ucred, p);
1041 if (error) {
1042 vm_map_unlock(map);
1043 return error;
1044 }
1045 objpsize = OFF_TO_IDX(round_page(vat.va_size));
1046 /*
1047 * Alloc/reference the object
1048 */
1049 object = vm_pager_allocate(OBJT_VNODE, vp,
1050 objpsize, VM_PROT_ALL, foff);
1051 if (object == NULL) {
1052 goto outnomem;
1053 }
1054 }
1055
1056 /*
1057 * Insert .text into the map
1058 */
1059 textend = *addr + textsize;
1060 rv = vm_map_insert(map, object, foff,
1061 *addr, textend,
1062 VM_PROT_READ|VM_PROT_EXECUTE, VM_PROT_ALL,
1063 MAP_COPY_ON_WRITE|MAP_COPY_NEEDED);
1064 if (rv != KERN_SUCCESS) {
1065 vm_object_deallocate(object);
1066 goto out;
1067 }
1068
1069 /*
1070 * Insert .data into the map, if there is any to map.
1071 */
1072 if (datasize != 0) {
1073 object->ref_count++;
1074 rv = vm_map_insert(map, object, foff + textsize,
1075 textend, textend + datasize,
1076 VM_PROT_ALL, VM_PROT_ALL,
1077 MAP_COPY_ON_WRITE|MAP_COPY_NEEDED);
1078 if (rv != KERN_SUCCESS) {
1079 --object->ref_count;
1080 vm_map_delete(map, *addr, textend);
1081 goto out;
1082 }
1083 }
1084
1085 /*
1086 * Preload the page tables
1087 */
1088 pmap_object_init_pt(map->pmap, *addr,
1089 object, (vm_pindex_t) OFF_TO_IDX(foff),
1090 textsize + datasize, 1);
1091
1092 /*
1093 * Get the space for bss.
1094 */
1095 if (bsssize != 0) {
1096 rv = vm_map_insert(map, NULL, 0,
1097 textend + datasize,
1098 *addr + totalsize,
1099 VM_PROT_ALL, VM_PROT_ALL, 0);
1100 }
1101 if (rv != KERN_SUCCESS) {
1102 vm_map_delete(map, *addr, textend + datasize + bsssize);
1103 }
1104
1105out:
1106 vm_map_unlock(map);
1107 switch (rv) {
1108 case KERN_SUCCESS:
1109 return 0;
1110 case KERN_INVALID_ADDRESS:
1111 case KERN_NO_SPACE:
1112 return ENOMEM;
1113 case KERN_PROTECTION_FAILURE:
1114 return EACCES;
1115 default:
1116 return EINVAL;
1117 }
1118outnomem:
1119 vm_map_unlock(map);
1120 return ENOMEM;
1121}
1122
1123
1124int
1125mapaout(struct proc *p, struct mapaout_args *uap, int *retval)
1126{
1127
1128 register struct filedesc *fdp = p->p_fd;
1129 struct file *fp;
1130 struct vnode *vp;
1131 int rtval;
1132
1133 if (((unsigned) uap->fd) >= fdp->fd_nfiles ||
1134 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
1135 return (EBADF);
1136 if (fp->f_type != DTYPE_VNODE)
1137 return (EINVAL);
1138
1139 vp = (struct vnode *) fp->f_data;
1140 if ((vp->v_type != VREG) && (vp->v_type != VCHR))
1141 return (EINVAL);
1142
1143 rtval = vm_mapaout( &p->p_vmspace->vm_map,
1144 uap->addr, vp, uap->offset,
1145 uap->textsize, uap->datasize, uap->bsssize,
1146 (vm_offset_t *)retval);
1147
1148 return rtval;
1149}
1150#endif