Deleted Added
full compact
vm_map.c (21673) vm_map.c (21754)
1/*
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * The Mach Operating System project at Carnegie-Mellon University.
7 *
8 * Redistribution and use in source and binary forms, with or without

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

56 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
57 * School of Computer Science
58 * Carnegie Mellon University
59 * Pittsburgh PA 15213-3890
60 *
61 * any improvements or extensions that they make and grant Carnegie the
62 * rights to redistribute these changes.
63 *
1/*
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * The Mach Operating System project at Carnegie-Mellon University.
7 *
8 * Redistribution and use in source and binary forms, with or without

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

56 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
57 * School of Computer Science
58 * Carnegie Mellon University
59 * Pittsburgh PA 15213-3890
60 *
61 * any improvements or extensions that they make and grant Carnegie the
62 * rights to redistribute these changes.
63 *
64 * $FreeBSD: head/sys/vm/vm_map.c 21673 1997-01-14 07:20:47Z jkh $
64 * $FreeBSD: head/sys/vm/vm_map.c 21754 1997-01-16 04:16:22Z dyson $
65 */
66
67/*
68 * Virtual memory mapping module.
69 */
70
71#include <sys/param.h>
72#include <sys/systm.h>

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

601 vm_offset_t end;
602 vm_prot_t prot, max;
603 int cow;
604{
605 register vm_map_entry_t new_entry;
606 register vm_map_entry_t prev_entry;
607 vm_map_entry_t temp_entry;
608 vm_object_t prev_object;
65 */
66
67/*
68 * Virtual memory mapping module.
69 */
70
71#include <sys/param.h>
72#include <sys/systm.h>

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

601 vm_offset_t end;
602 vm_prot_t prot, max;
603 int cow;
604{
605 register vm_map_entry_t new_entry;
606 register vm_map_entry_t prev_entry;
607 vm_map_entry_t temp_entry;
608 vm_object_t prev_object;
609 u_char protoeflags;
609
610 if ((object != NULL) && (cow & MAP_NOFAULT)) {
611 panic("vm_map_insert: paradoxical MAP_NOFAULT request");
612 }
613
614 /*
615 * Check that the start and end points are not bogus.
616 */

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

632 /*
633 * Assert that the next entry doesn't overlap the end point.
634 */
635
636 if ((prev_entry->next != &map->header) &&
637 (prev_entry->next->start < end))
638 return (KERN_NO_SPACE);
639
610
611 if ((object != NULL) && (cow & MAP_NOFAULT)) {
612 panic("vm_map_insert: paradoxical MAP_NOFAULT request");
613 }
614
615 /*
616 * Check that the start and end points are not bogus.
617 */

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

633 /*
634 * Assert that the next entry doesn't overlap the end point.
635 */
636
637 if ((prev_entry->next != &map->header) &&
638 (prev_entry->next->start < end))
639 return (KERN_NO_SPACE);
640
641 protoeflags = 0;
642 if (cow & MAP_COPY_NEEDED)
643 protoeflags |= MAP_ENTRY_NEEDS_COPY;
644
645 if (cow & MAP_COPY_ON_WRITE)
646 protoeflags |= MAP_ENTRY_COW;
647
648 if (cow & MAP_NOFAULT)
649 protoeflags |= MAP_ENTRY_NOFAULT;
650
640 /*
641 * See if we can avoid creating a new entry by extending one of our
642 * neighbors. Or at least extend the object.
643 */
644
645 if ((object == NULL) &&
646 (prev_entry != &map->header) &&
651 /*
652 * See if we can avoid creating a new entry by extending one of our
653 * neighbors. Or at least extend the object.
654 */
655
656 if ((object == NULL) &&
657 (prev_entry != &map->header) &&
647 ( ! prev_entry->is_a_map) &&
648 ( ! prev_entry->is_sub_map) &&
658 (( prev_entry->eflags & (MAP_ENTRY_IS_A_MAP | MAP_ENTRY_IS_SUB_MAP)) == 0) &&
649 (prev_entry->end == start) &&
650 (prev_entry->wired_count == 0)) {
659 (prev_entry->end == start) &&
660 (prev_entry->wired_count == 0)) {
661
651
662
652 u_char needs_copy = (cow & MAP_COPY_NEEDED) != 0;
653 u_char copy_on_write = (cow & MAP_COPY_ON_WRITE) != 0;
654 u_char nofault = (cow & MAP_NOFAULT) != 0;
655
656 if ((needs_copy == prev_entry->needs_copy) &&
657 (copy_on_write == prev_entry->copy_on_write) &&
658 (nofault == prev_entry->nofault) &&
659 (nofault ||
663 if ((protoeflags == prev_entry->eflags) &&
664 ((cow & MAP_NOFAULT) ||
660 vm_object_coalesce(prev_entry->object.vm_object,
661 OFF_TO_IDX(prev_entry->offset),
662 (vm_size_t) (prev_entry->end - prev_entry->start),
663 (vm_size_t) (end - prev_entry->end)))) {
664
665 /*
666 * Coalesced the two objects. Can we extend the
667 * previous map entry to include the new range?
668 */
669 if ((prev_entry->inheritance == VM_INHERIT_DEFAULT) &&
670 (prev_entry->protection == prot) &&
671 (prev_entry->max_protection == max)) {
672
673 map->size += (end - prev_entry->end);
674 prev_entry->end = end;
665 vm_object_coalesce(prev_entry->object.vm_object,
666 OFF_TO_IDX(prev_entry->offset),
667 (vm_size_t) (prev_entry->end - prev_entry->start),
668 (vm_size_t) (end - prev_entry->end)))) {
669
670 /*
671 * Coalesced the two objects. Can we extend the
672 * previous map entry to include the new range?
673 */
674 if ((prev_entry->inheritance == VM_INHERIT_DEFAULT) &&
675 (prev_entry->protection == prot) &&
676 (prev_entry->max_protection == max)) {
677
678 map->size += (end - prev_entry->end);
679 prev_entry->end = end;
675 if (!nofault) {
680 if ((cow & MAP_NOFAULT) == 0) {
676 prev_object = prev_entry->object.vm_object;
677 default_pager_convert_to_swapq(prev_object);
678 }
679 return (KERN_SUCCESS);
680 }
681 else {
682 object = prev_entry->object.vm_object;
683 offset = prev_entry->offset + (prev_entry->end -

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

691 /*
692 * Create a new entry
693 */
694
695 new_entry = vm_map_entry_create(map);
696 new_entry->start = start;
697 new_entry->end = end;
698
681 prev_object = prev_entry->object.vm_object;
682 default_pager_convert_to_swapq(prev_object);
683 }
684 return (KERN_SUCCESS);
685 }
686 else {
687 object = prev_entry->object.vm_object;
688 offset = prev_entry->offset + (prev_entry->end -

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

696 /*
697 * Create a new entry
698 */
699
700 new_entry = vm_map_entry_create(map);
701 new_entry->start = start;
702 new_entry->end = end;
703
699 new_entry->is_a_map = FALSE;
700 new_entry->is_sub_map = FALSE;
704 new_entry->eflags = protoeflags;
701 new_entry->object.vm_object = object;
702 new_entry->offset = offset;
703
705 new_entry->object.vm_object = object;
706 new_entry->offset = offset;
707
704 if (cow & MAP_COPY_NEEDED)
705 new_entry->needs_copy = TRUE;
706 else
707 new_entry->needs_copy = FALSE;
708
709 if (cow & MAP_COPY_ON_WRITE)
710 new_entry->copy_on_write = TRUE;
711 else
712 new_entry->copy_on_write = FALSE;
713
714 if (cow & MAP_NOFAULT)
715 new_entry->nofault = TRUE;
716 else
717 new_entry->nofault = FALSE;
718
719 if (map->is_main_map) {
720 new_entry->inheritance = VM_INHERIT_DEFAULT;
721 new_entry->protection = prot;
722 new_entry->max_protection = max;
723 new_entry->wired_count = 0;
724 }
725 /*
726 * Insert the new entry into the list

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

854void
855vm_map_simplify_entry(map, entry)
856 vm_map_t map;
857 vm_map_entry_t entry;
858{
859 vm_map_entry_t next, prev;
860 vm_size_t prevsize, esize;
861
708 if (map->is_main_map) {
709 new_entry->inheritance = VM_INHERIT_DEFAULT;
710 new_entry->protection = prot;
711 new_entry->max_protection = max;
712 new_entry->wired_count = 0;
713 }
714 /*
715 * Insert the new entry into the list

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

843void
844vm_map_simplify_entry(map, entry)
845 vm_map_t map;
846 vm_map_entry_t entry;
847{
848 vm_map_entry_t next, prev;
849 vm_size_t prevsize, esize;
850
862 if (entry->is_sub_map || entry->is_a_map)
851 if (entry->eflags & (MAP_ENTRY_IS_SUB_MAP|MAP_ENTRY_IS_A_MAP))
863 return;
864
865 prev = entry->prev;
866 if (prev != &map->header) {
867 prevsize = prev->end - prev->start;
868 if ( (prev->end == entry->start) &&
869 (prev->object.vm_object == entry->object.vm_object) &&
870 (!prev->object.vm_object || (prev->object.vm_object->behavior == entry->object.vm_object->behavior)) &&
871 (!prev->object.vm_object ||
872 (prev->offset + prevsize == entry->offset)) &&
852 return;
853
854 prev = entry->prev;
855 if (prev != &map->header) {
856 prevsize = prev->end - prev->start;
857 if ( (prev->end == entry->start) &&
858 (prev->object.vm_object == entry->object.vm_object) &&
859 (!prev->object.vm_object || (prev->object.vm_object->behavior == entry->object.vm_object->behavior)) &&
860 (!prev->object.vm_object ||
861 (prev->offset + prevsize == entry->offset)) &&
873 (prev->needs_copy == entry->needs_copy) &&
874 (prev->copy_on_write == entry->copy_on_write) &&
862 (prev->eflags == entry->eflags) &&
875 (prev->protection == entry->protection) &&
876 (prev->max_protection == entry->max_protection) &&
877 (prev->inheritance == entry->inheritance) &&
863 (prev->protection == entry->protection) &&
864 (prev->max_protection == entry->max_protection) &&
865 (prev->inheritance == entry->inheritance) &&
878 (prev->is_a_map == FALSE) &&
879 (prev->is_sub_map == FALSE) &&
880 (prev->wired_count == entry->wired_count)) {
881 if (map->first_free == prev)
882 map->first_free = entry;
883 if (map->hint == prev)
884 map->hint = entry;
885 vm_map_entry_unlink(map, prev);
886 entry->start = prev->start;
887 entry->offset = prev->offset;

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

894 next = entry->next;
895 if (next != &map->header) {
896 esize = entry->end - entry->start;
897 if ((entry->end == next->start) &&
898 (next->object.vm_object == entry->object.vm_object) &&
899 (!next->object.vm_object || (next->object.vm_object->behavior == entry->object.vm_object->behavior)) &&
900 (!entry->object.vm_object ||
901 (entry->offset + esize == next->offset)) &&
866 (prev->wired_count == entry->wired_count)) {
867 if (map->first_free == prev)
868 map->first_free = entry;
869 if (map->hint == prev)
870 map->hint = entry;
871 vm_map_entry_unlink(map, prev);
872 entry->start = prev->start;
873 entry->offset = prev->offset;

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

880 next = entry->next;
881 if (next != &map->header) {
882 esize = entry->end - entry->start;
883 if ((entry->end == next->start) &&
884 (next->object.vm_object == entry->object.vm_object) &&
885 (!next->object.vm_object || (next->object.vm_object->behavior == entry->object.vm_object->behavior)) &&
886 (!entry->object.vm_object ||
887 (entry->offset + esize == next->offset)) &&
902 (next->needs_copy == entry->needs_copy) &&
903 (next->copy_on_write == entry->copy_on_write) &&
888 (next->eflags == entry->eflags) &&
904 (next->protection == entry->protection) &&
905 (next->max_protection == entry->max_protection) &&
906 (next->inheritance == entry->inheritance) &&
889 (next->protection == entry->protection) &&
890 (next->max_protection == entry->max_protection) &&
891 (next->inheritance == entry->inheritance) &&
907 (next->is_a_map == FALSE) &&
908 (next->is_sub_map == FALSE) &&
909 (next->wired_count == entry->wired_count)) {
910 if (map->first_free == next)
911 map->first_free = entry;
912 if (map->hint == next)
913 map->hint = entry;
914 vm_map_entry_unlink(map, next);
915 entry->end = next->end;
916 if (next->object.vm_object)

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

956 *new_entry = *entry;
957
958 new_entry->end = start;
959 entry->offset += (start - entry->start);
960 entry->start = start;
961
962 vm_map_entry_link(map, entry->prev, new_entry);
963
892 (next->wired_count == entry->wired_count)) {
893 if (map->first_free == next)
894 map->first_free = entry;
895 if (map->hint == next)
896 map->hint = entry;
897 vm_map_entry_unlink(map, next);
898 entry->end = next->end;
899 if (next->object.vm_object)

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

939 *new_entry = *entry;
940
941 new_entry->end = start;
942 entry->offset += (start - entry->start);
943 entry->start = start;
944
945 vm_map_entry_link(map, entry->prev, new_entry);
946
964 if (entry->is_a_map || entry->is_sub_map)
947 if (entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP))
965 vm_map_reference(new_entry->object.share_map);
966 else
967 vm_object_reference(new_entry->object.vm_object);
968}
969
970/*
971 * vm_map_clip_end: [ internal use only ]
972 *

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

1000 new_entry = vm_map_entry_create(map);
1001 *new_entry = *entry;
1002
1003 new_entry->start = entry->end = end;
1004 new_entry->offset += (end - entry->start);
1005
1006 vm_map_entry_link(map, entry, new_entry);
1007
948 vm_map_reference(new_entry->object.share_map);
949 else
950 vm_object_reference(new_entry->object.vm_object);
951}
952
953/*
954 * vm_map_clip_end: [ internal use only ]
955 *

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

983 new_entry = vm_map_entry_create(map);
984 *new_entry = *entry;
985
986 new_entry->start = entry->end = end;
987 new_entry->offset += (end - entry->start);
988
989 vm_map_entry_link(map, entry, new_entry);
990
1008 if (entry->is_a_map || entry->is_sub_map)
991 if (entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP))
1009 vm_map_reference(new_entry->object.share_map);
1010 else
1011 vm_object_reference(new_entry->object.vm_object);
1012}
1013
1014/*
1015 * VM_MAP_RANGE_CHECK: [ internal use only ]
1016 *

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

1062 if (vm_map_lookup_entry(map, start, &entry)) {
1063 vm_map_clip_start(map, entry, start);
1064 } else
1065 entry = entry->next;
1066
1067 vm_map_clip_end(map, entry, end);
1068
1069 if ((entry->start == start) && (entry->end == end) &&
992 vm_map_reference(new_entry->object.share_map);
993 else
994 vm_object_reference(new_entry->object.vm_object);
995}
996
997/*
998 * VM_MAP_RANGE_CHECK: [ internal use only ]
999 *

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

1045 if (vm_map_lookup_entry(map, start, &entry)) {
1046 vm_map_clip_start(map, entry, start);
1047 } else
1048 entry = entry->next;
1049
1050 vm_map_clip_end(map, entry, end);
1051
1052 if ((entry->start == start) && (entry->end == end) &&
1070 (!entry->is_a_map) &&
1071 (entry->object.vm_object == NULL) &&
1072 (!entry->copy_on_write)) {
1073 entry->is_a_map = FALSE;
1074 entry->is_sub_map = TRUE;
1053 ((entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_COW)) == 0) &&
1054 (entry->object.vm_object == NULL)) {
1055 entry->eflags |= MAP_ENTRY_IS_SUB_MAP;
1075 vm_map_reference(entry->object.sub_map = submap);
1076 result = KERN_SUCCESS;
1077 }
1078 vm_map_unlock(map);
1079
1080 return (result);
1081}
1082

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

1110 }
1111
1112 /*
1113 * Make a first pass to check for protection violations.
1114 */
1115
1116 current = entry;
1117 while ((current != &map->header) && (current->start < end)) {
1056 vm_map_reference(entry->object.sub_map = submap);
1057 result = KERN_SUCCESS;
1058 }
1059 vm_map_unlock(map);
1060
1061 return (result);
1062}
1063

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

1091 }
1092
1093 /*
1094 * Make a first pass to check for protection violations.
1095 */
1096
1097 current = entry;
1098 while ((current != &map->header) && (current->start < end)) {
1118 if (current->is_sub_map) {
1099 if (current->eflags & MAP_ENTRY_IS_SUB_MAP) {
1119 vm_map_unlock(map);
1120 return (KERN_INVALID_ARGUMENT);
1121 }
1122 if ((new_prot & current->max_protection) != new_prot) {
1123 vm_map_unlock(map);
1124 return (KERN_PROTECTION_FAILURE);
1125 }
1126 current = current->next;

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

1147 current->protection = new_prot;
1148
1149 /*
1150 * Update physical map if necessary. Worry about copy-on-write
1151 * here -- CHECK THIS XXX
1152 */
1153
1154 if (current->protection != old_prot) {
1100 vm_map_unlock(map);
1101 return (KERN_INVALID_ARGUMENT);
1102 }
1103 if ((new_prot & current->max_protection) != new_prot) {
1104 vm_map_unlock(map);
1105 return (KERN_PROTECTION_FAILURE);
1106 }
1107 current = current->next;

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

1128 current->protection = new_prot;
1129
1130 /*
1131 * Update physical map if necessary. Worry about copy-on-write
1132 * here -- CHECK THIS XXX
1133 */
1134
1135 if (current->protection != old_prot) {
1155#define MASK(entry) ((entry)->copy_on_write ? ~VM_PROT_WRITE : \
1136#define MASK(entry) (((entry)->eflags & MAP_ENTRY_COW) ? ~VM_PROT_WRITE : \
1156 VM_PROT_ALL)
1157#define max(a,b) ((a) > (b) ? (a) : (b))
1158
1137 VM_PROT_ALL)
1138#define max(a,b) ((a) > (b) ? (a) : (b))
1139
1159 if (current->is_a_map) {
1140 if (current->eflags & MAP_ENTRY_IS_A_MAP) {
1160 vm_map_entry_t share_entry;
1161 vm_offset_t share_end;
1162
1163 vm_map_lock(current->object.share_map);
1164 (void) vm_map_lookup_entry(
1165 current->object.share_map,
1166 current->offset,
1167 &share_entry);

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

1224 if (vm_map_lookup_entry(map, start, &entry)) {
1225 vm_map_clip_start(map, entry, start);
1226 } else
1227 entry = entry->next;
1228
1229 for(current = entry;
1230 (current != &map->header) && (current->start < end);
1231 current = current->next) {
1141 vm_map_entry_t share_entry;
1142 vm_offset_t share_end;
1143
1144 vm_map_lock(current->object.share_map);
1145 (void) vm_map_lookup_entry(
1146 current->object.share_map,
1147 current->offset,
1148 &share_entry);

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

1205 if (vm_map_lookup_entry(map, start, &entry)) {
1206 vm_map_clip_start(map, entry, start);
1207 } else
1208 entry = entry->next;
1209
1210 for(current = entry;
1211 (current != &map->header) && (current->start < end);
1212 current = current->next) {
1232 if (current->is_a_map || current->is_sub_map) {
1213 if (current->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) {
1233 continue;
1234 }
1235 vm_map_clip_end(map, current, end);
1236 switch (advise) {
1237 case MADV_NORMAL:
1238 current->object.vm_object->behavior = OBJ_NORMAL;
1239 break;
1240 case MADV_SEQUENTIAL:

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

1372 * Now decrement the wiring count for each region. If a region
1373 * becomes completely unwired, unwire its physical pages and
1374 * mappings.
1375 */
1376 lock_set_recursive(&map->lock);
1377
1378 entry = start_entry;
1379 while ((entry != &map->header) && (entry->start < end)) {
1214 continue;
1215 }
1216 vm_map_clip_end(map, current, end);
1217 switch (advise) {
1218 case MADV_NORMAL:
1219 current->object.vm_object->behavior = OBJ_NORMAL;
1220 break;
1221 case MADV_SEQUENTIAL:

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

1353 * Now decrement the wiring count for each region. If a region
1354 * becomes completely unwired, unwire its physical pages and
1355 * mappings.
1356 */
1357 lock_set_recursive(&map->lock);
1358
1359 entry = start_entry;
1360 while ((entry != &map->header) && (entry->start < end)) {
1380 if (entry->user_wired) {
1361 if (entry->eflags & MAP_ENTRY_USER_WIRED) {
1381 vm_map_clip_end(map, entry, end);
1362 vm_map_clip_end(map, entry, end);
1382 entry->user_wired = 0;
1363 entry->eflags &= ~MAP_ENTRY_USER_WIRED;
1383 entry->wired_count--;
1384 if (entry->wired_count == 0)
1385 vm_fault_unwire(map, entry->start, entry->end);
1386 }
1387 entry = entry->next;
1388 }
1389 vm_map_simplify_entry(map, start_entry);
1390 lock_clear_recursive(&map->lock);

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

1397 * changed.
1398 */
1399 rescan:
1400
1401 entry = start_entry;
1402
1403 while ((entry != &map->header) && (entry->start < end)) {
1404
1364 entry->wired_count--;
1365 if (entry->wired_count == 0)
1366 vm_fault_unwire(map, entry->start, entry->end);
1367 }
1368 entry = entry->next;
1369 }
1370 vm_map_simplify_entry(map, start_entry);
1371 lock_clear_recursive(&map->lock);

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

1378 * changed.
1379 */
1380 rescan:
1381
1382 entry = start_entry;
1383
1384 while ((entry != &map->header) && (entry->start < end)) {
1385
1405 if (entry->user_wired != 0) {
1386 if (entry->eflags & MAP_ENTRY_USER_WIRED) {
1406 entry = entry->next;
1407 continue;
1408 }
1409
1410 if (entry->wired_count != 0) {
1411 entry->wired_count++;
1387 entry = entry->next;
1388 continue;
1389 }
1390
1391 if (entry->wired_count != 0) {
1392 entry->wired_count++;
1412 entry->user_wired = 1;
1393 entry->eflags |= MAP_ENTRY_USER_WIRED;
1413 entry = entry->next;
1414 continue;
1415 }
1416
1417 /* Here on entry being newly wired */
1418
1394 entry = entry->next;
1395 continue;
1396 }
1397
1398 /* Here on entry being newly wired */
1399
1419 if (!entry->is_a_map && !entry->is_sub_map) {
1420 int copyflag = entry->needs_copy;
1400 if ((entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) == 0) {
1401 int copyflag = entry->eflags & MAP_ENTRY_NEEDS_COPY;
1421 if (copyflag && ((entry->protection & VM_PROT_WRITE) != 0)) {
1422
1423 vm_object_shadow(&entry->object.vm_object,
1424 &entry->offset,
1425 OFF_TO_IDX(entry->end
1426 - entry->start));
1402 if (copyflag && ((entry->protection & VM_PROT_WRITE) != 0)) {
1403
1404 vm_object_shadow(&entry->object.vm_object,
1405 &entry->offset,
1406 OFF_TO_IDX(entry->end
1407 - entry->start));
1427 entry->needs_copy = FALSE;
1408 entry->eflags &= ~MAP_ENTRY_NEEDS_COPY;
1428
1429 } else if (entry->object.vm_object == NULL) {
1430
1431 entry->object.vm_object =
1432 vm_object_allocate(OBJT_DEFAULT,
1433 OFF_TO_IDX(entry->end - entry->start));
1434 entry->offset = (vm_offset_t) 0;
1435
1436 }
1437 default_pager_convert_to_swapq(entry->object.vm_object);
1438 }
1439
1440 vm_map_clip_start(map, entry, start);
1441 vm_map_clip_end(map, entry, end);
1442
1443 entry->wired_count++;
1409
1410 } else if (entry->object.vm_object == NULL) {
1411
1412 entry->object.vm_object =
1413 vm_object_allocate(OBJT_DEFAULT,
1414 OFF_TO_IDX(entry->end - entry->start));
1415 entry->offset = (vm_offset_t) 0;
1416
1417 }
1418 default_pager_convert_to_swapq(entry->object.vm_object);
1419 }
1420
1421 vm_map_clip_start(map, entry, start);
1422 vm_map_clip_end(map, entry, end);
1423
1424 entry->wired_count++;
1444 entry->user_wired = 1;
1425 entry->eflags |= MAP_ENTRY_USER_WIRED;
1445
1446 /* First we need to allow map modifications */
1447 lock_set_recursive(&map->lock);
1448 lock_write_to_read(&map->lock);
1449
1450 rv = vm_fault_user_wire(map, entry->start, entry->end);
1451 if (rv) {
1452
1453 entry->wired_count--;
1426
1427 /* First we need to allow map modifications */
1428 lock_set_recursive(&map->lock);
1429 lock_write_to_read(&map->lock);
1430
1431 rv = vm_fault_user_wire(map, entry->start, entry->end);
1432 if (rv) {
1433
1434 entry->wired_count--;
1454 entry->user_wired = 0;
1435 entry->eflags &= ~MAP_ENTRY_USER_WIRED;
1455
1456 lock_clear_recursive(&map->lock);
1457 vm_map_unlock(map);
1458
1459 (void) vm_map_user_pageable(map, start, entry->start, TRUE);
1460 return rv;
1461 }
1462

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

1593 * the write lock on the map: create a shadow
1594 * object for a copy-on-write region, or an
1595 * object for a zero-fill region.
1596 *
1597 * We don't have to do this for entries that
1598 * point to sharing maps, because we won't
1599 * hold the lock on the sharing map.
1600 */
1436
1437 lock_clear_recursive(&map->lock);
1438 vm_map_unlock(map);
1439
1440 (void) vm_map_user_pageable(map, start, entry->start, TRUE);
1441 return rv;
1442 }
1443

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

1574 * the write lock on the map: create a shadow
1575 * object for a copy-on-write region, or an
1576 * object for a zero-fill region.
1577 *
1578 * We don't have to do this for entries that
1579 * point to sharing maps, because we won't
1580 * hold the lock on the sharing map.
1581 */
1601 if (!entry->is_a_map && !entry->is_sub_map) {
1602 int copyflag = entry->needs_copy;
1582 if ((entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) == 0) {
1583 int copyflag = entry->eflags & MAP_ENTRY_NEEDS_COPY;
1603 if (copyflag &&
1604 ((entry->protection & VM_PROT_WRITE) != 0)) {
1605
1606 vm_object_shadow(&entry->object.vm_object,
1607 &entry->offset,
1608 OFF_TO_IDX(entry->end
1609 - entry->start));
1584 if (copyflag &&
1585 ((entry->protection & VM_PROT_WRITE) != 0)) {
1586
1587 vm_object_shadow(&entry->object.vm_object,
1588 &entry->offset,
1589 OFF_TO_IDX(entry->end
1590 - entry->start));
1610 entry->needs_copy = FALSE;
1591 entry->eflags &= ~MAP_ENTRY_NEEDS_COPY;
1611 } else if (entry->object.vm_object == NULL) {
1612 entry->object.vm_object =
1613 vm_object_allocate(OBJT_DEFAULT,
1614 OFF_TO_IDX(entry->end - entry->start));
1615 entry->offset = (vm_offset_t) 0;
1616 }
1617 default_pager_convert_to_swapq(entry->object.vm_object);
1618 }

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

1735 if (!vm_map_lookup_entry(map, start, &entry)) {
1736 vm_map_unlock_read(map);
1737 return (KERN_INVALID_ADDRESS);
1738 }
1739 /*
1740 * Make a first pass to check for holes.
1741 */
1742 for (current = entry; current->start < end; current = current->next) {
1592 } else if (entry->object.vm_object == NULL) {
1593 entry->object.vm_object =
1594 vm_object_allocate(OBJT_DEFAULT,
1595 OFF_TO_IDX(entry->end - entry->start));
1596 entry->offset = (vm_offset_t) 0;
1597 }
1598 default_pager_convert_to_swapq(entry->object.vm_object);
1599 }

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

1716 if (!vm_map_lookup_entry(map, start, &entry)) {
1717 vm_map_unlock_read(map);
1718 return (KERN_INVALID_ADDRESS);
1719 }
1720 /*
1721 * Make a first pass to check for holes.
1722 */
1723 for (current = entry; current->start < end; current = current->next) {
1743 if (current->is_sub_map) {
1724 if (current->eflags & MAP_ENTRY_IS_SUB_MAP) {
1744 vm_map_unlock_read(map);
1745 return (KERN_INVALID_ARGUMENT);
1746 }
1747 if (end > current->end &&
1748 (current->next == &map->header ||
1749 current->end != current->next->start)) {
1750 vm_map_unlock_read(map);
1751 return (KERN_INVALID_ADDRESS);
1752 }
1753 }
1754
1755 /*
1756 * Make a second pass, cleaning/uncaching pages from the indicated
1757 * objects as we go.
1758 */
1759 for (current = entry; current->start < end; current = current->next) {
1760 offset = current->offset + (start - current->start);
1761 size = (end <= current->end ? end : current->end) - start;
1725 vm_map_unlock_read(map);
1726 return (KERN_INVALID_ARGUMENT);
1727 }
1728 if (end > current->end &&
1729 (current->next == &map->header ||
1730 current->end != current->next->start)) {
1731 vm_map_unlock_read(map);
1732 return (KERN_INVALID_ADDRESS);
1733 }
1734 }
1735
1736 /*
1737 * Make a second pass, cleaning/uncaching pages from the indicated
1738 * objects as we go.
1739 */
1740 for (current = entry; current->start < end; current = current->next) {
1741 offset = current->offset + (start - current->start);
1742 size = (end <= current->end ? end : current->end) - start;
1762 if (current->is_a_map || current->is_sub_map) {
1743 if (current->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) {
1763 register vm_map_t smap;
1764 vm_map_entry_t tentry;
1765 vm_size_t tsize;
1766
1767 smap = current->object.share_map;
1768 vm_map_lock_read(smap);
1769 (void) vm_map_lookup_entry(smap, offset, &tentry);
1770 tsize = tentry->end - offset;

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

1845static void
1846vm_map_entry_delete(map, entry)
1847 register vm_map_t map;
1848 register vm_map_entry_t entry;
1849{
1850 vm_map_entry_unlink(map, entry);
1851 map->size -= entry->end - entry->start;
1852
1744 register vm_map_t smap;
1745 vm_map_entry_t tentry;
1746 vm_size_t tsize;
1747
1748 smap = current->object.share_map;
1749 vm_map_lock_read(smap);
1750 (void) vm_map_lookup_entry(smap, offset, &tentry);
1751 tsize = tentry->end - offset;

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

1826static void
1827vm_map_entry_delete(map, entry)
1828 register vm_map_t map;
1829 register vm_map_entry_t entry;
1830{
1831 vm_map_entry_unlink(map, entry);
1832 map->size -= entry->end - entry->start;
1833
1853 if (entry->is_a_map || entry->is_sub_map) {
1834 if (entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) {
1854 vm_map_deallocate(entry->object.share_map);
1855 } else {
1856 vm_object_deallocate(entry->object.vm_object);
1857 }
1858
1859 vm_map_entry_dispose(map, entry);
1860}
1861

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

2042 * Copies the contents of the source entry to the destination
2043 * entry. The entries *must* be aligned properly.
2044 */
2045static void
2046vm_map_copy_entry(src_map, dst_map, src_entry, dst_entry)
2047 vm_map_t src_map, dst_map;
2048 register vm_map_entry_t src_entry, dst_entry;
2049{
1835 vm_map_deallocate(entry->object.share_map);
1836 } else {
1837 vm_object_deallocate(entry->object.vm_object);
1838 }
1839
1840 vm_map_entry_dispose(map, entry);
1841}
1842

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

2023 * Copies the contents of the source entry to the destination
2024 * entry. The entries *must* be aligned properly.
2025 */
2026static void
2027vm_map_copy_entry(src_map, dst_map, src_entry, dst_entry)
2028 vm_map_t src_map, dst_map;
2029 register vm_map_entry_t src_entry, dst_entry;
2030{
2050 if (src_entry->is_sub_map || dst_entry->is_sub_map)
2031 if ((dst_entry->eflags|src_entry->eflags) &
2032 (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP))
2051 return;
2052
2053 if (src_entry->wired_count == 0) {
2054
2055 /*
2056 * If the source entry is marked needs_copy, it is already
2057 * write-protected.
2058 */
2033 return;
2034
2035 if (src_entry->wired_count == 0) {
2036
2037 /*
2038 * If the source entry is marked needs_copy, it is already
2039 * write-protected.
2040 */
2059 if (!src_entry->needs_copy) {
2041 if ((src_entry->eflags & MAP_ENTRY_NEEDS_COPY) == 0) {
2060
2061 boolean_t su;
2062
2063 /*
2064 * If the source entry has only one mapping, we can
2065 * just protect the virtual address range.
2066 */
2067 if (!(su = src_map->is_main_map)) {

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

2084 * Make a copy of the object.
2085 */
2086 if (src_entry->object.vm_object) {
2087 if ((src_entry->object.vm_object->handle == NULL) &&
2088 (src_entry->object.vm_object->type == OBJT_DEFAULT ||
2089 src_entry->object.vm_object->type == OBJT_SWAP))
2090 vm_object_collapse(src_entry->object.vm_object);
2091 ++src_entry->object.vm_object->ref_count;
2042
2043 boolean_t su;
2044
2045 /*
2046 * If the source entry has only one mapping, we can
2047 * just protect the virtual address range.
2048 */
2049 if (!(su = src_map->is_main_map)) {

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

2066 * Make a copy of the object.
2067 */
2068 if (src_entry->object.vm_object) {
2069 if ((src_entry->object.vm_object->handle == NULL) &&
2070 (src_entry->object.vm_object->type == OBJT_DEFAULT ||
2071 src_entry->object.vm_object->type == OBJT_SWAP))
2072 vm_object_collapse(src_entry->object.vm_object);
2073 ++src_entry->object.vm_object->ref_count;
2092 src_entry->copy_on_write = TRUE;
2093 src_entry->needs_copy = TRUE;
2094
2095 dst_entry->needs_copy = TRUE;
2096 dst_entry->copy_on_write = TRUE;
2074 src_entry->eflags |= (MAP_ENTRY_COW|MAP_ENTRY_NEEDS_COPY);
2075 dst_entry->eflags |= (MAP_ENTRY_COW|MAP_ENTRY_NEEDS_COPY);
2097 dst_entry->object.vm_object =
2098 src_entry->object.vm_object;
2099 dst_entry->offset = src_entry->offset;
2100 } else {
2101 dst_entry->object.vm_object = NULL;
2102 dst_entry->offset = 0;
2103 }
2104

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

2142 bcopy(&vm1->vm_startcopy, &vm2->vm_startcopy,
2143 (caddr_t) (vm1 + 1) - (caddr_t) &vm1->vm_startcopy);
2144 new_pmap = &vm2->vm_pmap; /* XXX */
2145 new_map = &vm2->vm_map; /* XXX */
2146
2147 old_entry = old_map->header.next;
2148
2149 while (old_entry != &old_map->header) {
2076 dst_entry->object.vm_object =
2077 src_entry->object.vm_object;
2078 dst_entry->offset = src_entry->offset;
2079 } else {
2080 dst_entry->object.vm_object = NULL;
2081 dst_entry->offset = 0;
2082 }
2083

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

2121 bcopy(&vm1->vm_startcopy, &vm2->vm_startcopy,
2122 (caddr_t) (vm1 + 1) - (caddr_t) &vm1->vm_startcopy);
2123 new_pmap = &vm2->vm_pmap; /* XXX */
2124 new_map = &vm2->vm_map; /* XXX */
2125
2126 old_entry = old_map->header.next;
2127
2128 while (old_entry != &old_map->header) {
2150 if (old_entry->is_sub_map)
2129 if (old_entry->eflags & MAP_ENTRY_IS_SUB_MAP)
2151 panic("vm_map_fork: encountered a submap");
2152
2153 switch (old_entry->inheritance) {
2154 case VM_INHERIT_NONE:
2155 break;
2156
2157 case VM_INHERIT_SHARE:
2158 /*

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

2185 case VM_INHERIT_COPY:
2186 /*
2187 * Clone the entry and link into the map.
2188 */
2189 new_entry = vm_map_entry_create(new_map);
2190 *new_entry = *old_entry;
2191 new_entry->wired_count = 0;
2192 new_entry->object.vm_object = NULL;
2130 panic("vm_map_fork: encountered a submap");
2131
2132 switch (old_entry->inheritance) {
2133 case VM_INHERIT_NONE:
2134 break;
2135
2136 case VM_INHERIT_SHARE:
2137 /*

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

2164 case VM_INHERIT_COPY:
2165 /*
2166 * Clone the entry and link into the map.
2167 */
2168 new_entry = vm_map_entry_create(new_map);
2169 *new_entry = *old_entry;
2170 new_entry->wired_count = 0;
2171 new_entry->object.vm_object = NULL;
2193 new_entry->is_a_map = FALSE;
2172 new_entry->eflags &= ~MAP_ENTRY_IS_A_MAP;
2194 vm_map_entry_link(new_map, new_map->header.prev,
2195 new_entry);
2196 vm_map_copy_entry(old_map, new_map, old_entry,
2197 new_entry);
2198 break;
2199 }
2200 old_entry = old_entry->next;
2201 }

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

2286 entry = tmp_entry;
2287 *out_entry = entry;
2288 }
2289
2290 /*
2291 * Handle submaps.
2292 */
2293
2173 vm_map_entry_link(new_map, new_map->header.prev,
2174 new_entry);
2175 vm_map_copy_entry(old_map, new_map, old_entry,
2176 new_entry);
2177 break;
2178 }
2179 old_entry = old_entry->next;
2180 }

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

2265 entry = tmp_entry;
2266 *out_entry = entry;
2267 }
2268
2269 /*
2270 * Handle submaps.
2271 */
2272
2294 if (entry->is_sub_map) {
2273 if (entry->eflags & MAP_ENTRY_IS_SUB_MAP) {
2295 vm_map_t old_map = map;
2296
2297 *var_map = map = entry->object.sub_map;
2298 vm_map_unlock_read(old_map);
2299 goto RetryLookup;
2300 }
2301 /*
2302 * Check whether this task is allowed to have this page.

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

2314 *wired = (entry->wired_count != 0);
2315 if (*wired)
2316 prot = fault_type = entry->protection;
2317
2318 /*
2319 * If we don't already have a VM object, track it down.
2320 */
2321
2274 vm_map_t old_map = map;
2275
2276 *var_map = map = entry->object.sub_map;
2277 vm_map_unlock_read(old_map);
2278 goto RetryLookup;
2279 }
2280 /*
2281 * Check whether this task is allowed to have this page.

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

2293 *wired = (entry->wired_count != 0);
2294 if (*wired)
2295 prot = fault_type = entry->protection;
2296
2297 /*
2298 * If we don't already have a VM object, track it down.
2299 */
2300
2322 su = !entry->is_a_map;
2301 su = (entry->eflags & MAP_ENTRY_IS_A_MAP) == 0;
2323 if (su) {
2324 share_map = map;
2325 share_offset = vaddr;
2326 } else {
2327 vm_map_entry_t share_entry;
2328
2329 /*
2330 * Compute the sharing map, and offset into it.

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

2346 }
2347 entry = share_entry;
2348 }
2349
2350 /*
2351 * If the entry was copy-on-write, we either ...
2352 */
2353
2302 if (su) {
2303 share_map = map;
2304 share_offset = vaddr;
2305 } else {
2306 vm_map_entry_t share_entry;
2307
2308 /*
2309 * Compute the sharing map, and offset into it.

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

2325 }
2326 entry = share_entry;
2327 }
2328
2329 /*
2330 * If the entry was copy-on-write, we either ...
2331 */
2332
2354 if (entry->needs_copy) {
2333 if (entry->eflags & MAP_ENTRY_NEEDS_COPY) {
2355 /*
2356 * If we want to write the page, we may as well handle that
2357 * now since we've got the sharing map locked.
2358 *
2359 * If we don't need to write the page, we just demote the
2360 * permissions allowed.
2361 */
2362

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

2373 vm_map_unlock_read(map);
2374 goto RetryLookup;
2375 }
2376 vm_object_shadow(
2377 &entry->object.vm_object,
2378 &entry->offset,
2379 OFF_TO_IDX(entry->end - entry->start));
2380
2334 /*
2335 * If we want to write the page, we may as well handle that
2336 * now since we've got the sharing map locked.
2337 *
2338 * If we don't need to write the page, we just demote the
2339 * permissions allowed.
2340 */
2341

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

2352 vm_map_unlock_read(map);
2353 goto RetryLookup;
2354 }
2355 vm_object_shadow(
2356 &entry->object.vm_object,
2357 &entry->offset,
2358 OFF_TO_IDX(entry->end - entry->start));
2359
2381 entry->needs_copy = FALSE;
2360 entry->eflags &= ~MAP_ENTRY_NEEDS_COPY;
2382
2383 lock_write_to_read(&share_map->lock);
2384 } else {
2385 /*
2386 * We're attempting to read a copy-on-write page --
2387 * don't allow writes.
2388 */
2389

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

2442vm_map_lookup_done(map, entry)
2443 register vm_map_t map;
2444 vm_map_entry_t entry;
2445{
2446 /*
2447 * If this entry references a map, unlock it first.
2448 */
2449
2361
2362 lock_write_to_read(&share_map->lock);
2363 } else {
2364 /*
2365 * We're attempting to read a copy-on-write page --
2366 * don't allow writes.
2367 */
2368

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

2421vm_map_lookup_done(map, entry)
2422 register vm_map_t map;
2423 vm_map_entry_t entry;
2424{
2425 /*
2426 * If this entry references a map, unlock it first.
2427 */
2428
2450 if (entry->is_a_map)
2429 if (entry->eflags & MAP_ENTRY_IS_A_MAP)
2451 vm_map_unlock_read(entry->object.share_map);
2452
2453 /*
2454 * Unlock the main-level map
2455 */
2456
2457 vm_map_unlock_read(map);
2458}

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

2493
2494 db_printf("prot=%x/%x/%s, ",
2495 entry->protection,
2496 entry->max_protection,
2497 inheritance_name[entry->inheritance]);
2498 if (entry->wired_count != 0)
2499 db_printf("wired, ");
2500 }
2430 vm_map_unlock_read(entry->object.share_map);
2431
2432 /*
2433 * Unlock the main-level map
2434 */
2435
2436 vm_map_unlock_read(map);
2437}

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

2472
2473 db_printf("prot=%x/%x/%s, ",
2474 entry->protection,
2475 entry->max_protection,
2476 inheritance_name[entry->inheritance]);
2477 if (entry->wired_count != 0)
2478 db_printf("wired, ");
2479 }
2501 if (entry->is_a_map || entry->is_sub_map) {
2480 if (entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) {
2502 db_printf("share=0x%x, offset=0x%x\n",
2503 (int) entry->object.share_map,
2504 (int) entry->offset);
2505 if ((entry->prev == &map->header) ||
2481 db_printf("share=0x%x, offset=0x%x\n",
2482 (int) entry->object.share_map,
2483 (int) entry->offset);
2484 if ((entry->prev == &map->header) ||
2506 (!entry->prev->is_a_map) ||
2485 ((entry->prev->eflags & MAP_ENTRY_IS_A_MAP) == 0) ||
2507 (entry->prev->object.share_map !=
2508 entry->object.share_map)) {
2509 db_indent += 2;
2510 vm_map_print((int)entry->object.share_map,
2511 full, 0, (char *)0);
2512 db_indent -= 2;
2513 }
2514 } else {
2515 db_printf("object=0x%x, offset=0x%x",
2516 (int) entry->object.vm_object,
2517 (int) entry->offset);
2486 (entry->prev->object.share_map !=
2487 entry->object.share_map)) {
2488 db_indent += 2;
2489 vm_map_print((int)entry->object.share_map,
2490 full, 0, (char *)0);
2491 db_indent -= 2;
2492 }
2493 } else {
2494 db_printf("object=0x%x, offset=0x%x",
2495 (int) entry->object.vm_object,
2496 (int) entry->offset);
2518 if (entry->copy_on_write)
2497 if (entry->eflags & MAP_ENTRY_COW)
2519 db_printf(", copy (%s)",
2498 db_printf(", copy (%s)",
2520 entry->needs_copy ? "needed" : "done");
2499 (entry->eflags & MAP_ENTRY_NEEDS_COPY) ? "needed" : "done");
2521 db_printf("\n");
2522
2523 if ((entry->prev == &map->header) ||
2500 db_printf("\n");
2501
2502 if ((entry->prev == &map->header) ||
2524 (entry->prev->is_a_map) ||
2503 (entry->prev->eflags & MAP_ENTRY_IS_A_MAP) ||
2525 (entry->prev->object.vm_object !=
2526 entry->object.vm_object)) {
2527 db_indent += 2;
2528 vm_object_print((int)entry->object.vm_object,
2529 full, 0, (char *)0);
2530 db_indent -= 2;
2531 }
2532 }
2533 }
2534 db_indent -= 2;
2535}
2536#endif /* DDB */
2504 (entry->prev->object.vm_object !=
2505 entry->object.vm_object)) {
2506 db_indent += 2;
2507 vm_object_print((int)entry->object.vm_object,
2508 full, 0, (char *)0);
2509 db_indent -= 2;
2510 }
2511 }
2512 }
2513 db_indent -= 2;
2514}
2515#endif /* DDB */