1 /* 2 * Copyright (c) 1987 Carnegie-Mellon University. 3 * All rights reserved. 4 * 5 * Authors: Avadis Tevanian, Jr., Michael Wayne Young 6 * 7 * Permission to use, copy, modify and distribute this software and 8 * its documentation is hereby granted, provided that both the copyright 9 * notice and this permission notice appear in all copies of the 10 * software, derivative works or modified versions, and any portions 11 * thereof, and that both notices appear in supporting documentation. 12 * 13 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 14 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 15 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 16 * 17 * Carnegie Mellon requests users of this software to return to Carnegie 18 * any improvements or extensions that they make and grant Carnegie 19 * the rights to redistribute these changes. We can be reached at 20 * mach@cs.cmu.edu or 21 * Project Mach 22 * School of Computer Science 23 * Carnegie Mellon University 24 * Pittsburgh PA 15213-3890 25 * 26 * 27 * Copyright (c) 1991 Regents of the University of California. 28 * All rights reserved. 29 * 30 * This code is derived from software contributed to Berkeley by 31 * The Mach Operating System project at Carnegie-Mellon University. 32 * 33 * %sccs.include.redist.c% 34 * 35 * @(#)vm_fault.c 7.3 (Berkeley) 03/27/91 36 */ 37 38 /* 39 * Page fault handling module. 40 */ 41 42 #include "param.h" 43 #include "../vm/vm_param.h" 44 #include "../vm/vm_map.h" 45 #include "../vm/vm_object.h" 46 #include "../vm/vm_page.h" 47 #include "../vm/pmap.h" 48 #include "../vm/vm_statistics.h" 49 #include "../vm/vm_pageout.h" 50 51 /* 52 * vm_fault: 53 * 54 * Handle a page fault occuring at the given address, 55 * requiring the given permissions, in the map specified. 56 * If successful, the page is inserted into the 57 * associated physical map. 58 * 59 * NOTE: the given address should be truncated to the 60 * proper page address. 61 * 62 * KERN_SUCCESS is returned if the page fault is handled; otherwise, 63 * a standard error specifying why the fault is fatal is returned. 64 * 65 * 66 * The map in question must be referenced, and remains so. 67 * Caller may hold no locks. 68 */ 69 vm_fault(map, vaddr, fault_type, change_wiring) 70 vm_map_t map; 71 vm_offset_t vaddr; 72 vm_prot_t fault_type; 73 boolean_t change_wiring; 74 { 75 vm_object_t first_object; 76 vm_offset_t first_offset; 77 vm_map_entry_t entry; 78 register vm_object_t object; 79 register vm_offset_t offset; 80 register vm_page_t m; 81 vm_page_t first_m; 82 vm_prot_t prot; 83 int result; 84 boolean_t wired; 85 boolean_t su; 86 boolean_t lookup_still_valid; 87 boolean_t page_exists; 88 vm_page_t old_m; 89 vm_object_t next_object; 90 91 vm_stat.faults++; /* needs lock XXX */ 92 /* 93 * Recovery actions 94 */ 95 #define FREE_PAGE(m) { \ 96 PAGE_WAKEUP(m); \ 97 vm_page_lock_queues(); \ 98 vm_page_free(m); \ 99 vm_page_unlock_queues(); \ 100 } 101 102 #define RELEASE_PAGE(m) { \ 103 PAGE_WAKEUP(m); \ 104 vm_page_lock_queues(); \ 105 vm_page_activate(m); \ 106 vm_page_unlock_queues(); \ 107 } 108 109 #define UNLOCK_MAP { \ 110 if (lookup_still_valid) { \ 111 vm_map_lookup_done(map, entry); \ 112 lookup_still_valid = FALSE; \ 113 } \ 114 } 115 116 #define UNLOCK_THINGS { \ 117 object->paging_in_progress--; \ 118 vm_object_unlock(object); \ 119 if (object != first_object) { \ 120 vm_object_lock(first_object); \ 121 FREE_PAGE(first_m); \ 122 first_object->paging_in_progress--; \ 123 vm_object_unlock(first_object); \ 124 } \ 125 UNLOCK_MAP; \ 126 } 127 128 #define UNLOCK_AND_DEALLOCATE { \ 129 UNLOCK_THINGS; \ 130 vm_object_deallocate(first_object); \ 131 } 132 133 RetryFault: ; 134 135 /* 136 * Find the backing store object and offset into 137 * it to begin the search. 138 */ 139 140 if ((result = vm_map_lookup(&map, vaddr, fault_type, &entry, 141 &first_object, &first_offset, 142 &prot, &wired, &su)) != KERN_SUCCESS) { 143 return(result); 144 } 145 lookup_still_valid = TRUE; 146 147 if (wired) 148 fault_type = prot; 149 150 first_m = VM_PAGE_NULL; 151 152 /* 153 * Make a reference to this object to 154 * prevent its disposal while we are messing with 155 * it. Once we have the reference, the map is free 156 * to be diddled. Since objects reference their 157 * shadows (and copies), they will stay around as well. 158 */ 159 160 vm_object_lock(first_object); 161 162 first_object->ref_count++; 163 first_object->paging_in_progress++; 164 165 /* 166 * INVARIANTS (through entire routine): 167 * 168 * 1) At all times, we must either have the object 169 * lock or a busy page in some object to prevent 170 * some other thread from trying to bring in 171 * the same page. 172 * 173 * Note that we cannot hold any locks during the 174 * pager access or when waiting for memory, so 175 * we use a busy page then. 176 * 177 * Note also that we aren't as concerned about 178 * more than one thead attempting to pager_data_unlock 179 * the same page at once, so we don't hold the page 180 * as busy then, but do record the highest unlock 181 * value so far. [Unlock requests may also be delivered 182 * out of order.] 183 * 184 * 2) Once we have a busy page, we must remove it from 185 * the pageout queues, so that the pageout daemon 186 * will not grab it away. 187 * 188 * 3) To prevent another thread from racing us down the 189 * shadow chain and entering a new page in the top 190 * object before we do, we must keep a busy page in 191 * the top object while following the shadow chain. 192 * 193 * 4) We must increment paging_in_progress on any object 194 * for which we have a busy page, to prevent 195 * vm_object_collapse from removing the busy page 196 * without our noticing. 197 */ 198 199 /* 200 * Search for the page at object/offset. 201 */ 202 203 object = first_object; 204 offset = first_offset; 205 206 /* 207 * See whether this page is resident 208 */ 209 210 while (TRUE) { 211 m = vm_page_lookup(object, offset); 212 if (m != VM_PAGE_NULL) { 213 /* 214 * If the page is being brought in, 215 * wait for it and then retry. 216 */ 217 if (m->busy) { 218 #ifdef DOTHREADS 219 int wait_result; 220 221 PAGE_ASSERT_WAIT(m, !change_wiring); 222 UNLOCK_THINGS; 223 thread_block(); 224 wait_result = current_thread()->wait_result; 225 vm_object_deallocate(first_object); 226 if (wait_result != THREAD_AWAKENED) 227 return(KERN_SUCCESS); 228 goto RetryFault; 229 #else 230 PAGE_ASSERT_WAIT(m, !change_wiring); 231 UNLOCK_THINGS; 232 thread_block(); 233 vm_object_deallocate(first_object); 234 goto RetryFault; 235 #endif 236 } 237 238 if (m->absent) 239 panic("vm_fault: absent"); 240 241 /* 242 * If the desired access to this page has 243 * been locked out, request that it be unlocked. 244 */ 245 246 if (fault_type & m->page_lock) { 247 #ifdef DOTHREADS 248 int wait_result; 249 250 if ((fault_type & m->unlock_request) != fault_type) 251 panic("vm_fault: pager_data_unlock"); 252 253 PAGE_ASSERT_WAIT(m, !change_wiring); 254 UNLOCK_THINGS; 255 thread_block(); 256 wait_result = current_thread()->wait_result; 257 vm_object_deallocate(first_object); 258 if (wait_result != THREAD_AWAKENED) 259 return(KERN_SUCCESS); 260 goto RetryFault; 261 #else 262 if ((fault_type & m->unlock_request) != fault_type) 263 panic("vm_fault: pager_data_unlock"); 264 265 PAGE_ASSERT_WAIT(m, !change_wiring); 266 UNLOCK_THINGS; 267 thread_block(); 268 vm_object_deallocate(first_object); 269 goto RetryFault; 270 #endif 271 } 272 273 /* 274 * Remove the page from the pageout daemon's 275 * reach while we play with it. 276 */ 277 278 vm_page_lock_queues(); 279 if (m->inactive) { 280 queue_remove(&vm_page_queue_inactive, m, 281 vm_page_t, pageq); 282 m->inactive = FALSE; 283 vm_page_inactive_count--; 284 vm_stat.reactivations++; 285 } 286 287 if (m->active) { 288 queue_remove(&vm_page_queue_active, m, 289 vm_page_t, pageq); 290 m->active = FALSE; 291 vm_page_active_count--; 292 } 293 vm_page_unlock_queues(); 294 295 /* 296 * Mark page busy for other threads. 297 */ 298 m->busy = TRUE; 299 m->absent = FALSE; 300 break; 301 } 302 303 if (((object->pager != vm_pager_null) && 304 (!change_wiring || wired)) 305 || (object == first_object)) { 306 307 /* 308 * Allocate a new page for this object/offset 309 * pair. 310 */ 311 312 m = vm_page_alloc(object, offset); 313 314 if (m == VM_PAGE_NULL) { 315 UNLOCK_AND_DEALLOCATE; 316 VM_WAIT; 317 goto RetryFault; 318 } 319 } 320 321 if ((object->pager != vm_pager_null) && 322 (!change_wiring || wired)) { 323 int rv; 324 325 /* 326 * Now that we have a busy page, we can 327 * release the object lock. 328 */ 329 vm_object_unlock(object); 330 331 /* 332 * Call the pager to retrieve the data, if any, 333 * after releasing the lock on the map. 334 */ 335 UNLOCK_MAP; 336 337 rv = vm_pager_get(object->pager, m, TRUE); 338 if (rv == VM_PAGER_OK) { 339 /* 340 * Found the page. 341 * Leave it busy while we play with it. 342 */ 343 vm_object_lock(object); 344 345 /* 346 * Relookup in case pager changed page. 347 * Pager is responsible for disposition 348 * of old page if moved. 349 */ 350 m = vm_page_lookup(object, offset); 351 352 vm_stat.pageins++; 353 m->fake = FALSE; 354 pmap_clear_modify(VM_PAGE_TO_PHYS(m)); 355 break; 356 } 357 358 /* 359 * Remove the bogus page (which does not 360 * exist at this object/offset); before 361 * doing so, we must get back our object 362 * lock to preserve our invariant. 363 * 364 * Also wake up any other thread that may want 365 * to bring in this page. 366 * 367 * If this is the top-level object, we must 368 * leave the busy page to prevent another 369 * thread from rushing past us, and inserting 370 * the page in that object at the same time 371 * that we are. 372 */ 373 374 vm_object_lock(object); 375 /* 376 * Data outside the range of the pager; an error 377 */ 378 if (rv == VM_PAGER_BAD) { 379 FREE_PAGE(m); 380 UNLOCK_AND_DEALLOCATE; 381 return(KERN_PROTECTION_FAILURE); /* XXX */ 382 } 383 if (object != first_object) { 384 FREE_PAGE(m); 385 /* 386 * XXX - we cannot just fall out at this 387 * point, m has been freed and is invalid! 388 */ 389 } 390 } 391 392 /* 393 * We get here if the object has no pager (or unwiring) 394 * or the pager doesn't have the page. 395 */ 396 if (object == first_object) 397 first_m = m; 398 399 /* 400 * Move on to the next object. Lock the next 401 * object before unlocking the current one. 402 */ 403 404 offset += object->shadow_offset; 405 next_object = object->shadow; 406 if (next_object == VM_OBJECT_NULL) { 407 /* 408 * If there's no object left, fill the page 409 * in the top object with zeros. 410 */ 411 if (object != first_object) { 412 object->paging_in_progress--; 413 vm_object_unlock(object); 414 415 object = first_object; 416 offset = first_offset; 417 m = first_m; 418 vm_object_lock(object); 419 } 420 first_m = VM_PAGE_NULL; 421 422 vm_page_zero_fill(m); 423 vm_stat.zero_fill_count++; 424 m->fake = FALSE; 425 m->absent = FALSE; 426 break; 427 } 428 else { 429 vm_object_lock(next_object); 430 if (object != first_object) 431 object->paging_in_progress--; 432 vm_object_unlock(object); 433 object = next_object; 434 object->paging_in_progress++; 435 } 436 } 437 438 if (m->absent || m->active || m->inactive || !m->busy) 439 panic("vm_fault: absent or active or inactive or not busy after main loop"); 440 441 /* 442 * PAGE HAS BEEN FOUND. 443 * [Loop invariant still holds -- the object lock 444 * is held.] 445 */ 446 447 old_m = m; /* save page that would be copied */ 448 449 /* 450 * If the page is being written, but isn't 451 * already owned by the top-level object, 452 * we have to copy it into a new page owned 453 * by the top-level object. 454 */ 455 456 if (object != first_object) { 457 /* 458 * We only really need to copy if we 459 * want to write it. 460 */ 461 462 if (fault_type & VM_PROT_WRITE) { 463 464 /* 465 * If we try to collapse first_object at this 466 * point, we may deadlock when we try to get 467 * the lock on an intermediate object (since we 468 * have the bottom object locked). We can't 469 * unlock the bottom object, because the page 470 * we found may move (by collapse) if we do. 471 * 472 * Instead, we first copy the page. Then, when 473 * we have no more use for the bottom object, 474 * we unlock it and try to collapse. 475 * 476 * Note that we copy the page even if we didn't 477 * need to... that's the breaks. 478 */ 479 480 /* 481 * We already have an empty page in 482 * first_object - use it. 483 */ 484 485 vm_page_copy(m, first_m); 486 first_m->fake = FALSE; 487 first_m->absent = FALSE; 488 489 /* 490 * If another map is truly sharing this 491 * page with us, we have to flush all 492 * uses of the original page, since we 493 * can't distinguish those which want the 494 * original from those which need the 495 * new copy. 496 */ 497 498 vm_page_lock_queues(); 499 if (!su) { 500 /* 501 * Also, once it's no longer in 502 * use by any maps, move it to 503 * the inactive queue instead. 504 */ 505 506 vm_page_deactivate(m); 507 pmap_remove_all(VM_PAGE_TO_PHYS(m)); 508 } 509 else { 510 /* 511 * Old page is only (possibly) 512 * in use by faulting map. We 513 * should do a pmap_remove on 514 * that mapping, but we know 515 * that pmap_enter will remove 516 * the old mapping before 517 * inserting the new one. 518 */ 519 vm_page_activate(m); 520 } 521 vm_page_unlock_queues(); 522 523 /* 524 * We no longer need the old page or object. 525 */ 526 PAGE_WAKEUP(m); 527 object->paging_in_progress--; 528 vm_object_unlock(object); 529 530 /* 531 * Only use the new page below... 532 */ 533 534 vm_stat.cow_faults++; 535 m = first_m; 536 object = first_object; 537 offset = first_offset; 538 539 /* 540 * Now that we've gotten the copy out of the 541 * way, let's try to collapse the top object. 542 */ 543 vm_object_lock(object); 544 /* 545 * But we have to play ugly games with 546 * paging_in_progress to do that... 547 */ 548 object->paging_in_progress--; 549 vm_object_collapse(object); 550 object->paging_in_progress++; 551 } 552 else { 553 prot &= (~VM_PROT_WRITE); 554 m->copy_on_write = TRUE; 555 } 556 } 557 558 if (m->active || m->inactive) 559 panic("vm_fault: active or inactive before copy object handling"); 560 561 /* 562 * If the page is being written, but hasn't been 563 * copied to the copy-object, we have to copy it there. 564 */ 565 RetryCopy: 566 if (first_object->copy != VM_OBJECT_NULL) { 567 vm_object_t copy_object = first_object->copy; 568 vm_offset_t copy_offset; 569 vm_page_t copy_m; 570 571 /* 572 * We only need to copy if we want to write it. 573 */ 574 if ((fault_type & VM_PROT_WRITE) == 0) { 575 prot &= ~VM_PROT_WRITE; 576 m->copy_on_write = TRUE; 577 } 578 else { 579 /* 580 * Try to get the lock on the copy_object. 581 */ 582 if (!vm_object_lock_try(copy_object)) { 583 vm_object_unlock(object); 584 /* should spin a bit here... */ 585 vm_object_lock(object); 586 goto RetryCopy; 587 } 588 589 /* 590 * Make another reference to the copy-object, 591 * to keep it from disappearing during the 592 * copy. 593 */ 594 copy_object->ref_count++; 595 596 /* 597 * Does the page exist in the copy? 598 */ 599 copy_offset = first_offset 600 - copy_object->shadow_offset; 601 copy_m = vm_page_lookup(copy_object, copy_offset); 602 if (page_exists = (copy_m != VM_PAGE_NULL)) { 603 if (copy_m->busy) { 604 #ifdef DOTHREADS 605 int wait_result; 606 607 /* 608 * If the page is being brought 609 * in, wait for it and then retry. 610 */ 611 PAGE_ASSERT_WAIT(copy_m, !change_wiring); 612 RELEASE_PAGE(m); 613 copy_object->ref_count--; 614 vm_object_unlock(copy_object); 615 UNLOCK_THINGS; 616 thread_block(); 617 wait_result = current_thread()->wait_result; 618 vm_object_deallocate(first_object); 619 if (wait_result != THREAD_AWAKENED) 620 return(KERN_SUCCESS); 621 goto RetryFault; 622 #else 623 /* 624 * If the page is being brought 625 * in, wait for it and then retry. 626 */ 627 PAGE_ASSERT_WAIT(copy_m, !change_wiring); 628 RELEASE_PAGE(m); 629 copy_object->ref_count--; 630 vm_object_unlock(copy_object); 631 UNLOCK_THINGS; 632 thread_block(); 633 vm_object_deallocate(first_object); 634 goto RetryFault; 635 #endif 636 } 637 } 638 639 /* 640 * If the page is not in memory (in the object) 641 * and the object has a pager, we have to check 642 * if the pager has the data in secondary 643 * storage. 644 */ 645 if (!page_exists) { 646 647 /* 648 * If we don't allocate a (blank) page 649 * here... another thread could try 650 * to page it in, allocate a page, and 651 * then block on the busy page in its 652 * shadow (first_object). Then we'd 653 * trip over the busy page after we 654 * found that the copy_object's pager 655 * doesn't have the page... 656 */ 657 copy_m = vm_page_alloc(copy_object, 658 copy_offset); 659 if (copy_m == VM_PAGE_NULL) { 660 /* 661 * Wait for a page, then retry. 662 */ 663 RELEASE_PAGE(m); 664 copy_object->ref_count--; 665 vm_object_unlock(copy_object); 666 UNLOCK_AND_DEALLOCATE; 667 VM_WAIT; 668 goto RetryFault; 669 } 670 671 if (copy_object->pager != vm_pager_null) { 672 vm_object_unlock(object); 673 vm_object_unlock(copy_object); 674 UNLOCK_MAP; 675 676 page_exists = vm_pager_has_page( 677 copy_object->pager, 678 (copy_offset + copy_object->paging_offset)); 679 680 vm_object_lock(copy_object); 681 682 /* 683 * Since the map is unlocked, someone 684 * else could have copied this object 685 * and put a different copy_object 686 * between the two. Or, the last 687 * reference to the copy-object (other 688 * than the one we have) may have 689 * disappeared - if that has happened, 690 * we don't need to make the copy. 691 */ 692 if (copy_object->shadow != object || 693 copy_object->ref_count == 1) { 694 /* 695 * Gaah... start over! 696 */ 697 FREE_PAGE(copy_m); 698 vm_object_unlock(copy_object); 699 vm_object_deallocate(copy_object); 700 /* may block */ 701 vm_object_lock(object); 702 goto RetryCopy; 703 } 704 vm_object_lock(object); 705 706 if (page_exists) { 707 /* 708 * We didn't need the page 709 */ 710 FREE_PAGE(copy_m); 711 } 712 } 713 } 714 if (!page_exists) { 715 /* 716 * Must copy page into copy-object. 717 */ 718 vm_page_copy(m, copy_m); 719 copy_m->fake = FALSE; 720 copy_m->absent = FALSE; 721 722 /* 723 * Things to remember: 724 * 1. The copied page must be marked 'dirty' 725 * so it will be paged out to the copy 726 * object. 727 * 2. If the old page was in use by any users 728 * of the copy-object, it must be removed 729 * from all pmaps. (We can't know which 730 * pmaps use it.) 731 */ 732 vm_page_lock_queues(); 733 pmap_remove_all(VM_PAGE_TO_PHYS(old_m)); 734 copy_m->clean = FALSE; 735 vm_page_activate(copy_m); /* XXX */ 736 vm_page_unlock_queues(); 737 738 PAGE_WAKEUP(copy_m); 739 } 740 /* 741 * The reference count on copy_object must be 742 * at least 2: one for our extra reference, 743 * and at least one from the outside world 744 * (we checked that when we last locked 745 * copy_object). 746 */ 747 copy_object->ref_count--; 748 vm_object_unlock(copy_object); 749 m->copy_on_write = FALSE; 750 } 751 } 752 753 if (m->active || m->inactive) 754 panic("vm_fault: active or inactive before retrying lookup"); 755 756 /* 757 * We must verify that the maps have not changed 758 * since our last lookup. 759 */ 760 761 if (!lookup_still_valid) { 762 vm_object_t retry_object; 763 vm_offset_t retry_offset; 764 vm_prot_t retry_prot; 765 766 /* 767 * Since map entries may be pageable, make sure we can 768 * take a page fault on them. 769 */ 770 vm_object_unlock(object); 771 772 /* 773 * To avoid trying to write_lock the map while another 774 * thread has it read_locked (in vm_map_pageable), we 775 * do not try for write permission. If the page is 776 * still writable, we will get write permission. If it 777 * is not, or has been marked needs_copy, we enter the 778 * mapping without write permission, and will merely 779 * take another fault. 780 */ 781 result = vm_map_lookup(&map, vaddr, 782 fault_type & ~VM_PROT_WRITE, &entry, 783 &retry_object, &retry_offset, &retry_prot, 784 &wired, &su); 785 786 vm_object_lock(object); 787 788 /* 789 * If we don't need the page any longer, put it on the 790 * active list (the easiest thing to do here). If no 791 * one needs it, pageout will grab it eventually. 792 */ 793 794 if (result != KERN_SUCCESS) { 795 RELEASE_PAGE(m); 796 UNLOCK_AND_DEALLOCATE; 797 return(result); 798 } 799 800 lookup_still_valid = TRUE; 801 802 if ((retry_object != first_object) || 803 (retry_offset != first_offset)) { 804 RELEASE_PAGE(m); 805 UNLOCK_AND_DEALLOCATE; 806 goto RetryFault; 807 } 808 809 /* 810 * Check whether the protection has changed or the object 811 * has been copied while we left the map unlocked. 812 * Changing from read to write permission is OK - we leave 813 * the page write-protected, and catch the write fault. 814 * Changing from write to read permission means that we 815 * can't mark the page write-enabled after all. 816 */ 817 prot &= retry_prot; 818 if (m->copy_on_write) 819 prot &= ~VM_PROT_WRITE; 820 } 821 822 /* 823 * (the various bits we're fiddling with here are locked by 824 * the object's lock) 825 */ 826 827 /* XXX This distorts the meaning of the copy_on_write bit */ 828 829 if (prot & VM_PROT_WRITE) 830 m->copy_on_write = FALSE; 831 832 /* 833 * It's critically important that a wired-down page be faulted 834 * only once in each map for which it is wired. 835 */ 836 837 if (m->active || m->inactive) 838 panic("vm_fault: active or inactive before pmap_enter"); 839 840 vm_object_unlock(object); 841 842 /* 843 * Put this page into the physical map. 844 * We had to do the unlock above because pmap_enter 845 * may cause other faults. We don't put the 846 * page back on the active queue until later so 847 * that the page-out daemon won't find us (yet). 848 */ 849 850 pmap_enter(map->pmap, vaddr, VM_PAGE_TO_PHYS(m), 851 prot & ~(m->page_lock), wired); 852 853 /* 854 * If the page is not wired down, then put it where the 855 * pageout daemon can find it. 856 */ 857 vm_object_lock(object); 858 vm_page_lock_queues(); 859 if (change_wiring) { 860 if (wired) 861 vm_page_wire(m); 862 else 863 vm_page_unwire(m); 864 } 865 else 866 vm_page_activate(m); 867 vm_page_unlock_queues(); 868 869 /* 870 * Unlock everything, and return 871 */ 872 873 PAGE_WAKEUP(m); 874 UNLOCK_AND_DEALLOCATE; 875 876 return(KERN_SUCCESS); 877 878 } 879 880 /* 881 * vm_fault_wire: 882 * 883 * Wire down a range of virtual addresses in a map. 884 */ 885 void vm_fault_wire(map, start, end) 886 vm_map_t map; 887 vm_offset_t start, end; 888 { 889 890 register vm_offset_t va; 891 register pmap_t pmap; 892 893 pmap = vm_map_pmap(map); 894 895 /* 896 * Inform the physical mapping system that the 897 * range of addresses may not fault, so that 898 * page tables and such can be locked down as well. 899 */ 900 901 pmap_pageable(pmap, start, end, FALSE); 902 903 /* 904 * We simulate a fault to get the page and enter it 905 * in the physical map. 906 */ 907 908 for (va = start; va < end; va += PAGE_SIZE) { 909 (void) vm_fault(map, va, VM_PROT_NONE, TRUE); 910 } 911 } 912 913 914 /* 915 * vm_fault_unwire: 916 * 917 * Unwire a range of virtual addresses in a map. 918 */ 919 void vm_fault_unwire(map, start, end) 920 vm_map_t map; 921 vm_offset_t start, end; 922 { 923 924 register vm_offset_t va, pa; 925 register pmap_t pmap; 926 927 pmap = vm_map_pmap(map); 928 929 /* 930 * Since the pages are wired down, we must be able to 931 * get their mappings from the physical map system. 932 */ 933 934 vm_page_lock_queues(); 935 936 for (va = start; va < end; va += PAGE_SIZE) { 937 pa = pmap_extract(pmap, va); 938 if (pa == (vm_offset_t) 0) { 939 panic("unwire: page not in pmap"); 940 } 941 pmap_change_wiring(pmap, va, FALSE); 942 vm_page_unwire(PHYS_TO_VM_PAGE(pa)); 943 } 944 vm_page_unlock_queues(); 945 946 /* 947 * Inform the physical mapping system that the range 948 * of addresses may fault, so that page tables and 949 * such may be unwired themselves. 950 */ 951 952 pmap_pageable(pmap, start, end, TRUE); 953 954 } 955 956 /* 957 * Routine: 958 * vm_fault_copy_entry 959 * Function: 960 * Copy all of the pages from a wired-down map entry to another. 961 * 962 * In/out conditions: 963 * The source and destination maps must be locked for write. 964 * The source map entry must be wired down (or be a sharing map 965 * entry corresponding to a main map entry that is wired down). 966 */ 967 968 void vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry) 969 vm_map_t dst_map; 970 vm_map_t src_map; 971 vm_map_entry_t dst_entry; 972 vm_map_entry_t src_entry; 973 { 974 975 vm_object_t dst_object; 976 vm_object_t src_object; 977 vm_offset_t dst_offset; 978 vm_offset_t src_offset; 979 vm_prot_t prot; 980 vm_offset_t vaddr; 981 vm_page_t dst_m; 982 vm_page_t src_m; 983 984 #ifdef lint 985 src_map++; 986 #endif lint 987 988 src_object = src_entry->object.vm_object; 989 src_offset = src_entry->offset; 990 991 /* 992 * Create the top-level object for the destination entry. 993 * (Doesn't actually shadow anything - we copy the pages 994 * directly.) 995 */ 996 dst_object = vm_object_allocate( 997 (vm_size_t) (dst_entry->end - dst_entry->start)); 998 999 dst_entry->object.vm_object = dst_object; 1000 dst_entry->offset = 0; 1001 1002 prot = dst_entry->max_protection; 1003 1004 /* 1005 * Loop through all of the pages in the entry's range, copying 1006 * each one from the source object (it should be there) to the 1007 * destination object. 1008 */ 1009 for (vaddr = dst_entry->start, dst_offset = 0; 1010 vaddr < dst_entry->end; 1011 vaddr += PAGE_SIZE, dst_offset += PAGE_SIZE) { 1012 1013 /* 1014 * Allocate a page in the destination object 1015 */ 1016 vm_object_lock(dst_object); 1017 do { 1018 dst_m = vm_page_alloc(dst_object, dst_offset); 1019 if (dst_m == VM_PAGE_NULL) { 1020 vm_object_unlock(dst_object); 1021 VM_WAIT; 1022 vm_object_lock(dst_object); 1023 } 1024 } while (dst_m == VM_PAGE_NULL); 1025 1026 /* 1027 * Find the page in the source object, and copy it in. 1028 * (Because the source is wired down, the page will be 1029 * in memory.) 1030 */ 1031 vm_object_lock(src_object); 1032 src_m = vm_page_lookup(src_object, dst_offset + src_offset); 1033 if (src_m == VM_PAGE_NULL) 1034 panic("vm_fault_copy_wired: page missing"); 1035 1036 vm_page_copy(src_m, dst_m); 1037 1038 /* 1039 * Enter it in the pmap... 1040 */ 1041 vm_object_unlock(src_object); 1042 vm_object_unlock(dst_object); 1043 1044 pmap_enter(dst_map->pmap, vaddr, VM_PAGE_TO_PHYS(dst_m), 1045 prot, FALSE); 1046 1047 /* 1048 * Mark it no longer busy, and put it on the active list. 1049 */ 1050 vm_object_lock(dst_object); 1051 vm_page_lock_queues(); 1052 vm_page_activate(dst_m); 1053 vm_page_unlock_queues(); 1054 PAGE_WAKEUP(dst_m); 1055 vm_object_unlock(dst_object); 1056 } 1057 1058 } 1059