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 | |