| 414 | } |
| 415 | |
| 416 | static int |
| 417 | vm_fault_populate(struct faultstate *fs) |
| 418 | { |
| 419 | vm_offset_t vaddr; |
| 420 | vm_page_t m; |
| 421 | vm_pindex_t map_first, map_last, pager_first, pager_last, pidx; |
| 422 | int bdry_idx, i, npages, psind, rv; |
| 423 | |
| 424 | MPASS(fs->object == fs->first_object); |
| 425 | VM_OBJECT_ASSERT_WLOCKED(fs->first_object); |
| 426 | MPASS(blockcount_read(&fs->first_object->paging_in_progress) > 0); |
| 427 | MPASS(fs->first_object->backing_object == NULL); |
| 428 | MPASS(fs->lookup_still_valid); |
| 429 | |
| 430 | pager_first = OFF_TO_IDX(fs->entry->offset); |
| 431 | pager_last = pager_first + atop(fs->entry->end - fs->entry->start) - 1; |
| 432 | unlock_map(fs); |
| 433 | unlock_vp(fs); |
| 434 | |
| 435 | /* |
| 436 | * Call the pager (driver) populate() method. |
| 437 | * |
| 438 | * There is no guarantee that the method will be called again |
| 439 | * if the current fault is for read, and a future fault is |
| 440 | * for write. Report the entry's maximum allowed protection |
| 441 | * to the driver. |
| 442 | */ |
| 443 | rv = vm_pager_populate(fs->first_object, fs->first_pindex, |
| 444 | fs->fault_type, fs->entry->max_protection, &pager_first, |
| 445 | &pager_last); |
| 446 | |
| 447 | VM_OBJECT_ASSERT_WLOCKED(fs->first_object); |
| 448 | if (rv == VM_PAGER_BAD) { |
| 449 | /* |
| 450 | * VM_PAGER_BAD is the backdoor for a pager to request |
| 451 | * normal fault handling. |
| 452 | */ |
| 453 | vm_fault_restore_map_lock(fs); |
| 454 | if (fs->map->timestamp != fs->map_generation) |
| 455 | return (KERN_RESTART); |
| 456 | return (KERN_NOT_RECEIVER); |
| 457 | } |
| 458 | if (rv != VM_PAGER_OK) |
| 459 | return (KERN_FAILURE); /* AKA SIGSEGV */ |
| 460 | |
| 461 | /* Ensure that the driver is obeying the interface. */ |
| 462 | MPASS(pager_first <= pager_last); |
| 463 | MPASS(fs->first_pindex <= pager_last); |
| 464 | MPASS(fs->first_pindex >= pager_first); |
| 465 | MPASS(pager_last < fs->first_object->size); |
| 466 | |
| 467 | vm_fault_restore_map_lock(fs); |
| 468 | bdry_idx = (fs->entry->eflags & MAP_ENTRY_SPLIT_BOUNDARY_MASK) >> |
| 469 | MAP_ENTRY_SPLIT_BOUNDARY_SHIFT; |
| 470 | if (fs->map->timestamp != fs->map_generation) { |
| 471 | if (bdry_idx == 0) { |
| 472 | vm_fault_populate_cleanup(fs->first_object, pager_first, |
| 473 | pager_last); |
no test coverage detected