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

Function trap_pfault

freebsd/i386/i386/trap.c:735–875  ·  view source on GitHub ↗

* Handle all details of a page fault. * Returns: * -2 if the fault was caused by triggered workaround for Intel Pentium * 0xf00f bug. * -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 userm

Source from the content-addressed store, hash-verified

733 * number, *ucode gives si_code.
734 */
735static int
736trap_pfault(struct trapframe *frame, bool usermode, vm_offset_t eva,
737 int *signo, int *ucode)
738{
739 struct thread *td;
740 struct proc *p;
741 vm_map_t map;
742 int rv;
743 vm_prot_t ftype;
744
745 MPASS(!usermode || (signo != NULL && ucode != NULL));
746
747 td = curthread;
748 p = td->td_proc;
749
750 if (__predict_false((td->td_pflags & TDP_NOFAULTING) != 0)) {
751 /*
752 * Due to both processor errata and lazy TLB invalidation when
753 * access restrictions are removed from virtual pages, memory
754 * accesses that are allowed by the physical mapping layer may
755 * nonetheless cause one spurious page fault per virtual page.
756 * When the thread is executing a "no faulting" section that
757 * is bracketed by vm_fault_{disable,enable}_pagefaults(),
758 * every page fault is treated as a spurious page fault,
759 * unless it accesses the same virtual address as the most
760 * recent page fault within the same "no faulting" section.
761 */
762 if (td->td_md.md_spurflt_addr != eva ||
763 (td->td_pflags & TDP_RESETSPUR) != 0) {
764 /*
765 * Do nothing to the TLB. A stale TLB entry is
766 * flushed automatically by a page fault.
767 */
768 td->td_md.md_spurflt_addr = eva;
769 td->td_pflags &= ~TDP_RESETSPUR;
770 return (0);
771 }
772 } else {
773 /*
774 * If we get a page fault while in a critical section, then
775 * it is most likely a fatal kernel page fault. The kernel
776 * is already going to panic trying to get a sleep lock to
777 * do the VM lookup, so just consider it a fatal trap so the
778 * kernel can print out a useful trap message and even get
779 * to the debugger.
780 *
781 * If we get a page fault while holding a non-sleepable
782 * lock, then it is most likely a fatal kernel page fault.
783 * If WITNESS is enabled, then it's going to whine about
784 * bogus LORs with various VM locks, so just skip to the
785 * fatal trap handling directly.
786 */
787 if (td->td_critnest != 0 ||
788 WITNESS_CHECK(WARN_SLEEPOK | WARN_GIANTOK, NULL,
789 "Kernel page fault") != 0) {
790 trap_fatal(frame, eva);
791 return (-1);
792 }

Callers 1

trapFunction · 0.70

Calls 2

vm_fault_trapFunction · 0.85
trap_fatalFunction · 0.70

Tested by

no test coverage detected