summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/arm64/arm64/support.S5
-rw-r--r--sys/arch/arm64/arm64/trap.c14
-rw-r--r--sys/arch/arm64/conf/files.arm644
-rw-r--r--sys/arch/arm64/dev/efi_machdep.c27
4 files changed, 38 insertions, 12 deletions
diff --git a/sys/arch/arm64/arm64/support.S b/sys/arch/arm64/arm64/support.S
index a08d11d64c4..5eebc4dbcad 100644
--- a/sys/arch/arm64/arm64/support.S
+++ b/sys/arch/arm64/arm64/support.S
@@ -1,4 +1,4 @@
-/* $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
@@ -36,8 +36,9 @@
#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 */
diff --git a/sys/arch/arm64/arm64/trap.c b/sys/arch/arm64/arm64/trap.c
index d30e40eb27d..1932e3850d6 100644
--- a/sys/arch/arm64/arm64/trap.c
+++ b/sys/arch/arm64/arm64/trap.c
@@ -1,4 +1,4 @@
-/* $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.
@@ -158,11 +158,14 @@ kdata_abort(struct trapframe *frame, uint64_t esr, uint64_t far, int exe)
* 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 */
@@ -175,7 +178,7 @@ kdata_abort(struct trapframe *frame, uint64_t esr, uint64_t far, int exe)
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;
}
@@ -215,6 +218,9 @@ do_el1h_sync(struct trapframe *frame)
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;
diff --git a/sys/arch/arm64/conf/files.arm64 b/sys/arch/arm64/conf/files.arm64
index 2a7bdba0c21..e8087bcadd9 100644
--- a/sys/arch/arm64/conf/files.arm64
+++ b/sys/arch/arm64/conf/files.arm64
@@ -1,4 +1,4 @@
-# $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
@@ -65,7 +65,7 @@ file arch/arm64/dev/simplebus.c simplebus
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
diff --git a/sys/arch/arm64/dev/efi_machdep.c b/sys/arch/arm64/dev/efi_machdep.c
index 1dd2c4eb71b..3779f9feba1 100644
--- a/sys/arch/arm64/dev/efi_machdep.c
+++ b/sys/arch/arm64/dev/efi_machdep.c
@@ -1,4 +1,4 @@
-/* $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>
@@ -26,6 +26,7 @@
#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>
@@ -75,6 +76,11 @@ void efi_leave(struct efi_softc *);
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)
{
@@ -161,7 +167,8 @@ efi_attach(struct device *parent, struct device *self, 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)
@@ -253,6 +260,12 @@ efi_map_runtime(struct efi_softc *sc)
}
void
+efi_fault(void)
+{
+ longjmp(&efi_jmpbuf);
+}
+
+void
efi_enter(struct efi_softc *sc)
{
struct pmap *pm = sc->sc_pm;
@@ -268,6 +281,8 @@ 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
@@ -276,6 +291,8 @@ efi_leave(struct efi_softc *sc)
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);
@@ -296,7 +313,8 @@ efi_gettime(struct todr_chip_handle *handle, struct timeval *tv)
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)
@@ -340,7 +358,8 @@ efi_settime(struct todr_chip_handle *handle, struct timeval *tv)
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)