|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Mach Operating System
27: * Copyright (c) 1987 Carnegie-Mellon University
28: * All rights reserved. The CMU software License Agreement specifies
29: * the terms and conditions for use and redistribution.
30: */
31: /*
32: * File: vm_fault.c
33: * Author: Avadis Tevanian, Jr., Michael Wayne Young
34: *
35: * Copyright (C) 1985, Avadis Tevanian, Jr., Michael Wayne Young
36: *
37: * Page fault handling module.
38: */
39:
40: #import <mach_xp.h>
41:
42: #define USE_VERSIONS MACH_XP
43:
44: #import <mach/kern_return.h>
45: #import <mach/message.h> /* for error codes */
46: #import <kern/thread.h>
47: #import <kern/sched_prim.h>
48: #import <vm/vm_map.h>
49: #import <vm/vm_object.h>
50: #import <vm/vm_page.h>
51: #import <vm/pmap.h>
52: #import <mach/vm_statistics.h>
53: #import <vm/vm_pageout.h>
54: #import <mach/vm_param.h>
55:
56:
57: /*
58: * vm_fault:
59: *
60: * Handle a page fault occuring at the given address,
61: * requiring the given permissions, in the map specified.
62: * If successful, the page is inserted into the
63: * associated physical map.
64: *
65: * NOTE: the given address should be truncated to the
66: * proper page address.
67: *
68: * KERN_SUCCESS is returned if the page fault is handled; otherwise,
69: * a standard error specifying why the fault is fatal is returned.
70: *
71: *
72: * The map in question must be referenced, and remains so.
73: * Caller may hold no locks.
74: */
75: #if NeXT
76: kern_return_t vm_fault(map, vaddr, fault_type, change_wiring, error)
77: vm_map_t map;
78: vm_offset_t vaddr;
79: vm_prot_t fault_type;
80: boolean_t change_wiring;
81: int *error;
82: #else NeXT
83: kern_return_t vm_fault(map, vaddr, fault_type, change_wiring)
84: vm_map_t map;
85: vm_offset_t vaddr;
86: vm_prot_t fault_type;
87: boolean_t change_wiring;
88: #endif NeXT
89: {
90: vm_object_t first_object;
91: vm_offset_t first_offset;
92: #if USE_VERSIONS
93: vm_map_version_t version;
94: #else USE_VERSIONS
95: vm_map_entry_t entry;
96: #endif USE_VERSIONS
97: register vm_object_t object;
98: register vm_offset_t offset;
99: register vm_page_t m;
100: vm_page_t first_m;
101: vm_prot_t prot;
102: kern_return_t result;
103: boolean_t wired;
104: boolean_t su;
105: #if !USE_VERSIONS
106: boolean_t lookup_still_valid;
107: #endif !USE_VERSIONS
108: boolean_t page_exists;
109: vm_page_t old_m;
110: vm_object_t next_object;
111:
112: vm_stat.faults++; /* needs lock XXX */
113: /*
114: * Recovery actions
115: */
116: #if MACH_XP
117: /* vm_page_free does a PAGE_WAKEUP anyway */
118: #define FREE_PAGE(m) { \
119: vm_page_lock_queues(); \
120: vm_page_free(m); \
121: vm_page_unlock_queues(); \
122: }
123: #else MACH_XP
124: #define FREE_PAGE(m) { \
125: PAGE_WAKEUP(m); \
126: vm_page_lock_queues(); \
127: vm_page_free(m); \
128: vm_page_unlock_queues(); \
129: }
130: #endif MACH_XP
131:
132: #define RELEASE_PAGE(m) { \
133: PAGE_WAKEUP(m); \
134: vm_page_lock_queues(); \
135: vm_page_activate(m); \
136: vm_page_unlock_queues(); \
137: }
138:
139: #if USE_VERSIONS
140: #define UNLOCK_MAP
141: #else USE_VERSIONS
142: #define UNLOCK_MAP { \
143: if (lookup_still_valid) { \
144: vm_map_lookup_done(map, entry); \
145: lookup_still_valid = FALSE; \
146: } \
147: }
148: #endif USE_VERSIONS
149:
150: #define UNLOCK_THINGS { \
151: object->paging_in_progress--; \
152: vm_object_unlock(object); \
153: if (object != first_object) { \
154: vm_object_lock(first_object); \
155: FREE_PAGE(first_m); \
156: first_object->paging_in_progress--; \
157: vm_object_unlock(first_object); \
158: } \
159: UNLOCK_MAP; \
160: }
161:
162: #define UNLOCK_AND_DEALLOCATE { \
163: UNLOCK_THINGS; \
164: vm_object_deallocate(first_object); \
165: }
166:
167: RetryFault: ;
168:
169: /*
170: * Find the backing store object and offset into
171: * it to begin the search.
172: */
173:
174: #if USE_VERSIONS
175: if ((result = vm_map_lookup(&map, vaddr, fault_type, &version,
176: #else USE_VERSIONS
177: if ((result = vm_map_lookup(&map, vaddr, fault_type, &entry,
178: #endif USE_VERSIONS
179: &first_object, &first_offset,
180: &prot, &wired, &su)) != KERN_SUCCESS) {
181: return(result);
182: }
183: #if !USE_VERSIONS
184: lookup_still_valid = TRUE;
185: #endif !USE_VERSIONS
186:
187: if (wired)
188: fault_type = prot;
189:
190: first_m = VM_PAGE_NULL;
191:
192: /*
193: * Make a reference to this object to
194: * prevent its disposal while we are messing with
195: * it. Once we have the reference, the map is free
196: * to be diddled. Since objects reference their
197: * shadows (and copies), they will stay around as well.
198: */
199:
200: #if !USE_VERSIONS
201: vm_object_lock(first_object);
202: #endif !USE_VERSIONS
203:
204: first_object->ref_count++;
205: first_object->paging_in_progress++;
206:
207: /*
208: * INVARIANTS (through entire routine):
209: *
210: * 1) At all times, we must either have the object
211: * lock or a busy page in some object to prevent
212: * some other thread from trying to bring in
213: * the same page.
214: *
215: * Note that we cannot hold any locks during the
216: * pager access or when waiting for memory, so
217: * we use a busy page then.
218: *
219: * Note also that we aren't as concerned about
220: * more than one thead attempting to pager_data_unlock
221: * the same page at once, so we don't hold the page
222: * as busy then, but do record the highest unlock
223: * value so far. [Unlock requests may also be delivered
224: * out of order.]
225: *
226: * 2) Once we have a busy page, we must remove it from
227: * the pageout queues, so that the pageout daemon
228: * will not grab it away.
229: *
230: * 3) To prevent another thread from racing us down the
231: * shadow chain and entering a new page in the top
232: * object before we do, we must keep a busy page in
233: * the top object while following the shadow chain.
234: *
235: * 4) We must increment paging_in_progress on any object
236: * for which we have a busy page, to prevent
237: * vm_object_collapse from removing the busy page
238: * without our noticing.
239: */
240:
241: /*
242: * Search for the page at object/offset.
243: */
244:
245: object = first_object;
246: offset = first_offset;
247:
248: /*
249: * See whether this page is resident
250: */
251:
252: while (TRUE) {
253: m = vm_page_lookup(object, offset);
254: if (m != VM_PAGE_NULL) {
255: /*
256: * If the page is in error, give up now.
257: */
258:
259: if (m->error) {
260: FREE_PAGE(m);
261: UNLOCK_AND_DEALLOCATE;
262: return(KERN_MEMORY_ERROR);
263: }
264:
265: /*
266: * If the page is being brought in,
267: * wait for it and then retry.
268: */
269: if (m->busy) {
270: kern_return_t wait_result;
271: #if SCRUBVM3
272: /* hint if we miss it its ok */
273: if (m->dry_vp){
274: vm_page_lock_queues();
275: (void) vm_page_completeio(m, TRUE);
276: vm_page_unlock_queues();
277: } else {
278: #endif
279: PAGE_ASSERT_WAIT(m, !change_wiring);
280: UNLOCK_MAP;
281: vm_object_unlock(object);
282: thread_block();
283: wait_result = current_thread()->wait_result;
284: vm_object_lock(object);
285: if (wait_result == THREAD_RESTART) {
286: UNLOCK_AND_DEALLOCATE;
287: goto RetryFault;
288: }
289: if (wait_result != THREAD_AWAKENED) {
290: UNLOCK_AND_DEALLOCATE;
291: return(KERN_SUCCESS);
292: }
293: continue;
294: #if SCRUBVM3
295: }
296: #endif
297: }
298:
299: /*
300: * If the page isn't busy, but is absent,
301: * then it was deemed "unavailable".
302: */
303:
304: if (m->absent) {
305: /*
306: * Remove the non-existent page (unless it's
307: * in the top object) and move on down to the
308: * next object (if there is one).
309: */
310: offset += object->shadow_offset;
311: next_object = object->shadow;
312: if (next_object == VM_OBJECT_NULL) {
313: /*
314: * Absent page at bottom of shadow
315: * chain; zero fill the page we left
316: * busy in the first object, and flush
317: * the absent page.
318: */
319: if (object != first_object) {
320: m->busy = m->absent = FALSE;
321: FREE_PAGE(m);
322: object->paging_in_progress--;
323: vm_object_unlock(object);
324: object = first_object;
325: offset = first_offset;
326: m = first_m;
327: vm_object_lock(object);
328: }
329: first_m = VM_PAGE_NULL;
330: vm_page_zero_fill(m);
331: vm_stat.zero_fill_count++;
332: m->absent = FALSE;
333: } else {
334: if (object != first_object) {
335: object->paging_in_progress--;
336: FREE_PAGE(m);
337: } else {
338: first_m = m;
339: m->absent = FALSE;
340: }
341: vm_object_lock(next_object);
342: vm_object_unlock(object);
343: object = next_object;
344: object->paging_in_progress++;
345: continue;
346: }
347: }
348:
349: /*
350: * If the desired access to this page has
351: * been locked out, request that it be unlocked.
352: */
353:
354: if (fault_type & m->page_lock) {
355: UNLOCK_AND_DEALLOCATE;
356: return (KERN_MEMORY_ERROR);
357: }
358:
359: /*
360: * Remove the page from the pageout daemon's
361: * reach while we play with it.
362: */
363:
364: vm_page_lock_queues();
365: if (m->inactive) {
366: queue_remove(&vm_page_queue_inactive, m,
367: vm_page_t, pageq);
368: m->inactive = FALSE;
369: vm_page_inactive_count--;
370: vm_stat.reactivations++;
371: }
372:
373: if (m->active) {
374: queue_remove(&vm_page_queue_active, m,
375: vm_page_t, pageq);
376: m->active = FALSE;
377: vm_page_active_count--;
378: }
379: #if NeXT
380: if (m->free) {
381: /*
382: * We only get here on reactivation of a free page,
383: * vm_page_alloc takes care of this for us in the
384: * typical case.
385: */
386: queue_remove(&vm_page_queue_free, m,
387: vm_page_t, pageq);
388: m->free = FALSE;
389: vm_page_free_count--;
390: vm_stat.reactivations++;
391: }
392: #endif NeXT
393: vm_page_unlock_queues();
394:
395: /*
396: * Mark page busy for other threads.
397: */
398: m->busy = TRUE;
399: m->absent = FALSE;
400: break;
401: }
402:
403: if (((object->pager != vm_pager_null) &&
404: (!change_wiring || wired))
405: || (object == first_object)) {
406:
407: /*
408: * Allocate a new page for this object/offset
409: * pair.
410: */
411:
412: m = vm_page_alloc(object, offset);
413:
414: if (m == VM_PAGE_NULL) {
415: UNLOCK_AND_DEALLOCATE;
416: VM_WAIT;
417: goto RetryFault;
418: }
419: }
420:
421: if ((object->pager != vm_pager_null) &&
422: (!change_wiring || wired)) {
423: #if MACH_XP
424: kern_return_t rc;
425: #else MACH_XP
426: pager_return_t rc;
427: #endif MACH_XP
428:
429: /*
430: * Now that we have a busy page, we can
431: * release the object lock.
432: */
433: vm_object_unlock(object);
434:
435: /*
436: * Call the pager to retrieve the data, if any,
437: * after releasing the lock on the map.
438: */
439: UNLOCK_MAP;
440:
441: #if MACH_XP
442: m->absent = TRUE;
443:
444: vm_stat.pageins++;
445: if ((rc = pager_data_request(object->pager,
446: object->pager_request,
447: m->offset + object->paging_offset,
448: PAGE_SIZE, fault_type)) != KERN_SUCCESS) {
449: if (rc != SEND_INTERRUPTED)
450: kprintf("%s(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) failed, %d\n",
451: "pager_data_request",
452: object->pager,
453: object->pager_request,
454: m->offset + object->paging_offset,
455: PAGE_SIZE, fault_type, rc);
456: vm_object_lock(object);
457: FREE_PAGE(m);
458: UNLOCK_AND_DEALLOCATE;
459: return((rc == SEND_INTERRUPTED) ?
460: KERN_SUCCESS : KERN_MEMORY_ERROR);
461: }
462:
463: /*
464: * Retry with same object/offset, since new data may
465: * be in a different page (ie, m is meaningless at
466: * this point).
467: */
468: vm_object_lock(object);
469: continue;
470: #else MACH_XP
471: #if NeXT
472: rc = vm_pager_get(object->pager, m, error);
473: #else NeXT
474: rc = vm_pager_get(object->pager, m);
475: #endif NeXT
476: if (rc == PAGER_SUCCESS) {
477:
478: /*
479: * Found the page.
480: * Leave it busy while we play with it.
481: */
482: vm_object_lock(object);
483:
484: /*
485: * Relookup in case pager changed page.
486: * Pager is responsible for disposition
487: * of old page if moved.
488: */
489: m = vm_page_lookup(object, offset);
490:
491: vm_stat.pageins++;
492: pmap_clear_modify(VM_PAGE_TO_PHYS(m));
493: break;
494: }
495: if (rc == PAGER_ERROR) {
496: /*
497: * Pager had the page, but could not
498: * read it. Return error to stop caller.
499: */
500: vm_object_lock(object);
501: FREE_PAGE(m);
502: UNLOCK_AND_DEALLOCATE;
503: return(KERN_MEMORY_ERROR);
504: }
505:
506: /*
507: * Remove the bogus page (which does not
508: * exist at this object/offset); before
509: * doing so, we must get back our object
510: * lock to preserve our invariant.
511: *
512: * Also wake up any other thread that may want
513: * to bring in this page.
514: *
515: * If this is the top-level object, we must
516: * leave the busy page to prevent another
517: * thread from rushing past us, and inserting
518: * the page in that object at the same time
519: * that we are.
520: */
521:
522: vm_object_lock(object);
523: if (object != first_object) {
524: FREE_PAGE(m);
525: }
526: #endif MACH_XP
527: }
528:
529: /*
530: * For the XP system, the only case in which we get here is if
531: * object has no pager (or unwiring). If the pager doesn't
532: * have the page this is handled in the m->absent case above
533: * (and if you change things here you should look above).
534: */
535: if (object == first_object)
536: first_m = m;
537:
538: /*
539: * Move on to the next object. Lock the next
540: * object before unlocking the current one.
541: */
542:
543: offset += object->shadow_offset;
544: next_object = object->shadow;
545: if (next_object == VM_OBJECT_NULL) {
546: /*
547: * If there's no object left, fill the page
548: * in the top object with zeros.
549: */
550: if (object != first_object) {
551: object->paging_in_progress--;
552: vm_object_unlock(object);
553:
554: object = first_object;
555: offset = first_offset;
556: m = first_m;
557: vm_object_lock(object);
558: }
559: first_m = VM_PAGE_NULL;
560:
561: vm_page_zero_fill(m);
562: vm_stat.zero_fill_count++;
563: m->absent = FALSE;
564: break;
565: }
566: else {
567: vm_object_lock(next_object);
568: if (object != first_object)
569: object->paging_in_progress--;
570: vm_object_unlock(object);
571: object = next_object;
572: object->paging_in_progress++;
573: }
574: }
575:
576: if (m->absent || m->active || m->inactive || !m->busy)
577: panic("vm_fault: absent or active or inactive or not busy after main loop");
578:
579: /*
580: * PAGE HAS BEEN FOUND.
581: * [Loop invariant still holds -- the object lock
582: * is held.]
583: */
584:
585: old_m = m; /* save page that would be copied */
586:
587: /*
588: * If the page is being written, but isn't
589: * already owned by the top-level object,
590: * we have to copy it into a new page owned
591: * by the top-level object.
592: */
593:
594: if (object != first_object) {
595: /*
596: * We only really need to copy if we
597: * want to write it.
598: */
599:
600: if (fault_type & VM_PROT_WRITE) {
601:
602: /*
603: * If we try to collapse first_object at this
604: * point, we may deadlock when we try to get
605: * the lock on an intermediate object (since we
606: * have the bottom object locked). We can't
607: * unlock the bottom object, because the page
608: * we found may move (by collapse) if we do.
609: *
610: * Instead, we first copy the page. Then, when
611: * we have no more use for the bottom object,
612: * we unlock it and try to collapse.
613: *
614: * Note that we copy the page even if we didn't
615: * need to... that's the breaks.
616: */
617:
618: /*
619: * We already have an empty page in
620: * first_object - use it.
621: */
622:
623: vm_page_copy(m, first_m);
624: first_m->absent = FALSE;
625:
626: /*
627: * If another map is truly sharing this
628: * page with us, we have to flush all
629: * uses of the original page, since we
630: * can't distinguish those which want the
631: * original from those which need the
632: * new copy.
633: */
634:
635: vm_page_lock_queues();
636: /*
637: * We first activate the page, then deactivate
638: * it since vm_page_deactivate will only
639: * deactivate active pages.
640: */
641: vm_page_activate(m);
642: vm_page_deactivate(m);
643: if (!su)
644: pmap_remove_all(VM_PAGE_TO_PHYS(m));
645: vm_page_unlock_queues();
646:
647: /*
648: * We no longer need the old page or object.
649: */
650: PAGE_WAKEUP(m);
651: object->paging_in_progress--;
652: vm_object_unlock(object);
653:
654: /*
655: * Only use the new page below...
656: */
657:
658: vm_stat.cow_faults++;
659: m = first_m;
660: object = first_object;
661: offset = first_offset;
662:
663: /*
664: * Now that we've gotten the copy out of the
665: * way, let's try to collapse the top object.
666: */
667: vm_object_lock(object);
668: /*
669: * But we have to play ugly games with
670: * paging_in_progress to do that...
671: */
672: object->paging_in_progress--;
673: vm_object_collapse(object);
674: object->paging_in_progress++;
675: }
676: else {
677: prot &= (~VM_PROT_WRITE);
678: m->copy_on_write = TRUE;
679: }
680: }
681:
682: if (m->active || m->inactive)
683: panic("vm_fault: active or inactive before copy object handling");
684:
685: /*
686: * If the page is being written, but hasn't been
687: * copied to the copy-object, we have to copy it there.
688: */
689: RetryCopy:
690: if (first_object->copy != VM_OBJECT_NULL) {
691: vm_object_t copy_object = first_object->copy;
692: vm_offset_t copy_offset;
693: vm_page_t copy_m;
694:
695: /*
696: * We only need to copy if we want to write it.
697: */
698: if ((fault_type & VM_PROT_WRITE) == 0) {
699: prot &= ~VM_PROT_WRITE;
700: m->copy_on_write = TRUE;
701: }
702: else {
703: /*
704: * Try to get the lock on the copy_object.
705: */
706: if (!vm_object_lock_try(copy_object)) {
707: vm_object_unlock(object);
708: /* should spin a bit here... */
709: vm_object_lock(object);
710: goto RetryCopy;
711: }
712:
713: /*
714: * Make another reference to the copy-object,
715: * to keep it from disappearing during the
716: * copy.
717: */
718: copy_object->ref_count++;
719:
720: /*
721: * Does the page exist in the copy?
722: */
723: copy_offset = first_offset
724: - copy_object->shadow_offset;
725: copy_m = vm_page_lookup(copy_object, copy_offset);
726: if (page_exists = (copy_m != VM_PAGE_NULL)) {
727: if (copy_m->busy) {
728: kern_return_t wait_result;
729: #if SCRUBVM3
730: /* hint if we miss it its ok */
731: if (copy_m->dry_vp){
732: vm_page_lock_queues();
733: (void) vm_page_completeio(copy_m, TRUE);
734: vm_page_unlock_queues();
735: } else {
736: #endif
737:
738: /*
739: * If the page is being brought
740: * in, wait for it and then retry.
741: */
742: PAGE_ASSERT_WAIT(copy_m, !change_wiring);
743: RELEASE_PAGE(m);
744: copy_object->ref_count--;
745: vm_object_unlock(copy_object);
746: UNLOCK_THINGS;
747: thread_block();
748: wait_result = current_thread()->wait_result;
749: vm_object_deallocate(first_object);
750: /* may block */
751: if (wait_result != THREAD_AWAKENED)
752: return(KERN_SUCCESS);
753: goto RetryFault;
754: #if SCRUBVM3
755: }
756: #endif
757: }
758: }
759:
760: #if MACH_XP
761: else {
762: /*
763: * Allocate a page for the copy
764: */
765: copy_m = vm_page_alloc(copy_object,
766: copy_offset);
767: if (copy_m == VM_PAGE_NULL) {
768: /*
769: * Wait for a page, then retry.
770: */
771: RELEASE_PAGE(m);
772: copy_object->ref_count--;
773: vm_object_unlock(copy_object);
774: UNLOCK_AND_DEALLOCATE;
775: VM_WAIT;
776: goto RetryFault;
777: }
778:
779: /*
780: * Must copy page into copy-object.
781: */
782:
783: vm_page_copy(m, copy_m);
784: m->copy_on_write = FALSE;
785: copy_m->absent = FALSE;
786:
787: /*
788: * If the old page was in use by any users
789: * of the copy-object, it must be removed
790: * from all pmaps. (We can't know which
791: * pmaps use it.)
792: */
793:
794: vm_page_lock_queues();
795: pmap_remove_all(VM_PAGE_TO_PHYS(old_m));
796: copy_m->clean = FALSE;
797: vm_page_unlock_queues();
798:
799: /*
800: * If there's a pager, then immediately
801: * page out this page, using the "initialize"
802: * option. Else, we use the copy.
803: */
804:
805: if (copy_object->pager == vm_pager_null) {
806: vm_page_lock_queues();
807: vm_page_activate(copy_m);
808: vm_page_unlock_queues();
809: PAGE_WAKEUP(copy_m);
810: } else {
811: /*
812: * Prepare the page for pageout:
813: *
814: * Since it was just allocated,
815: * it is not on a pageout queue, but
816: * it is busy.
817: */
818:
819: copy_m->busy = FALSE;
820:
821: /*
822: * Unlock everything except the
823: * copy_object itself.
824: */
825:
826: vm_object_unlock(object);
827: UNLOCK_MAP;
828:
829: vm_pageout_page(copy_m, TRUE);
830:
831: /*
832: * Since the pageout may have
833: * temporarily dropped the
834: * copy_object's lock, we
835: * check whether we'll have
836: * to deallocate the hard way.
837: */
838:
839: if ((copy_object->shadow != object) ||
840: (copy_object->ref_count == 1)) {
841: vm_object_unlock(copy_object);
842: vm_object_deallocate(copy_object);
843: vm_object_lock(object);
844: goto RetryCopy;
845: }
846:
847: /*
848: * Pick back up the old object's
849: * lock. [It is safe to do so,
850: * since it must be deeper in the
851: * object tree.]
852: */
853:
854: vm_object_lock(object);
855: }
856: }
857: #if defined(lint) || defined(hc)
858: if (++page_exists != 0)
859: panic("lint");
860: #endif defined(lint) || defined(hc)
861: #else MACH_XP
862: /*
863: * If the page is not in memory (in the object)
864: * and the object has a pager, we have to check
865: * if the pager has the data in secondary
866: * storage.
867: */
868: if (!page_exists) {
869:
870: /*
871: * If we don't allocate a (blank) page
872: * here... another thread could try
873: * to page it in, allocate a page, and
874: * then block on the busy page in its
875: * shadow (first_object). Then we'd
876: * trip over the busy page after we
877: * found that the copy_object's pager
878: * doesn't have the page...
879: */
880: copy_m = vm_page_alloc(copy_object,
881: copy_offset);
882: if (copy_m == VM_PAGE_NULL) {
883: /*
884: * Wait for a page, then retry.
885: */
886: RELEASE_PAGE(m);
887: copy_object->ref_count--;
888: vm_object_unlock(copy_object);
889: UNLOCK_AND_DEALLOCATE;
890: VM_WAIT;
891: goto RetryFault;
892: }
893:
894: if (copy_object->pager != vm_pager_null) {
895: vm_object_unlock(object);
896: vm_object_unlock(copy_object);
897: UNLOCK_MAP;
898:
899: page_exists = vm_pager_has_page(
900: copy_object->pager,
901: (copy_offset + copy_object->paging_offset));
902:
903: vm_object_lock(copy_object);
904:
905: /*
906: * Since the map is unlocked, someone
907: * else could have copied this object
908: * and put a different copy_object
909: * between the two. Or, the last
910: * reference to the copy-object (other
911: * than the one we have) may have
912: * disappeared - if that has happened,
913: * we don't need to make the copy.
914: */
915: if (copy_object->shadow != object ||
916: copy_object->ref_count == 1) {
917: /*
918: * Gaah... start over!
919: */
920: FREE_PAGE(copy_m);
921: vm_object_unlock(copy_object);
922: vm_object_deallocate(copy_object);
923: /* may block */
924: vm_object_lock(object);
925: goto RetryCopy;
926: }
927: vm_object_lock(object);
928:
929: if (page_exists) {
930: /*
931: * We didn't need the page
932: */
933: FREE_PAGE(copy_m);
934: }
935: }
936: }
937: if (!page_exists) {
938: /*
939: * Must copy page into copy-object.
940: */
941: vm_page_copy(m, copy_m);
942: copy_m->absent = FALSE;
943:
944: /*
945: * Things to remember:
946: * 1. The copied page must be marked 'dirty'
947: * so it will be paged out to the copy
948: * object.
949: * 2. If the old page was in use by any users
950: * of the copy-object, it must be removed
951: * from all pmaps. (We can't know which
952: * pmaps use it.)
953: */
954: vm_page_lock_queues();
955: pmap_remove_all(VM_PAGE_TO_PHYS(old_m));
956: copy_m->clean = FALSE;
957: vm_page_activate(copy_m); /* XXX */
958: vm_page_unlock_queues();
959:
960: PAGE_WAKEUP(copy_m);
961: }
962: #endif MACH_XP
963: /*
964: * The reference count on copy_object must be
965: * at least 2: one for our extra reference,
966: * and at least one from the outside world
967: * (we checked that when we last locked
968: * copy_object).
969: */
970: copy_object->ref_count--;
971: vm_object_unlock(copy_object);
972: m->copy_on_write = FALSE;
973: }
974: }
975:
976: if (m->active || m->inactive)
977: panic("vm_fault: active or inactive before retrying lookup");
978:
979: /*
980: * We must verify that the maps have not changed
981: * since our last lookup.
982: */
983:
984: #if USE_VERSIONS
985: vm_object_unlock(object);
986: while (!vm_map_verify(map, &version)) {
987: vm_object_t retry_object;
988: vm_offset_t retry_offset;
989: vm_prot_t retry_prot;
990:
991: /*
992: * To avoid trying to write_lock the map while another
993: * thread has it read_locked (in vm_map_pageable), we
994: * do not try for write permission. If the page is
995: * still writable, we will get write permission. If it
996: * is not, or has been marked needs_copy, we enter the
997: * mapping without write permission, and will merely
998: * take another fault.
999: */
1000: result = vm_map_lookup(&map, vaddr,
1001: fault_type & ~VM_PROT_WRITE, &version,
1002: &retry_object, &retry_offset, &retry_prot,
1003: &wired, &su);
1004:
1005: if (result != KERN_SUCCESS) {
1006: RELEASE_PAGE(m);
1007: UNLOCK_AND_DEALLOCATE;
1008: return(result);
1009: }
1010:
1011: vm_object_unlock(retry_object);
1012: vm_object_lock(object);
1013:
1014: if ((retry_object != first_object) ||
1015: (retry_offset != first_offset)) {
1016: RELEASE_PAGE(m);
1017: UNLOCK_AND_DEALLOCATE;
1018: goto RetryFault;
1019: }
1020:
1021: /*
1022: * Check whether the protection has changed or the object
1023: * has been copied while we left the map unlocked.
1024: * Changing from read to write permission is OK - we leave
1025: * the page write-protected, and catch the write fault.
1026: * Changing from write to read permission means that we
1027: * can't mark the page write-enabled after all.
1028: */
1029: prot &= retry_prot;
1030: if (m->copy_on_write)
1031: prot &= ~VM_PROT_WRITE;
1032:
1033: vm_object_unlock(object);
1034: }
1035: vm_object_lock(object);
1036: #else USE_VERSIONS
1037:
1038: if (!lookup_still_valid) {
1039: vm_object_t retry_object;
1040: vm_offset_t retry_offset;
1041: vm_prot_t retry_prot;
1042:
1043: /*
1044: * Since map entries may be pageable, make sure we can
1045: * take a page fault on them.
1046: */
1047: vm_object_unlock(object);
1048:
1049: /*
1050: * To avoid trying to write_lock the map while another
1051: * thread has it read_locked (in vm_map_pageable), we
1052: * do not try for write permission. If the page is
1053: * still writable, we will get write permission. If it
1054: * is not, or has been marked needs_copy, we enter the
1055: * mapping without write permission, and will merely
1056: * take another fault.
1057: */
1058:
1059: result = vm_map_lookup(&map, vaddr,
1060: fault_type & ~VM_PROT_WRITE, &entry,
1061: &retry_object, &retry_offset, &retry_prot,
1062: &wired, &su);
1063: vm_object_lock(object);
1064:
1065: /*
1066: * If we don't need the page any longer, put it on the
1067: * active list (the easiest thing to do here). If no
1068: * one needs it, pageout will grab it eventually.
1069: */
1070:
1071: if (result != KERN_SUCCESS) {
1072: RELEASE_PAGE(m);
1073: UNLOCK_AND_DEALLOCATE;
1074: return(result);
1075: }
1076:
1077: lookup_still_valid = TRUE;
1078:
1079: if ((retry_object != first_object) ||
1080: (retry_offset != first_offset)) {
1081: RELEASE_PAGE(m);
1082: UNLOCK_AND_DEALLOCATE;
1083: goto RetryFault;
1084: }
1085:
1086: /*
1087: * Check whether the protection has changed or the object
1088: * has been copied while we left the map unlocked.
1089: * Changing from read to write permission is OK - we leave
1090: * the page write-protected, and catch the write fault.
1091: * Changing from write to read permission means that we
1092: * can't mark the page write-enabled after all.
1093: */
1094: prot &= retry_prot;
1095: if (m->copy_on_write)
1096: prot &= ~VM_PROT_WRITE;
1097: /*
1098: * Can't catch write fault if page is to be wired. This
1099: * should never happen because caller holds a read lock
1100: * on the map.
1101: */
1102: if (wired && (prot != fault_type)) {
1103: RELEASE_PAGE(m);
1104: UNLOCK_AND_DEALLOCATE;
1105: goto RetryFault;
1106: }
1107: }
1108: #endif USE_VERSIONS
1109:
1110: /*
1111: * (the various bits we're fiddling with here are locked by
1112: * the object's lock)
1113: */
1114:
1115: /* XXX This distorts the meaning of the copy_on_write bit */
1116:
1117: if (prot & VM_PROT_WRITE)
1118: m->copy_on_write = FALSE;
1119:
1120: /*
1121: * It's critically important that a wired-down page be faulted
1122: * only once in each map for which it is wired.
1123: */
1124:
1125: if (m->active || m->inactive)
1126: panic("vm_fault: active or inactive before pmap_enter");
1127:
1128: vm_object_unlock(object);
1129:
1130: /*
1131: * Put this page into the physical map.
1132: * We had to do the unlock above because pmap_enter
1133: * may cause other faults. We don't put the
1134: * page back on the active queue until later so
1135: * that the page-out daemon won't find us (yet).
1136: */
1137:
1138: pmap_enter(map->pmap, vaddr, VM_PAGE_TO_PHYS(m),
1139: prot & ~(m->page_lock), wired);
1140:
1141: /*
1142: * If the page is not wired down, then put it where the
1143: * pageout daemon can find it.
1144: */
1145: vm_object_lock(object);
1146: vm_page_lock_queues();
1147: if (change_wiring) {
1148: if (wired)
1149: vm_page_wire(m);
1150: else
1151: vm_page_unwire(m);
1152: }
1153: else
1154: vm_page_activate(m);
1155: vm_page_unlock_queues();
1156:
1157: /*
1158: * Unlock everything, and return
1159: */
1160:
1161: #if USE_VERSIONS
1162: vm_map_verify_done(map, &version);
1163: #endif USE_VERSIONS
1164: PAGE_WAKEUP(m);
1165: UNLOCK_AND_DEALLOCATE;
1166:
1167: return(KERN_SUCCESS);
1168:
1169: }
1170:
1171: kern_return_t vm_fault_wire_fast();
1172:
1173: /*
1174: * vm_fault_wire:
1175: *
1176: * Wire down a range of virtual addresses in a map.
1177: */
1178: void vm_fault_wire(map, entry)
1179: vm_map_t map;
1180: vm_map_entry_t entry;
1181: {
1182:
1183: register vm_offset_t va;
1184: register pmap_t pmap;
1185: register vm_offset_t end_addr = entry->vme_end;
1186:
1187: pmap = vm_map_pmap(map);
1188:
1189: /*
1190: * Inform the physical mapping system that the
1191: * range of addresses may not fault, so that
1192: * page tables and such can be locked down as well.
1193: */
1194:
1195: pmap_pageable(pmap, entry->vme_start, end_addr, FALSE);
1196:
1197: /*
1198: * We simulate a fault to get the page and enter it
1199: * in the physical map.
1200: */
1201:
1202: for (va = entry->vme_start; va < end_addr; va += PAGE_SIZE) {
1203: if (vm_fault_wire_fast(map, va, entry) != KERN_SUCCESS)
1204: (void) vm_fault(map, va, VM_PROT_NONE, TRUE, 0);
1205: }
1206: }
1207:
1208:
1209: /*
1210: * vm_fault_unwire:
1211: *
1212: * Unwire a range of virtual addresses in a map.
1213: */
1214: void vm_fault_unwire(map, entry)
1215: vm_map_t map;
1216: vm_map_entry_t entry;
1217: {
1218:
1219: register vm_offset_t va, pa;
1220: register pmap_t pmap;
1221: register vm_offset_t end_addr = entry->vme_end;
1222:
1223: pmap = vm_map_pmap(map);
1224:
1225: /*
1226: * Since the pages are wired down, we must be able to
1227: * get their mappings from the physical map system.
1228: */
1229:
1230: vm_page_lock_queues();
1231:
1232: for (va = entry->vme_start; va < end_addr; va += PAGE_SIZE) {
1233: pa = pmap_extract(pmap, va);
1234: if (pa == (vm_offset_t) 0)
1235: continue;
1236:
1237: pmap_change_wiring(pmap, va, FALSE);
1238: vm_page_unwire(PHYS_TO_VM_PAGE(pa));
1239: }
1240: vm_page_unlock_queues();
1241:
1242: /*
1243: * Inform the physical mapping system that the range
1244: * of addresses may fault, so that page tables and
1245: * such may be unwired themselves.
1246: */
1247:
1248: pmap_pageable(pmap, entry->vme_start, end_addr, TRUE);
1249:
1250: }
1251:
1252: /*
1253: * Routine:
1254: * vm_fault_copy_entry
1255: * Function:
1256: * Copy all of the pages from a wired-down map entry to another.
1257: *
1258: * In/out conditions:
1259: * The source and destination maps must be locked for write.
1260: * The source map entry must be wired down (or be a sharing map
1261: * entry corresponding to a main map entry that is wired down).
1262: */
1263:
1264: void vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry)
1265: vm_map_t dst_map;
1266: vm_map_t src_map;
1267: vm_map_entry_t dst_entry;
1268: vm_map_entry_t src_entry;
1269: {
1270:
1271: vm_object_t dst_object;
1272: vm_object_t src_object;
1273: vm_offset_t dst_offset;
1274: vm_offset_t src_offset;
1275: vm_prot_t prot;
1276: vm_offset_t vaddr;
1277: vm_page_t dst_m;
1278: vm_page_t src_m;
1279:
1280: #ifdef lint
1281: src_map++;
1282: #endif lint
1283:
1284: src_object = src_entry->object.vm_object;
1285: src_offset = src_entry->offset;
1286:
1287: /*
1288: * Create the top-level object for the destination entry.
1289: * (Doesn't actually shadow anything - we copy the pages
1290: * directly.)
1291: */
1292: dst_object = vm_object_allocate(
1293: (vm_size_t) (dst_entry->vme_end -
1294: dst_entry->vme_start));
1295:
1296: dst_entry->object.vm_object = dst_object;
1297: dst_entry->offset = 0;
1298:
1299: prot = dst_entry->max_protection;
1300:
1301: /*
1302: * Loop through all of the pages in the entry's range, copying
1303: * each one from the source object (it should be there) to the
1304: * destination object.
1305: */
1306: for (vaddr = dst_entry->vme_start, dst_offset = 0;
1307: vaddr < dst_entry->vme_end;
1308: vaddr += PAGE_SIZE, dst_offset += PAGE_SIZE) {
1309:
1310: /*
1311: * Allocate a page in the destination object
1312: */
1313: vm_object_lock(dst_object);
1314: do {
1315: dst_m = vm_page_alloc(dst_object, dst_offset);
1316: if (dst_m == VM_PAGE_NULL) {
1317: vm_object_unlock(dst_object);
1318: VM_WAIT;
1319: vm_object_lock(dst_object);
1320: }
1321: } while (dst_m == VM_PAGE_NULL);
1322:
1323: /*
1324: * Find the page in the source object, and copy it in.
1325: * (Because the source is wired down, the page will be
1326: * in memory.)
1327: */
1328: vm_object_lock(src_object);
1329: src_m = vm_page_lookup(src_object, dst_offset + src_offset);
1330: if (src_m == VM_PAGE_NULL)
1331: panic("vm_fault_copy_wired: page missing");
1332:
1333: vm_page_copy(src_m, dst_m);
1334:
1335: /*
1336: * Enter it in the pmap...
1337: */
1338: vm_object_unlock(src_object);
1339: vm_object_unlock(dst_object);
1340:
1341: pmap_enter(dst_map->pmap, vaddr, VM_PAGE_TO_PHYS(dst_m),
1342: prot, FALSE);
1343:
1344: /*
1345: * Mark it no longer busy, and put it on the active list.
1346: */
1347: vm_object_lock(dst_object);
1348: vm_page_lock_queues();
1349: vm_page_activate(dst_m);
1350: vm_page_unlock_queues();
1351: PAGE_WAKEUP(dst_m);
1352: vm_object_unlock(dst_object);
1353: }
1354:
1355: }
1356:
1357:
1358: /*
1359: * vm_fault_wire_fast:
1360: *
1361: * Handle common case of a wire down page fault at the given address.
1362: * If successful, the page is inserted into the associated physical map.
1363: * The map entry is passed in to avoid the overhead of a map lookup.
1364: *
1365: * NOTE: the given address should be truncated to the
1366: * proper page address.
1367: *
1368: * KERN_SUCCESS is returned if the page fault is handled; otherwise,
1369: * a standard error specifying why the fault is fatal is returned.
1370: *
1371: * The map in question must be referenced, and remains so.
1372: * Caller has a read lock on the map.
1373: *
1374: * This is a stripped version of vm_fault() for wiring pages. Anything
1375: * other than the common case will return KERN_FAILURE, and the caller
1376: * is expected to call vm_fault().
1377: */
1378: kern_return_t vm_fault_wire_fast(map, va, entry)
1379: vm_map_t map;
1380: vm_offset_t va;
1381: vm_map_entry_t entry;
1382: {
1383: vm_object_t object;
1384: vm_offset_t offset;
1385: register vm_page_t m;
1386: vm_prot_t prot;
1387:
1388: vm_stat.faults++; /* needs lock XXX */
1389: /*
1390: * Recovery actions
1391: */
1392:
1393: #undef RELEASE_PAGE
1394: #define RELEASE_PAGE(m) { \
1395: PAGE_WAKEUP(m); \
1396: vm_page_lock_queues(); \
1397: vm_page_unwire(m); \
1398: vm_page_unlock_queues(); \
1399: }
1400:
1401:
1402: #undef UNLOCK_THINGS
1403: #define UNLOCK_THINGS { \
1404: object->paging_in_progress--; \
1405: vm_object_unlock(object); \
1406: }
1407:
1408: #undef UNLOCK_AND_DEALLOCATE
1409: #define UNLOCK_AND_DEALLOCATE { \
1410: UNLOCK_THINGS; \
1411: vm_object_deallocate(object); \
1412: }
1413: /*
1414: * Give up and have caller do things the hard way.
1415: */
1416:
1417: #define GIVE_UP { \
1418: UNLOCK_AND_DEALLOCATE; \
1419: return(KERN_FAILURE); \
1420: }
1421:
1422:
1423: /*
1424: * If this entry is not directly to a vm_object, bail out.
1425: */
1426: if ((entry->is_a_map) || (entry->is_sub_map))
1427: return(KERN_FAILURE);
1428:
1429: /*
1430: * Find the backing store object and offset into it.
1431: */
1432:
1433: object = entry->object.vm_object;
1434: offset = va - entry->vme_start + entry->offset;
1435: prot = entry->protection;
1436:
1437: /*
1438: * Make a reference to this object to prevent its
1439: * disposal while we are messing with it.
1440: */
1441:
1442: vm_object_lock(object);
1443: object->ref_count++;
1444: object->paging_in_progress++;
1445:
1446: /*
1447: * INVARIANTS (through entire routine):
1448: *
1449: * 1) At all times, we must either have the object
1450: * lock or a busy page in some object to prevent
1451: * some other thread from trying to bring in
1452: * the same page.
1453: *
1454: * 2) Once we have a busy page, we must remove it from
1455: * the pageout queues, so that the pageout daemon
1456: * will not grab it away.
1457: *
1458: */
1459:
1460: /*
1461: * Look for page in top-level object. If it's not there or
1462: * there's something going on, give up.
1463: */
1464: m = vm_page_lookup(object, offset);
1465: #if SCRUBVM3
1466: if ((m != VM_PAGE_NULL) && (m->dry_vp)){
1467: vm_page_lock_queues();
1468: (void) vm_page_completeio(m, TRUE);
1469: vm_page_unlock_queues();
1470: }
1471: #endif
1472: if ((m == VM_PAGE_NULL) || (m->busy) || (m->absent) ||
1473: (prot & m->page_lock)) {
1474: GIVE_UP;
1475: }
1476:
1477: /*
1478: * Wire the page down now. All bail outs beyond this
1479: * point must unwire the page.
1480: */
1481:
1482: vm_page_lock_queues();
1483: vm_page_wire(m);
1484: vm_page_unlock_queues();
1485:
1486: /*
1487: * Mark page busy for other threads.
1488: */
1489: m->busy = TRUE;
1490: m->absent = FALSE;
1491:
1492: /*
1493: * Give up if the page is being written and there's a copy object
1494: */
1495: if (object->copy != VM_OBJECT_NULL) {
1496: if ((prot & VM_PROT_WRITE) == 0) {
1497: m->copy_on_write = TRUE;
1498: }
1499: else {
1500: RELEASE_PAGE(m);
1501: GIVE_UP;
1502: }
1503: }
1504:
1505: /*
1506: * (the various bits we're fiddling with here are locked by
1507: * the object's lock)
1508: */
1509:
1510: /* XXX This distorts the meaning of the copy_on_write bit */
1511:
1512: if (prot & VM_PROT_WRITE)
1513: m->copy_on_write = FALSE;
1514:
1515: /*
1516: * Put this page into the physical map.
1517: * We have to unlock the object because pmap_enter
1518: * may cause other faults.
1519: */
1520: vm_object_unlock(object);
1521:
1522: pmap_enter(map->pmap, va, VM_PAGE_TO_PHYS(m), prot , TRUE);
1523:
1524: /*
1525: * Must relock object so that paging_in_progress can be cleared.
1526: */
1527: vm_object_lock(object);
1528:
1529: /*
1530: * Unlock everything, and return
1531: */
1532:
1533: PAGE_WAKEUP(m);
1534: UNLOCK_AND_DEALLOCATE;
1535:
1536: return(KERN_SUCCESS);
1537:
1538: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.