summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2020-09-14 12:51:29 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2020-09-14 12:51:29 +0000
commit9b41c91126f2ecc369463aae629bef1a45dac699 (patch)
tree1790838640e8d513e93a056b46203d8ab70b3a34 /sys
parent3498316847c9ce67c52bfef67d95779d23a8d763 (diff)
The uvm_map_inentry() check may sleep to grab the lock of the map.
The fault address is read from cr2 in pageflttrap() which gets called after this check and if the check sleeps, cr2 is likely to be clobbered by a page fault in another process. Fix this by reading cr2 early and pass it to pageflttrap(). ok mpi@, semarie@, deraadt@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/amd64/trap.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c
index 4a4c6275aa7..c401042f03e 100644
--- a/sys/arch/amd64/amd64/trap.c
+++ b/sys/arch/amd64/amd64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.80 2020/08/19 10:10:57 mpi Exp $ */
+/* $OpenBSD: trap.c,v 1.81 2020/09/14 12:51:28 kettenis Exp $ */
/* $NetBSD: trap.c,v 1.2 2003/05/04 23:51:56 fvdl Exp $ */
/*-
@@ -92,7 +92,7 @@
#include "isa.h"
-int pageflttrap(struct trapframe *, int _usermode);
+int pageflttrap(struct trapframe *, uint64_t, int _usermode);
void kerntrap(struct trapframe *);
void usertrap(struct trapframe *);
void ast(struct trapframe *);
@@ -157,12 +157,11 @@ fault(const char *format, ...)
* if something was so broken that we should panic.
*/
int
-pageflttrap(struct trapframe *frame, int usermode)
+pageflttrap(struct trapframe *frame, uint64_t cr2, int usermode)
{
struct proc *p = curproc;
struct pcb *pcb;
int error;
- uint64_t cr2;
vaddr_t va;
struct vm_map *map;
vm_prot_t ftype;
@@ -172,7 +171,6 @@ pageflttrap(struct trapframe *frame, int usermode)
map = &p->p_vmspace->vm_map;
pcb = &p->p_addr->u_pcb;
- cr2 = rcr2();
va = trunc_page((vaddr_t)cr2);
KERNEL_LOCK();
@@ -280,6 +278,7 @@ void
kerntrap(struct trapframe *frame)
{
int type = (int)frame->tf_trapno;
+ uint64_t cr2 = rcr2();
verify_smap(__func__);
uvmexp.traps++;
@@ -299,7 +298,7 @@ kerntrap(struct trapframe *frame)
/*NOTREACHED*/
case T_PAGEFLT: /* allow page faults in kernel mode */
- if (pageflttrap(frame, 0))
+ if (pageflttrap(frame, cr2, 0))
return;
goto we_re_toast;
@@ -333,6 +332,7 @@ usertrap(struct trapframe *frame)
{
struct proc *p = curproc;
int type = (int)frame->tf_trapno;
+ uint64_t cr2 = rcr2();
union sigval sv;
int sig, code;
@@ -381,7 +381,7 @@ usertrap(struct trapframe *frame)
break;
case T_PAGEFLT: /* page fault */
- if (pageflttrap(frame, 1))
+ if (pageflttrap(frame, cr2, 1))
goto out;
/* FALLTHROUGH */