Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_fault.c
| Show First 20 Lines • Show All 702 Lines • ▼ Show 20 Lines | ||||||||||
| /* compat definition to keep common code for signal translation */ | /* compat definition to keep common code for signal translation */ | |||||||||
| #define UCODE_PAGEFLT 12 | #define UCODE_PAGEFLT 12 | |||||||||
| #ifdef T_PAGEFLT | #ifdef T_PAGEFLT | |||||||||
| _Static_assert(UCODE_PAGEFLT == T_PAGEFLT, "T_PAGEFLT"); | _Static_assert(UCODE_PAGEFLT == T_PAGEFLT, "T_PAGEFLT"); | |||||||||
| #endif | #endif | |||||||||
| /* | /* | |||||||||
| * vm_fault_trap: | * vm_fault_trap: | |||||||||
| * | * | |||||||||
| * Handle a page fault occurring at the given address, | * Helper for the page fault trap handlers, wrapping vm_fault(). | |||||||||
alcUnsubmitted Done Inline Actions
alc: | ||||||||||
| * requiring the given permissions, in the map specified. | * Issues ktrace(2) tracepoints for the faults. | |||||||||
Done Inline Actions
markj: | ||||||||||
| * If successful, the page is inserted into the | ||||||||||
| * associated physical map. | ||||||||||
| * | * | |||||||||
| * NOTE: the given address should be truncated to the | * If a fault cannot be handled successfully by satisfying the | |||||||||
alcUnsubmitted Done Inline Actions
alc: | ||||||||||
| * proper page address. | * required mapping, and the faulted instruction cannot be restarted, | |||||||||
| * the signal number and si_code values are returned for trapsignal() | ||||||||||
| * to deliver. | ||||||||||
Done Inline Actions
or "a fault" markj: or "a fault" | ||||||||||
| * | * | |||||||||
| * KERN_SUCCESS is returned if the page fault is handled; otherwise, | * Returns Mach error codes, but callers should only check for | |||||||||
| * a standard error specifying why the fault is fatal is returned. | * KERN_SUCCESS. | |||||||||
| * | ||||||||||
| * The map in question must be referenced, and remains so. | ||||||||||
| * Caller may hold no locks. | ||||||||||
| */ | */ | |||||||||
| int | int | |||||||||
| vm_fault_trap(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type, | vm_fault_trap(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type, | |||||||||
| int fault_flags, int *signo, int *ucode) | int fault_flags, int *signo, int *ucode) | |||||||||
| { | { | |||||||||
| int result; | int result; | |||||||||
| MPASS(signo == NULL || ucode != NULL); | MPASS(signo == NULL || ucode != NULL); | |||||||||
| ▲ Show 20 Lines • Show All 887 Lines • ▼ Show 20 Lines | if (vm_fault_object_needs_getpages(fs->object)) { | |||||||||
| if (res == FAULT_CONTINUE) | if (res == FAULT_CONTINUE) | |||||||||
| VM_OBJECT_WLOCK(fs->object); | VM_OBJECT_WLOCK(fs->object); | |||||||||
| } else { | } else { | |||||||||
| res = FAULT_CONTINUE; | res = FAULT_CONTINUE; | |||||||||
| } | } | |||||||||
| return (res); | return (res); | |||||||||
| } | } | |||||||||
| /* | ||||||||||
| * vm_fault: | ||||||||||
| * | ||||||||||
| * Handle a page fault occurring at the given address, requiring the | ||||||||||
| * given permissions, in the map specified. If successful, the page | ||||||||||
| * is inserted into the associated physical map, and optionally | ||||||||||
| * referenced and returned in *m_hold. | ||||||||||
| * | ||||||||||
| * The given address should be truncated to the proper page address. | ||||||||||
| * | ||||||||||
| * KERN_SUCCESS is returned if the page fault is handled; otherwise, a | ||||||||||
| * Mach error specifying why the fault is fatal is returned. | ||||||||||
alcUnsubmitted Done Inline Actions
alc: | ||||||||||
| * | ||||||||||
| * The map in question must be alive, either being the map for current | ||||||||||
alcUnsubmitted Done Inline Actions
alc: | ||||||||||
| * process, or the owner process hold count incremented to prevent | ||||||||||
Done Inline ActionsIt's not quite true that the caller may hold no locks, e.g., in the TDP_NOFAULTING case the caller may legitimately hold them. markj: It's not quite true that the caller may hold no locks, e.g., in the TDP_NOFAULTING case the… | ||||||||||
alcUnsubmitted Done Inline Actions
alc: | ||||||||||
| * exit(). | ||||||||||
| * | ||||||||||
Done Inline Actions
markj: | ||||||||||
| * If the thread private TDP_NOFAULTING flag is set, any fault results | ||||||||||
| * in immediate protection failure. Otherwise the fault is processed, | ||||||||||
| * and caller may hold no locks. | ||||||||||
| */ | ||||||||||
| int | int | |||||||||
| vm_fault(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type, | vm_fault(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type, | |||||||||
| int fault_flags, vm_page_t *m_hold) | int fault_flags, vm_page_t *m_hold) | |||||||||
| { | { | |||||||||
| struct pctrie_iter pages; | struct pctrie_iter pages; | |||||||||
| struct faultstate fs; | struct faultstate fs; | |||||||||
| int ahead, behind, faultcount, rv; | int ahead, behind, faultcount, rv; | |||||||||
| enum fault_status res; | enum fault_status res; | |||||||||
| ▲ Show 20 Lines • Show All 820 Lines • Show Last 20 Lines | ||||||||||