summaryrefslogtreecommitdiffstats
path: root/sys/arch/powerpc64/powerpc64/trap.c
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2020-06-22 18:03:22 +0000
committerkettenis <kettenis@openbsd.org>2020-06-22 18:03:22 +0000
commitc0e8dfc26859acc5c80a7cd731a9232aad396d94 (patch)
tree06c987bcee62a3a4b6f3a27a0d74ba032a0b2899 /sys/arch/powerpc64/powerpc64/trap.c
parentMake return-to-user and kernel re-entry work. This adds a per-pmap SLB (diff)
downloadwireguard-openbsd-c0e8dfc26859acc5c80a7cd731a9232aad396d94.tar.xz
wireguard-openbsd-c0e8dfc26859acc5c80a7cd731a9232aad396d94.zip
Handle data storage and data segment interrupts from userland as well.
Diffstat (limited to '')
-rw-r--r--sys/arch/powerpc64/powerpc64/trap.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/sys/arch/powerpc64/powerpc64/trap.c b/sys/arch/powerpc64/powerpc64/trap.c
index 313d9b31066..3807aca55de 100644
--- a/sys/arch/powerpc64/powerpc64/trap.c
+++ b/sys/arch/powerpc64/powerpc64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.11 2020/06/22 16:58:20 kettenis Exp $ */
+/* $OpenBSD: trap.c,v 1.12 2020/06/22 18:03:22 kettenis Exp $ */
/*
* Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
@@ -41,6 +41,8 @@ trap(struct trapframe *frame)
struct proc *p = curproc;
int type = frame->exc;
struct vm_map *map;
+ struct slb_desc *slbd;
+ pmap_t pm;
vaddr_t va;
int ftype;
int error;
@@ -107,12 +109,47 @@ trap(struct trapframe *frame)
printf("dar 0x%lx dsisr 0x%lx\n", frame->dar, frame->dsisr);
goto fatal;
- case EXC_ISI|EXC_USER:
+ case EXC_DSE|EXC_USER:
+ intr_enable();
+ pm = p->p_vmspace->vm_map.pmap;
+ slbd = pmap_slbd_lookup(pm, frame->dar);
+ if (slbd) {
+ pmap_slbd_cache(pm, slbd);
+ break;
+ }
+ /* FALLTHROUGH */
+
+ case EXC_DSI|EXC_USER:
+ intr_enable();
+ map = &p->p_vmspace->vm_map;
+ va = frame->dar;
+ if (frame->dsisr & DSISR_STORE)
+ ftype = PROT_READ | PROT_WRITE;
+ else
+ ftype = PROT_READ;
+ KERNEL_LOCK();
+ error = uvm_fault(map, trunc_page(va), 0, ftype);
+ KERNEL_UNLOCK();
+ if (error)
+ goto fatal;
+ break;
+
case EXC_ISE|EXC_USER:
intr_enable();
+ pm = p->p_vmspace->vm_map.pmap;
+ slbd = pmap_slbd_lookup(pm, frame->srr0);
+ if (slbd) {
+ pmap_slbd_cache(pm, slbd);
+ break;
+ }
+ /* FALLTHROUGH */
+
+ case EXC_ISI|EXC_USER:
+ intr_enable();
map = &p->p_vmspace->vm_map;
va = frame->srr0;
ftype = PROT_READ | PROT_EXEC;
+ KERNEL_LOCK();
error = uvm_fault(map, trunc_page(va), 0, ftype);
KERNEL_UNLOCK();
if (error)