summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2020-06-30 20:35:53 +0000
committerkettenis <kettenis@openbsd.org>2020-06-30 20:35:53 +0000
commitbdd8fc67eea437f1e652a2e808b91c5dbe8c2832 (patch)
tree035a5f4da2206c0102e876afface6f8e74d8f46e
parentNo need to do anything FPU-related when we exit. (diff)
downloadwireguard-openbsd-bdd8fc67eea437f1e652a2e808b91c5dbe8c2832.tar.xz
wireguard-openbsd-bdd8fc67eea437f1e652a2e808b91c5dbe8c2832.zip
When we sleep during one of the copyin(9) functions, another process may
come in and steal the SLB entry that we use to temporarily map userland adresses in the kernel. Handle this case by reinserting the entry when we get a data segment interrupt.
-rw-r--r--sys/arch/powerpc64/powerpc64/pmap.c14
-rw-r--r--sys/arch/powerpc64/powerpc64/trap.c13
2 files changed, 25 insertions, 2 deletions
diff --git a/sys/arch/powerpc64/powerpc64/pmap.c b/sys/arch/powerpc64/powerpc64/pmap.c
index 6022affba6b..e085c182863 100644
--- a/sys/arch/powerpc64/powerpc64/pmap.c
+++ b/sys/arch/powerpc64/powerpc64/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.20 2020/06/27 21:22:30 kettenis Exp $ */
+/* $OpenBSD: pmap.c,v 1.21 2020/06/30 20:35:53 kettenis Exp $ */
/*
* Copyright (c) 2015 Martin Pieuchot
@@ -371,6 +371,18 @@ pmap_set_user_slb(pmap_t pm, vaddr_t va)
if (slbd == NULL)
return EFAULT;
}
+ KASSERT(slbd->slbd_esid != 0);
+
+ /*
+ * We might get here while another process is sleeping while
+ * handling a page fault. Kill their SLB entry before
+ * inserting our own.
+ */
+ if (ci->ci_kernel_slb[31].slb_slbe != 0) {
+ isync();
+ slbie(ci->ci_kernel_slb[31].slb_slbe);
+ isync();
+ }
slbe = (slbd->slbd_esid << SLBE_ESID_SHIFT) | SLBE_VALID | 31;
slbv = slbd->slbd_vsid << SLBV_VSID_SHIFT;
diff --git a/sys/arch/powerpc64/powerpc64/trap.c b/sys/arch/powerpc64/powerpc64/trap.c
index 8a33f71b8ec..f05af0e3917 100644
--- a/sys/arch/powerpc64/powerpc64/trap.c
+++ b/sys/arch/powerpc64/powerpc64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.18 2020/06/29 13:19:22 kettenis Exp $ */
+/* $OpenBSD: trap.c,v 1.19 2020/06/30 20:35:53 kettenis Exp $ */
/*
* Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
@@ -116,6 +116,17 @@ trap(struct trapframe *frame)
goto fatal;
case EXC_DSE:
+ /*
+ * If we sleep while handling a fault, we may lose our
+ * SLB entry. Enter it again.
+ */
+ va = frame->dar;
+ if (curpcb->pcb_onfault && va < VM_MAXUSER_ADDRESS) {
+ map = &p->p_vmspace->vm_map;
+ if (pmap_set_user_slb(map->pmap, va) == 0)
+ return;
+ }
+
if (curpcb->pcb_onfault) {
frame->srr0 = curpcb->pcb_onfault;
return;