* 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
| 733 | * number, *ucode gives si_code. |
| 734 | */ |
| 735 | static int |
| 736 | trap_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 | } |
no test coverage detected