Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 15 Mar 2026 06:58:01 +0000
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 8365f877b1e4 - main - amd64: do reset %rip after page fault if pcb_onfault is set
Message-ID:  <69b65879.27fa1.4fc60671@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by kib:

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

commit 8365f877b1e4b6d4c30df72e0826ca60a412ce7d
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-03-14 11:40:07 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
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);


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69b65879.27fa1.4fc60671>