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