summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/amd64/amd64/fpu.c6
-rw-r--r--sys/arch/amd64/amd64/locore.S11
-rw-r--r--sys/arch/amd64/amd64/trap.c14
3 files changed, 26 insertions, 5 deletions
diff --git a/sys/arch/amd64/amd64/fpu.c b/sys/arch/amd64/amd64/fpu.c
index 4e8365cc694..74cd263c015 100644
--- a/sys/arch/amd64/amd64/fpu.c
+++ b/sys/arch/amd64/amd64/fpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fpu.c,v 1.35 2017/05/29 14:19:49 mpi Exp $ */
+/* $OpenBSD: fpu.c,v 1.36 2017/10/03 17:36:40 guenther Exp $ */
/* $NetBSD: fpu.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */
/*-
@@ -55,6 +55,8 @@
#include <dev/isa/isavar.h>
+void xrstor_user(struct savefpu *_addr, uint64_t _mask);
+
/*
* We do lazy initialization and switching using the TS bit in cr0 and the
* MDP_USEDFPU bit in mdproc.
@@ -253,7 +255,7 @@ fpudna(struct cpu_info *ci)
p->p_md.md_flags |= MDP_USEDFPU;
} else {
if (xsave_mask) {
- xrstor(sfp, xsave_mask);
+ xrstor_user(sfp, xsave_mask);
} else {
static double zero = 0.0;
diff --git a/sys/arch/amd64/amd64/locore.S b/sys/arch/amd64/amd64/locore.S
index dbd2e2fbbaf..e0fa7144b62 100644
--- a/sys/arch/amd64/amd64/locore.S
+++ b/sys/arch/amd64/amd64/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.87 2017/07/06 06:17:04 deraadt Exp $ */
+/* $OpenBSD: locore.S,v 1.88 2017/10/03 17:36:40 guenther Exp $ */
/* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */
/*
@@ -691,6 +691,15 @@ _C_LABEL(doreti_iret):
iretq
#endif /* !defined(GPROF) && defined(DDBPROF) */
+ENTRY(xrstor_user)
+ movq %rsi, %rdx
+ movl %esi, %eax
+ shrq $32, %rdx
+ .globl xrstor_fault
+xrstor_fault:
+ xrstor (%rdi)
+ ret
+
ENTRY(pagezero)
movq $-PAGE_SIZE,%rdx
subq %rdx,%rdi
diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c
index 726bea4394e..66278f198e8 100644
--- a/sys/arch/amd64/amd64/trap.c
+++ b/sys/arch/amd64/amd64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.58 2017/09/16 02:03:40 guenther Exp $ */
+/* $OpenBSD: trap.c,v 1.59 2017/10/03 17:36:40 guenther Exp $ */
/* $NetBSD: trap.c,v 1.2 2003/05/04 23:51:56 fvdl Exp $ */
/*-
@@ -144,7 +144,7 @@ trap(struct trapframe *frame)
struct proc *p = curproc;
int type = (int)frame->tf_trapno;
struct pcb *pcb;
- extern char doreti_iret[], resume_iret[];
+ extern char doreti_iret[], resume_iret[], xrstor_fault[];
caddr_t onfault;
int error;
uint64_t cr2;
@@ -204,6 +204,15 @@ trap(struct trapframe *frame)
/*NOTREACHED*/
case T_PROTFLT:
+ /*
+ * Check for xrstor faulting because of invalid xstate
+ * We do this by looking at the address of the
+ * instruction that faulted.
+ */
+ if (frame->tf_rip == (u_int64_t)xrstor_fault && p != NULL) {
+ fpusave_proc(p, 0);
+ goto user_trap;
+ }
case T_SEGNPFLT:
case T_ALIGNFLT:
case T_TSSFLT:
@@ -231,6 +240,7 @@ copyfault:
case T_TSSFLT|T_USER:
case T_SEGNPFLT|T_USER:
case T_STKFLT|T_USER:
+user_trap:
#ifdef TRAP_SIGDEBUG
printf("pid %d (%s): %s at rip %llx addr %llx\n",
p->p_p->ps_pid, p->p_p->ps_comm, "BUS",