MCPcopy Create free account
hub / github.com/F-Stack/f-stack / trap_pfault

Function trap_pfault

freebsd/amd64/amd64/trap.c:679–843  ·  view source on GitHub ↗

* Handle all details of a page fault. * Returns: * -1 if this fault was fatal, typically from kernel mode * (cannot happen, but we need to return something). * 0 if this fault was handled by updating either the user or kernel * page table, execution can continue. * 1 if this fault was from usermode and it was not handled, a synchronous * signal should be delivered to the thread.

Source from the content-addressed store, hash-verified

677 * number, *ucode gives si_code.
678 */
679static int
680trap_pfault(struct trapframe *frame, bool usermode, int *signo, int *ucode)
681{
682 struct thread *td;
683 struct proc *p;
684 vm_map_t map;
685 vm_offset_t eva;
686 int rv;
687 vm_prot_t ftype;
688
689 MPASS(!usermode || (signo != NULL && ucode != NULL));
690
691 td = curthread;
692 p = td->td_proc;
693 eva = frame->tf_addr;
694
695 if (__predict_false((td->td_pflags & TDP_NOFAULTING) != 0)) {
696 /*
697 * Due to both processor errata and lazy TLB invalidation when
698 * access restrictions are removed from virtual pages, memory
699 * accesses that are allowed by the physical mapping layer may
700 * nonetheless cause one spurious page fault per virtual page.
701 * When the thread is executing a "no faulting" section that
702 * is bracketed by vm_fault_{disable,enable}_pagefaults(),
703 * every page fault is treated as a spurious page fault,
704 * unless it accesses the same virtual address as the most
705 * recent page fault within the same "no faulting" section.
706 */
707 if (td->td_md.md_spurflt_addr != eva ||
708 (td->td_pflags & TDP_RESETSPUR) != 0) {
709 /*
710 * Do nothing to the TLB. A stale TLB entry is
711 * flushed automatically by a page fault.
712 */
713 td->td_md.md_spurflt_addr = eva;
714 td->td_pflags &= ~TDP_RESETSPUR;
715 return (0);
716 }
717 } else {
718 /*
719 * If we get a page fault while in a critical section, then
720 * it is most likely a fatal kernel page fault. The kernel
721 * is already going to panic trying to get a sleep lock to
722 * do the VM lookup, so just consider it a fatal trap so the
723 * kernel can print out a useful trap message and even get
724 * to the debugger.
725 *
726 * If we get a page fault while holding a non-sleepable
727 * lock, then it is most likely a fatal kernel page fault.
728 * If WITNESS is enabled, then it's going to whine about
729 * bogus LORs with various VM locks, so just skip to the
730 * fatal trap handling directly.
731 */
732 if (td->td_critnest != 0 ||
733 WITNESS_CHECK(WARN_SLEEPOK | WARN_GIANTOK, NULL,
734 "Kernel page fault") != 0) {
735 trap_fatal(frame, eva);
736 return (-1);

Callers 1

trapFunction · 0.70

Calls 5

trap_is_smapFunction · 0.85
trap_is_ptiFunction · 0.85
vm_fault_trapFunction · 0.85
trap_fatalFunction · 0.70
panicFunction · 0.50

Tested by

no test coverage detected