diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 4590be501d64..8e9b115ef224 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -107,6 +107,7 @@ void trap_check(struct trapframe *frame); void dblfault_handler(struct trapframe *frame); static int trap_pfault(struct trapframe *, bool, int *, int *); +static void trap_diag(struct trapframe *, vm_offset_t); static void trap_fatal(struct trapframe *, vm_offset_t); #ifdef KDTRACE_HOOKS static bool trap_user_dtrace(struct trapframe *, @@ -150,6 +151,13 @@ static const char *const trap_msg[] = { [T_DTRACE_RET] = "DTrace pid return trap", }; +static const char * +traptype_to_msg(u_int type) +{ + return (type < nitems(trap_msg) ? trap_msg[type] : + "unknown/reserved trap"); +} + static int uprintf_signal; SYSCTL_INT(_machdep, OID_AUTO, uprintf_signal, CTLFLAG_RWTUN, &uprintf_signal, 0, @@ -415,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); @@ -578,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". @@ -849,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); } @@ -857,15 +871,12 @@ after_vmfault: } static void -trap_fatal(struct trapframe *frame, vm_offset_t eva) +trap_diag(struct trapframe *frame, vm_offset_t eva) { int code, ss; u_int type; struct soft_segment_descriptor softseg; struct user_segment_descriptor *gdt; -#ifdef KDB - bool handled; -#endif code = frame->tf_err; type = frame->tf_trapno; @@ -925,8 +936,20 @@ trap_fatal(struct trapframe *frame, vm_offset_t eva) printf("r13: %016lx r14: %016lx r15: %016lx\n", frame->tf_r13, frame->tf_r14, frame->tf_r15); + printf("trap number = %d\n", type); +} + +static void +trap_fatal(struct trapframe *frame, vm_offset_t eva) +{ + u_int type; + + type = frame->tf_trapno; + trap_diag(frame, eva); #ifdef KDB if (debugger_on_trap) { + bool handled; + kdb_why = KDB_WHY_TRAP; handled = kdb_trap(type, 0, frame); kdb_why = KDB_WHY_UNSET; @@ -934,9 +957,7 @@ trap_fatal(struct trapframe *frame, vm_offset_t eva) return; } #endif - printf("trap number = %d\n", type); - panic("%s", type < nitems(trap_msg) ? trap_msg[type] : - "unknown/reserved trap"); + panic("%s", traptype_to_msg(type)); } #ifdef KDTRACE_HOOKS diff --git a/sys/dev/efidev/efirt.c b/sys/dev/efidev/efirt.c index 8cada0d5061b..fcbed48af395 100644 --- a/sys/dev/efidev/efirt.c +++ b/sys/dev/efidev/efirt.c @@ -490,31 +490,32 @@ efi_rt_arch_call_nofault(struct efirt_callinfo *ec) switch (ec->ec_argcnt) { case 0: - ec->ec_efi_status = ((register_t (*)(void))ec->ec_fptr)(); + ec->ec_efi_status = ((register_t EFIABI_ATTR (*)(void)) + ec->ec_fptr)(); break; case 1: - ec->ec_efi_status = ((register_t (*)(register_t))ec->ec_fptr) - (ec->ec_arg1); + ec->ec_efi_status = ((register_t EFIABI_ATTR (*)(register_t)) + ec->ec_fptr)(ec->ec_arg1); break; case 2: - ec->ec_efi_status = ((register_t (*)(register_t, register_t)) - ec->ec_fptr)(ec->ec_arg1, ec->ec_arg2); + ec->ec_efi_status = ((register_t EFIABI_ATTR (*)(register_t, + register_t))ec->ec_fptr)(ec->ec_arg1, ec->ec_arg2); break; case 3: - ec->ec_efi_status = ((register_t (*)(register_t, register_t, - register_t))ec->ec_fptr)(ec->ec_arg1, ec->ec_arg2, - ec->ec_arg3); + ec->ec_efi_status = ((register_t EFIABI_ATTR (*)(register_t, + register_t, register_t))ec->ec_fptr)(ec->ec_arg1, + ec->ec_arg2, ec->ec_arg3); break; case 4: - ec->ec_efi_status = ((register_t (*)(register_t, register_t, - register_t, register_t))ec->ec_fptr)(ec->ec_arg1, - ec->ec_arg2, ec->ec_arg3, ec->ec_arg4); + ec->ec_efi_status = ((register_t EFIABI_ATTR (*)(register_t, + register_t, register_t, register_t))ec->ec_fptr)( + ec->ec_arg1, ec->ec_arg2, ec->ec_arg3, ec->ec_arg4); break; case 5: - ec->ec_efi_status = ((register_t (*)(register_t, register_t, - register_t, register_t, register_t))ec->ec_fptr)( - ec->ec_arg1, ec->ec_arg2, ec->ec_arg3, ec->ec_arg4, - ec->ec_arg5); + ec->ec_efi_status = ((register_t EFIABI_ATTR (*)(register_t, + register_t, register_t, register_t, register_t)) + ec->ec_fptr)(ec->ec_arg1, ec->ec_arg2, ec->ec_arg3, + ec->ec_arg4, ec->ec_arg5); break; default: panic("efi_rt_arch_call: %d args", (int)ec->ec_argcnt);