Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch Change the argument to fpudna() to be the trapframe.
details: https://anonhg.NetBSD.org/src/rev/4e1485ec3a08
branches: trunk
changeset: 326680:4e1485ec3a08
user: dsl <dsl%NetBSD.org@localhost>
date: Wed Feb 12 19:53:49 2014 +0000
description:
Change the argument to fpudna() to be the trapframe.
Move the checks for fpu traps in kernel into x86/fpu.c.
Remove the code from amd64/trap.c related to fpu traps (they've not gone
there for ages - expect to panic in kernel mode).
In fpudna():
- Don't actually enable hardware interrupts unless we need to
allow in IPIs.
- There is no point in enabling them when they are blocked in software
(by splhigh()).
- Keep the splhigh() to avoid a load of the KASSERTS() firing.
diffstat:
sys/arch/amd64/amd64/amd64_trap.S | 13 ++++---------
sys/arch/amd64/amd64/trap.c | 23 ++++++-----------------
sys/arch/x86/x86/fpu.c | 28 ++++++++++++++++++++--------
3 files changed, 30 insertions(+), 34 deletions(-)
diffs (194 lines):
diff -r e4ff5d3759a7 -r 4e1485ec3a08 sys/arch/amd64/amd64/amd64_trap.S
--- a/sys/arch/amd64/amd64/amd64_trap.S Wed Feb 12 04:08:31 2014 +0000
+++ b/sys/arch/amd64/amd64/amd64_trap.S Wed Feb 12 19:53:49 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: amd64_trap.S,v 1.1 2013/06/25 00:27:22 uebayasi Exp $ */
+/* $NetBSD: amd64_trap.S,v 1.2 2014/02/12 19:53:49 dsl Exp $ */
/*-
* Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
#if 0
#include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.1 2013/06/25 00:27:22 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.2 2014/02/12 19:53:49 dsl Exp $");
#endif
/*
@@ -195,12 +195,12 @@
IDTVEC_END(trap06)
IDTVEC(trap07)
- ZTRAP_NJ(T_ASTFLT)
+ ZTRAP_NJ(T_DNA)
INTRENTRY
#ifdef DIAGNOSTIC
movl CPUVAR(ILEVEL),%ebx
#endif /* DIAGNOSTIC */
- movq CPUVAR(SELF),%rdi
+ movq %rsp,%rdi
call _C_LABEL(fpudna)
jmp .Lalltraps_checkusr
IDTVEC_END(trap07)
@@ -290,14 +290,9 @@
#ifdef DIAGNOSTIC
movl CPUVAR(ILEVEL),%ebx
#endif /* DIAGNOSTIC */
- testb $SEL_RPL,TF_CS(%rsp)
- jz 1f
movq %rsp,%rdi
call _C_LABEL(fputrap)
jmp .Lalltraps_checkusr
-1:
- STI(si)
- jmp calltrap
IDTVEC_END(trap10)
IDTVEC(trap11)
diff -r e4ff5d3759a7 -r 4e1485ec3a08 sys/arch/amd64/amd64/trap.c
--- a/sys/arch/amd64/amd64/trap.c Wed Feb 12 04:08:31 2014 +0000
+++ b/sys/arch/amd64/amd64/trap.c Wed Feb 12 19:53:49 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.76 2014/02/11 20:17:16 dsl Exp $ */
+/* $NetBSD: trap.c,v 1.77 2014/02/12 19:53:49 dsl Exp $ */
/*-
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.76 2014/02/11 20:17:16 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.77 2014/02/12 19:53:49 dsl Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@@ -210,6 +210,10 @@
* that prepare a suitable stack frame, and restore this frame after the
* exception has been processed. Note that the effect is as if the arguments
* were passed call by reference.
+ *
+ * Note that the fpu traps (07 T_DNA, 10 T_ARITHTRAP and 13 T_XMM)
+ * jump directly into the code in x86/fpu.c so they get processed
+ * without interrupts being enabled.
*/
void
trap(struct trapframe *frame)
@@ -445,9 +449,6 @@
}
goto trapsignal;
- case T_ARITHTRAP|T_USER:
- case T_XMM|T_USER:
- /* Already handled by fputrap(), fall through. */
case T_ASTFLT|T_USER:
/* Allow process switch. */
//curcpu()->ci_data.cpu_nast++;
@@ -461,18 +462,6 @@
}
goto out;
-#if 0 /* handled by fpudna() */
- case T_DNA|T_USER: {
- printf("pid %d.%d killed due to lack of floating point\n",
- p->p_pid, l->l_lid);
- KSI_INIT_TRAP(&ksi);
- ksi.ksi_signo = SIGKILL;
- ksi.ksi_trap = type & ~T_USER;
- ksi.ksi_addr = (void *)frame->tf_rip;
- goto trapsignal;
- }
-#endif
-
case T_BOUND|T_USER:
case T_OFLOW|T_USER:
case T_DIVIDE|T_USER:
diff -r e4ff5d3759a7 -r 4e1485ec3a08 sys/arch/x86/x86/fpu.c
--- a/sys/arch/x86/x86/fpu.c Wed Feb 12 04:08:31 2014 +0000
+++ b/sys/arch/x86/x86/fpu.c Wed Feb 12 19:53:49 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu.c,v 1.1 2014/02/11 20:17:16 dsl Exp $ */
+/* $NetBSD: fpu.c,v 1.2 2014/02/12 19:53:49 dsl Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc. All
@@ -100,7 +100,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.1 2014/02/11 20:17:16 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.2 2014/02/12 19:53:49 dsl Exp $");
#include "opt_multiprocessor.h"
@@ -143,7 +143,7 @@
* state is saved.
*/
-void fpudna(struct cpu_info *);
+void fpudna(struct trapframe *frame);
/*
* The following table is used to ensure that the FPE_... value
@@ -265,6 +265,9 @@
uint32_t statbits;
ksiginfo_t ksi;
+ if (!USERMODE(frame->tf_cs, frame->tf_eflags))
+ panic("fpu trap from kernel, trapframe %p\n", frame);
+
/*
* At this point, fpcurlwp should be curlwp. If it wasn't, the TS bit
* should be set, and we should have gotten a DNA exception.
@@ -312,19 +315,26 @@
* If we were the last lwp to use the FPU, we can simply return.
* Otherwise, we save the previous state, if necessary, and restore
* our last saved state.
+ *
+ * Called directly from the trap 0x13 entry with interrupts still disabled.
*/
void
-fpudna(struct cpu_info *ci)
+fpudna(struct trapframe *frame)
{
+ struct cpu_info *ci;
uint16_t cw;
uint32_t mxcsr;
struct lwp *l, *fl;
struct pcb *pcb;
int s;
- /* Lock out IPIs and disable preemption. */
+ if (!USERMODE(frame->tf_cs, frame->tf_eflags))
+ panic("fpudna from kernel, trapframe %p\n", frame);
+
+ ci = curcpu();
+
+ /* Save soft spl level - interrupts are hard disabled */
s = splhigh();
- x86_enable_intr();
/* Save state on current CPU. */
l = ci->ci_curlwp;
@@ -341,9 +351,7 @@
splx(s);
return;
}
- KASSERT(fl != l);
fpusave_cpu(true);
- KASSERT(ci->ci_fpcurlwp == NULL);
}
/* Save our state if on a remote CPU. */
@@ -351,6 +359,10 @@
/* Explicitly disable preemption before dropping spl. */
KPREEMPT_DISABLE(l);
splx(s);
+
+ /* Actually enable interrupts */
+ x86_enable_intr();
+
fpusave_lwp(l, true);
KASSERT(pcb->pcb_fpcpu == NULL);
s = splhigh();
Home |
Main Index |
Thread Index |
Old Index