diff options
author | kettenis <kettenis@openbsd.org> | 2020-06-22 18:03:22 +0000 |
---|---|---|
committer | kettenis <kettenis@openbsd.org> | 2020-06-22 18:03:22 +0000 |
commit | c0e8dfc26859acc5c80a7cd731a9232aad396d94 (patch) | |
tree | 06c987bcee62a3a4b6f3a27a0d74ba032a0b2899 /sys/arch/powerpc64/powerpc64/trap.c | |
parent | Make return-to-user and kernel re-entry work. This adds a per-pmap SLB (diff) | |
download | wireguard-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.c | 41 |
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) |