-/* $OpenBSD: efi_machdep.c,v 1.2 2022/10/20 18:43:35 kettenis Exp $ */
+/* $OpenBSD: efi_machdep.c,v 1.3 2022/11/04 16:49:31 kettenis Exp $ */
/*
* Copyright (c) 2022 Mark Kettenis <kettenis@openbsd.org>
int efi_gettime(struct todr_chip_handle *, struct timeval *);
int efi_settime(struct todr_chip_handle *, struct timeval *);
+label_t efi_jmpbuf;
+
+#define efi_enter_check(sc) (setjmp(&efi_jmpbuf) ? \
+ (efi_leave(sc), EFAULT) : (efi_enter(sc), 0))
+
int
efi_match(struct device *parent, void *match, void *aux)
{
}
efi_leave(sc);
- efi_enter(sc);
+ if (efi_enter_check(sc))
+ return;
status = sc->sc_rs->GetTime(&time, NULL);
efi_leave(sc);
if (status != EFI_SUCCESS)
}
}
+void
+efi_fault(void)
+{
+ longjmp(&efi_jmpbuf);
+}
+
void
efi_enter(struct efi_softc *sc)
{
lcr3(sc->sc_pm->pm_pdirpa | (pmap_use_pcid ? PCID_EFI : 0));
fpu_kernel_enter();
+
+ curpcb->pcb_onfault = (void *)efi_fault;
}
void
efi_leave(struct efi_softc *sc)
{
+ curpcb->pcb_onfault = NULL;
+
fpu_kernel_exit();
lcr3(sc->sc_cr3);
EFI_TIME time;
EFI_STATUS status;
- efi_enter(sc);
+ if (efi_enter_check(sc))
+ return EFAULT;
status = sc->sc_rs->GetTime(&time, NULL);
efi_leave(sc);
if (status != EFI_SUCCESS)
time.TimeZone = 0;
time.Daylight = 0;
- efi_enter(sc);
+ if (efi_enter_check(sc))
+ return EFAULT;
status = sc->sc_rs->SetTime(&time);
efi_leave(sc);
if (status != EFI_SUCCESS)
-/* $OpenBSD: locore.S,v 1.128 2022/08/07 23:56:06 guenther Exp $ */
+/* $OpenBSD: locore.S,v 1.129 2022/11/04 16:49:31 kettenis Exp $ */
/* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */
/*
*/
#include "assym.h"
+#include "efi.h"
#include "lapic.h"
#include "ksyms.h"
#include "xen.h"
lretq
END(lgdt)
-#ifdef DDB
+#if defined(DDB) || NEFI > 0
ENTRY(setjmp)
RETGUARD_SETUP(setjmp, r11)
/*
ret
lfence
END(longjmp)
-#endif /* DDB */
+#endif /* DDB || NEFI > 0 */
/*****************************************************************************/
-/* $OpenBSD: trap.c,v 1.91 2022/11/02 07:20:07 guenther Exp $ */
+/* $OpenBSD: trap.c,v 1.92 2022/11/04 16:49:31 kettenis Exp $ */
/* $NetBSD: trap.c,v 1.2 2003/05/04 23:51:56 fvdl Exp $ */
/*-
pcb = &p->p_addr->u_pcb;
/* This will only trigger if SMEP is enabled */
- if (cr2 <= VM_MAXUSER_ADDRESS && frame->tf_err & PGEX_I) {
+ if (pcb->pcb_onfault == NULL && cr2 <= VM_MAXUSER_ADDRESS &&
+ frame->tf_err & PGEX_I) {
KERNEL_LOCK();
fault("attempt to execute user address %p "
"in supervisor mode", (void *)cr2);