-/* $OpenBSD: support.S,v 1.9 2019/03/15 05:42:38 kevlo Exp $ */
+/* $OpenBSD: support.S,v 1.10 2022/11/06 11:44:30 kettenis Exp $ */
/*-
* Copyright (c) 2014 Andrew Turner
* Copyright (c) 2014-2015 The FreeBSD Foundation
#include <machine/vmparam.h>
#include "assym.h"
+#include "efi.h"
-#ifdef DDB
+#if defined(DDB) || NEFI > 0
ENTRY(setjmp)
RETGUARD_SETUP(setjmp, x15)
/* Store the stack pointer */
-/* $OpenBSD: trap.c,v 1.40 2022/08/15 13:33:22 jsg Exp $ */
+/* $OpenBSD: trap.c,v 1.41 2022/11/06 11:44:30 kettenis Exp $ */
/*-
* Copyright (c) 2014 Andrew Turner
* All rights reserved.
* Only allow user-space access using
* unprivileged load/store instructions.
*/
- if (!is_unpriv_ldst(frame->tf_elr)) {
+ if (is_unpriv_ldst(frame->tf_elr))
+ map = &p->p_vmspace->vm_map;
+ else if (pcb->pcb_onfault != NULL)
+ map = kernel_map;
+ else {
panic("attempt to access user address"
" 0x%llx from EL1", far);
}
- map = &p->p_vmspace->vm_map;
}
/* Handle referenced/modified emulation */
if (error != 0) {
if (curcpu()->ci_idepth == 0 &&
- pcb->pcb_onfault != 0) {
+ pcb->pcb_onfault != NULL) {
frame->tf_elr = (register_t)pcb->pcb_onfault;
return;
}
case EXCP_FP_SIMD:
case EXCP_TRAP_FP:
panic("FP exception in the kernel");
+ case EXCP_INSN_ABORT:
+ kdata_abort(frame, esr, far, 1);
+ break;
case EXCP_DATA_ABORT:
kdata_abort(frame, esr, far, 0);
break;
-# $OpenBSD: files.arm64,v 1.61 2022/10/03 19:32:22 kettenis Exp $
+# $OpenBSD: files.arm64,v 1.62 2022/11/06 11:44:30 kettenis Exp $
maxpartitions 16
maxusers 2 8 128
device efi {}
attach efi at fdt
-file arch/arm64/dev/efi_machdep.c efi
+file arch/arm64/dev/efi_machdep.c efi needs-flag
device smbios
attach smbios at efi
-/* $OpenBSD: efi_machdep.c,v 1.4 2022/10/29 20:35:50 kettenis Exp $ */
+/* $OpenBSD: efi_machdep.c,v 1.5 2022/11/06 11:44:30 kettenis Exp $ */
/*
* Copyright (c) 2017 Mark Kettenis <kettenis@openbsd.org>
#include <machine/bus.h>
#include <machine/fdt.h>
#include <machine/fpu.h>
+#include <machine/pcb.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/fdt.h>
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)
{
config_found(self, &fa, NULL);
}
- 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)
{
cpu_setttb(pm->pm_asid, pm->pm_pt0pa);
fpu_kernel_enter();
+
+ curcpu()->ci_curpcb->pcb_onfault = (void *)efi_fault;
}
void
struct pmap *pm = curcpu()->ci_curpm;
uint64_t tcr;
+ curcpu()->ci_curpcb->pcb_onfault = NULL;
+
fpu_kernel_exit();
WRITE_SPECIALREG(ttbr0_el1, pmap_kernel()->pm_pt0pa);
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)