The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=8365f877b1e4b6d4c30df72e0826ca60a412ce7d

commit 8365f877b1e4b6d4c30df72e0826ca60a412ce7d
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2026-03-14 11:40:07 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2026-03-15 06:57:08 +0000

    amd64: do reset %rip after page fault if pcb_onfault is set
    
    for any kernel page fault, and not only for EFIRT case.
    
    Reported and tested by: pho
    Fixes:  914a53570750ce5a104a5870403d7669656fddc3
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
---
 sys/amd64/amd64/trap.c | 33 ++++++++++++++++++++-------------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 4bf56226d076..3a9323936d2d 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -219,15 +219,19 @@ trap_uprintf_signal(struct thread *td, struct trapframe 
*frame, register_t addr,
 }
 
 static bool
-trap_check_efirt(struct thread *td, struct trapframe *frame)
+trap_check_pcb_onfault(struct thread *td, struct trapframe *frame)
 {
-       /*
-        * Most likely, EFI RT faulted.  This check prevents
-        * kdb from handling breakpoints set on the BIOS text,
-        * if such option is ever needed.
-        */
-       if ((td->td_pflags & TDP_EFIRT) != 0 &&
-           curpcb->pcb_onfault != NULL) {
+       bool res = false;
+
+       if (curpcb->pcb_onfault == NULL)
+               return (res);
+
+       if (__predict_false((td->td_pflags & TDP_EFIRT) != 0)) {
+               /*
+                * Most likely, EFI RT faulted.  This check prevents
+                * kdb from handling breakpoints set on the BIOS text,
+                * if such option is ever needed.
+                */
                u_long cnt = atomic_fetchadd_long(&cnt_efirt_faults, 1);
 
                if ((print_efirt_faults == 1 && cnt == 0) ||
@@ -236,10 +240,13 @@ trap_check_efirt(struct thread *td, struct trapframe 
*frame)
                            traptype_to_msg(frame->tf_trapno));
                        trap_diag(frame, 0);
                }
-               frame->tf_rip = (long)curpcb->pcb_onfault;
-               return (true);
+               res = true;
+       } else if (frame->tf_trapno == T_PAGEFLT) {
+               res = true;
        }
-       return (false);
+       if (res)
+               frame->tf_rip = (register_t)curpcb->pcb_onfault;
+       return (res);
 }
 
 static void
@@ -494,7 +501,7 @@ trap(struct trapframe *frame)
                KASSERT(cold || td->td_ucred != NULL,
                    ("kernel trap doesn't have ucred"));
 
-               if (type != T_PAGEFLT && trap_check_efirt(td, frame))
+               if (type != T_PAGEFLT && trap_check_pcb_onfault(td, frame))
                        return;
 
                switch (type) {
@@ -904,7 +911,7 @@ trap_pfault(struct trapframe *frame, bool usermode, int 
*signo, int *ucode)
                return (1);
 after_vmfault:
        if (td->td_intr_nesting_level == 0 &&
-           trap_check_efirt(td, frame))
+           trap_check_pcb_onfault(td, frame))
                return (0);
        trap_fatal(frame, eva);
        return (-1);

Reply via email to