diff options
author | 2020-06-30 20:35:53 +0000 | |
---|---|---|
committer | 2020-06-30 20:35:53 +0000 | |
commit | bdd8fc67eea437f1e652a2e808b91c5dbe8c2832 (patch) | |
tree | 035a5f4da2206c0102e876afface6f8e74d8f46e | |
parent | No need to do anything FPU-related when we exit. (diff) | |
download | wireguard-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.c | 14 | ||||
-rw-r--r-- | sys/arch/powerpc64/powerpc64/trap.c | 13 |
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; |