git: dd2b54436445 - main - amd64: on any fault during call to EFI RT, restore execution and print fault details

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 25 Dec 2024 01:37:26 UTC
The branch main has been updated by kib:

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

commit dd2b5443644505af51c95503898ab363e7d7c29d
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-12-24 02:35:16 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-12-25 01:37:19 +0000

    amd64: on any fault during call to EFI RT, restore execution and print fault details
    
    The fault info should be useful to see what specifically BIOS tried to
    do and why it faulted.  E.g. it might allow to see which EFI memory
    segment needs to be mapped in addition to normal runtime segments, to
    work around the fault.
    
    Reviewed by:    kevans, markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D48186
---
 sys/amd64/amd64/trap.c | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 3b23a34662d5..8e9b115ef224 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -423,6 +423,20 @@ trap(struct trapframe *frame)
 
 		KASSERT(cold || td->td_ucred != NULL,
 		    ("kernel trap doesn't have ucred"));
+
+		/*
+		 * 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 && type != T_PAGEFLT) {
+			trap_diag(frame, 0);
+			printf("EFI RT fault %s\n", traptype_to_msg(type));
+			frame->tf_rip = (long)curpcb->pcb_onfault;
+			return;
+		}
+
 		switch (type) {
 		case T_PAGEFLT:			/* page fault */
 			(void)trap_pfault(frame, false, NULL, NULL);
@@ -586,18 +600,6 @@ trap(struct trapframe *frame)
 			 * FALLTHROUGH (TRCTRAP kernel mode, kernel address)
 			 */
 		case T_BPTFLT:
-			/*
-			 * Most likely, EFI RT hitting INT3.  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) {
-				frame->tf_rip = (long)curpcb->pcb_onfault;
-				return;
-			}
-
 			/*
 			 * If KDB is enabled, let it handle the debugger trap.
 			 * Otherwise, debugger traps "can't happen".
@@ -857,6 +859,10 @@ trap_pfault(struct trapframe *frame, bool usermode, int *signo, int *ucode)
 after_vmfault:
 	if (td->td_intr_nesting_level == 0 &&
 	    curpcb->pcb_onfault != NULL) {
+		if ((td->td_pflags & TDP_EFIRT) != 0) {
+			trap_diag(frame, eva);
+			printf("EFI RT page fault\n");
+		}
 		frame->tf_rip = (long)curpcb->pcb_onfault;
 		return (0);
 	}