Skip to content

Commit

Permalink
amd64: on any fault during call to EFI RT, restore execution and prin…
Browse files Browse the repository at this point in the history
…t 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
  • Loading branch information
kostikbel committed Dec 25, 2024
1 parent 5e3ab18 commit dd2b544
Showing 1 changed file with 18 additions and 12 deletions.
30 changes: 18 additions & 12 deletions sys/amd64/amd64/trap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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".
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit dd2b544

Please sign in to comment.