Author: jhb
Date: Wed Mar 25 17:22:15 2009
New Revision: 190418
URL: http://svn.freebsd.org/changeset/base/190418

Log:
  Allow different ABIs to use different initial control words for the FPU on
  amd64 and i386.  This fixes a bug were 32-bit binaries would run with a
  different floating point exception mask under FreeBSD/amd64 vs FreeBSD/i386.
  This commit also includes a few other minor changes to keep the code in
  sync with 8.
  
  Approved by:  re (kib)

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/amd64/amd64/fpu.c
  stable/7/sys/amd64/amd64/machdep.c
  stable/7/sys/amd64/amd64/trap.c
  stable/7/sys/amd64/ia32/ia32_signal.c
  stable/7/sys/amd64/include/fpu.h
  stable/7/sys/amd64/include/pcb.h
  stable/7/sys/amd64/linux32/linux32_sysvec.c
  stable/7/sys/compat/linux/linux_misc.h
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/ath/ath_hal/   (props changed)
  stable/7/sys/dev/cxgb/   (props changed)
  stable/7/sys/i386/i386/machdep.c
  stable/7/sys/i386/i386/mp_machdep.c
  stable/7/sys/i386/include/npx.h
  stable/7/sys/i386/include/pcb.h
  stable/7/sys/i386/isa/npx.c
  stable/7/sys/i386/linux/linux_sysvec.c

Modified: stable/7/sys/amd64/amd64/fpu.c
==============================================================================
--- stable/7/sys/amd64/amd64/fpu.c      Wed Mar 25 17:02:05 2009        
(r190417)
+++ stable/7/sys/amd64/amd64/fpu.c      Wed Mar 25 17:22:15 2009        
(r190418)
@@ -98,16 +98,15 @@ typedef u_char bool_t;
 
 static void    fpu_clean_state(void);
 
-int    hw_float = 1;
-SYSCTL_INT(_hw,HW_FLOATINGPT, floatingpoint,
-       CTLFLAG_RD, &hw_float, 0, 
-       "Floatingpoint instructions executed in hardware");
+SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD,
+    NULL, 1, "Floating point instructions executed in hardware");
 
 static struct savefpu          fpu_cleanstate;
-static bool_t                  fpu_cleanstate_ready;
 
 /*
- * Initialize floating point unit.
+ * Initialize the floating point unit.  On the boot CPU we generate a
+ * clean state that is used to initialize the floating point unit when
+ * it is first used by a process.
  */
 void
 fpuinit(void)
@@ -117,22 +116,22 @@ fpuinit(void)
        u_short control;
 
        savecrit = intr_disable();
-       PCPU_SET(fpcurthread, 0);
        stop_emulating();
        fninit();
        control = __INITIAL_FPUCW__;
        fldcw(&control);
        mxcsr = __INITIAL_MXCSR__;
        ldmxcsr(mxcsr);
-       fxsave(&fpu_cleanstate);
-       if (fpu_cleanstate.sv_env.en_mxcsr_mask)
-               cpu_mxcsr_mask = fpu_cleanstate.sv_env.en_mxcsr_mask;
-       else
-               cpu_mxcsr_mask = 0xFFBF;
+       if (PCPU_GET(cpuid) == 0) {
+               fxsave(&fpu_cleanstate);
+               if (fpu_cleanstate.sv_env.en_mxcsr_mask)
+                       cpu_mxcsr_mask = fpu_cleanstate.sv_env.en_mxcsr_mask;
+               else
+                       cpu_mxcsr_mask = 0xFFBF;
+               bzero(fpu_cleanstate.sv_fp, sizeof(fpu_cleanstate.sv_fp));
+               bzero(fpu_cleanstate.sv_xmm, sizeof(fpu_cleanstate.sv_xmm));
+       }
        start_emulating();
-       bzero(fpu_cleanstate.sv_fp, sizeof(fpu_cleanstate.sv_fp));
-       bzero(fpu_cleanstate.sv_xmm, sizeof(fpu_cleanstate.sv_xmm));
-       fpu_cleanstate_ready = 1;
        intr_restore(savecrit);
 }
 
@@ -386,8 +385,8 @@ fputrap()
 
 static int err_count = 0;
 
-int
-fpudna()
+void
+fpudna(void)
 {
        struct pcb *pcb;
        register_t s;
@@ -396,7 +395,7 @@ fpudna()
                printf("fpudna: fpcurthread == curthread %d times\n",
                    ++err_count);
                stop_emulating();
-               return (1);
+               return;
        }
        if (PCPU_GET(fpcurthread) != NULL) {
                printf("fpudna: fpcurthread = %p (%d), curthread = %p (%d)\n",
@@ -421,12 +420,12 @@ fpudna()
                 * explicitly load sanitized registers.
                 */
                fxrstor(&fpu_cleanstate);
+               if (pcb->pcb_initial_fpucw != __INITIAL_FPUCW__)
+                       fldcw(&pcb->pcb_initial_fpucw);
                pcb->pcb_flags |= PCB_FPUINITDONE;
        } else
                fxrstor(&pcb->pcb_save);
        intr_restore(s);
-
-       return (1);
 }
 
 /*
@@ -454,10 +453,8 @@ fpugetregs(struct thread *td, struct sav
        register_t s;
 
        if ((td->td_pcb->pcb_flags & PCB_FPUINITDONE) == 0) {
-               if (fpu_cleanstate_ready)
-                       bcopy(&fpu_cleanstate, addr, sizeof(fpu_cleanstate));
-               else
-                       bzero(addr, sizeof(*addr));
+               bcopy(&fpu_cleanstate, addr, sizeof(fpu_cleanstate));
+               addr->sv_env.en_cw = td->td_pcb->pcb_initial_fpucw;
                return (_MC_FPOWNED_NONE);
        }
        s = intr_disable();

Modified: stable/7/sys/amd64/amd64/machdep.c
==============================================================================
--- stable/7/sys/amd64/amd64/machdep.c  Wed Mar 25 17:02:05 2009        
(r190417)
+++ stable/7/sys/amd64/amd64/machdep.c  Wed Mar 25 17:22:15 2009        
(r190418)
@@ -586,7 +586,7 @@ cpu_idle(void)
 void (*cpu_idle_hook)(void) = cpu_idle_default;
 
 /*
- * Clear registers on exec
+ * Reset registers to default values on exec.
  */
 void
 exec_setregs(td, entry, stack, ps_strings)
@@ -613,6 +613,7 @@ exec_setregs(td, entry, stack, ps_string
        pcb->pcb_es = _udatasel;
        pcb->pcb_fs = _udatasel;
        pcb->pcb_gs = _udatasel;
+       pcb->pcb_initial_fpucw = __INITIAL_FPUCW__;
 
        bzero((char *)regs, sizeof(struct trapframe));
        regs->tf_rip = entry;

Modified: stable/7/sys/amd64/amd64/trap.c
==============================================================================
--- stable/7/sys/amd64/amd64/trap.c     Wed Mar 25 17:02:05 2009        
(r190417)
+++ stable/7/sys/amd64/amd64/trap.c     Wed Mar 25 17:22:15 2009        
(r190418)
@@ -421,13 +421,8 @@ trap(struct trapframe *frame)
 
                case T_DNA:
                        /* transparent fault (due to context switch "late") */
-                       if (fpudna())
-                               goto userout;
-                       printf("pid %d killed due to lack of floating point\n",
-                               p->p_pid);
-                       i = SIGKILL;
-                       ucode = 0;
-                       break;
+                       fpudna();
+                       goto userout;
 
                case T_FPOPFLT:         /* FPU operand fetch fault */
                        ucode = ILL_COPROC;
@@ -455,11 +450,9 @@ trap(struct trapframe *frame)
                         * XXX this should be fatal unless the kernel has
                         * registered such use.
                         */
-                       if (fpudna()) {
-                               printf("fpudna in kernel mode!\n");
-                               goto out;
-                       }
-                       break;
+                       fpudna();
+                       printf("fpudna in kernel mode!\n");
+                       goto out;
 
                case T_STKFLT:          /* stack fault */
                        break;

Modified: stable/7/sys/amd64/ia32/ia32_signal.c
==============================================================================
--- stable/7/sys/amd64/ia32/ia32_signal.c       Wed Mar 25 17:02:05 2009        
(r190417)
+++ stable/7/sys/amd64/ia32/ia32_signal.c       Wed Mar 25 17:22:15 2009        
(r190418)
@@ -727,6 +727,7 @@ ia32_setregs(td, entry, stack, ps_string
        pcb->pcb_es = _udatasel;
        pcb->pcb_fs = _udatasel;
        pcb->pcb_gs = _udatasel;
+       pcb->pcb_initial_fpucw = __INITIAL_FPUCW_I386__;
 
        bzero((char *)regs, sizeof(struct trapframe));
        regs->tf_rip = entry;

Modified: stable/7/sys/amd64/include/fpu.h
==============================================================================
--- stable/7/sys/amd64/include/fpu.h    Wed Mar 25 17:02:05 2009        
(r190417)
+++ stable/7/sys/amd64/include/fpu.h    Wed Mar 25 17:22:15 2009        
(r190418)
@@ -92,11 +92,12 @@ struct  savefpu {
  * SSE2 based math.  For FreeBSD/amd64, we go with the default settings.
  */
 #define        __INITIAL_FPUCW__       0x037F
+#define        __INITIAL_FPUCW_I386__  0x127F
 #define        __INITIAL_MXCSR__       0x1F80
 #define        __INITIAL_MXCSR_MASK__  0xFFBF
 
 #ifdef _KERNEL
-int    fpudna(void);
+void   fpudna(void);
 void   fpudrop(void);
 void   fpuexit(struct thread *td);
 int    fpuformat(void);

Modified: stable/7/sys/amd64/include/pcb.h
==============================================================================
--- stable/7/sys/amd64/include/pcb.h    Wed Mar 25 17:02:05 2009        
(r190417)
+++ stable/7/sys/amd64/include/pcb.h    Wed Mar 25 17:22:15 2009        
(r190418)
@@ -55,6 +55,13 @@ struct pcb {
        register_t      pcb_rip;
        register_t      pcb_fsbase;
        register_t      pcb_gsbase;
+       u_long          pcb_flags;
+#define        PCB_DBREGS      0x02    /* process using debug registers */
+#define        PCB_FPUINITDONE 0x08    /* fpu state is initialized */
+#define        PCB_GS32BIT     0x20    /* linux gs switch */
+#define        PCB_32BIT       0x40    /* process has 32 bit context (segs 
etc) */
+#define        PCB_FULLCTX     0x80    /* full context restore on sysret */
+
        u_int32_t       pcb_ds;
        u_int32_t       pcb_es;
        u_int32_t       pcb_fs;
@@ -67,12 +74,7 @@ struct pcb {
        u_int64_t       pcb_dr7;
 
        struct  savefpu pcb_save;
-       u_long  pcb_flags;
-#define        PCB_DBREGS      0x02    /* process using debug registers */
-#define        PCB_FPUINITDONE 0x08    /* fpu state is initialized */
-#define        PCB_GS32BIT     0x20    /* linux gs switch */
-#define        PCB_32BIT       0x40    /* process has 32 bit context (segs 
etc) */
-#define        PCB_FULLCTX     0x80    /* full context restore on sysret */
+       uint16_t        pcb_initial_fpucw;
 
        caddr_t pcb_onfault;    /* copyin/out fault recovery */
 

Modified: stable/7/sys/amd64/linux32/linux32_sysvec.c
==============================================================================
--- stable/7/sys/amd64/linux32/linux32_sysvec.c Wed Mar 25 17:02:05 2009        
(r190417)
+++ stable/7/sys/amd64/linux32/linux32_sysvec.c Wed Mar 25 17:22:15 2009        
(r190418)
@@ -832,6 +832,7 @@ exec_linux_setregs(td, entry, stack, ps_
        pcb->pcb_es = _udatasel;
        pcb->pcb_fs = _udatasel;
        pcb->pcb_gs = _udatasel;
+       pcb->pcb_initial_fpucw = __LINUX_NPXCW__;
 
        bzero((char *)regs, sizeof(struct trapframe));
        regs->tf_rip = entry;

Modified: stable/7/sys/compat/linux/linux_misc.h
==============================================================================
--- stable/7/sys/compat/linux/linux_misc.h      Wed Mar 25 17:02:05 2009        
(r190417)
+++ stable/7/sys/compat/linux/linux_misc.h      Wed Mar 25 17:22:15 2009        
(r190418)
@@ -45,4 +45,9 @@
 #define        LINUX_MREMAP_MAYMOVE    1
 #define        LINUX_MREMAP_FIXED      2
 
+/* Linux sets the i387 to extended precision. */
+#if defined(__i386__) || defined(__amd64__)
+#define        __LINUX_NPXCW__         0x37f
+#endif
+
 #endif /* _LINUX_MISC_H_ */

Modified: stable/7/sys/i386/i386/machdep.c
==============================================================================
--- stable/7/sys/i386/i386/machdep.c    Wed Mar 25 17:02:05 2009        
(r190417)
+++ stable/7/sys/i386/i386/machdep.c    Wed Mar 25 17:22:15 2009        
(r190418)
@@ -1188,7 +1188,7 @@ cpu_idle(void)
 void (*cpu_idle_hook)(void) = cpu_idle_default;
 
 /*
- * Clear registers on exec
+ * Reset registers to default values on exec.
  */
 void
 exec_setregs(td, entry, stack, ps_strings)
@@ -1253,6 +1253,7 @@ exec_setregs(td, entry, stack, ps_string
         * emulators don't provide an entry point for initialization.
         */
        td->td_pcb->pcb_flags &= ~FP_SOFTFP;
+       pcb->pcb_initial_npxcw = __INITIAL_NPXCW__;
 
        /*
         * Drop the FP state if we hold it, so that the process gets a

Modified: stable/7/sys/i386/i386/mp_machdep.c
==============================================================================
--- stable/7/sys/i386/i386/mp_machdep.c Wed Mar 25 17:02:05 2009        
(r190417)
+++ stable/7/sys/i386/i386/mp_machdep.c Wed Mar 25 17:22:15 2009        
(r190418)
@@ -575,7 +575,7 @@ init_secondary(void)
        cpu_setregs();
 
        /* set up FPU state on the AP */
-       npxinit(__INITIAL_NPXCW__);
+       npxinit();
 
        /* set up SSE registers */
        enable_sse();

Modified: stable/7/sys/i386/include/npx.h
==============================================================================
--- stable/7/sys/i386/include/npx.h     Wed Mar 25 17:02:05 2009        
(r190417)
+++ stable/7/sys/i386/include/npx.h     Wed Mar 25 17:22:15 2009        
(r190418)
@@ -151,7 +151,7 @@ void        npxdrop(void);
 void   npxexit(struct thread *td);
 int    npxformat(void);
 int    npxgetregs(struct thread *td, union savefpu *addr);
-void   npxinit(u_short control);
+void   npxinit(void);
 void   npxsave(union savefpu *addr);
 void   npxsetregs(struct thread *td, union savefpu *addr);
 int    npxtrap(void);

Modified: stable/7/sys/i386/include/pcb.h
==============================================================================
--- stable/7/sys/i386/include/pcb.h     Wed Mar 25 17:02:05 2009        
(r190417)
+++ stable/7/sys/i386/include/pcb.h     Wed Mar 25 17:22:15 2009        
(r190418)
@@ -61,6 +61,7 @@ struct pcb {
        int     pcb_dr7;
 
        union   savefpu pcb_save;
+       uint16_t pcb_initial_npxcw;
        u_int   pcb_flags;
 #define        FP_SOFTFP       0x01    /* process using software fltng pnt 
emulator */
 #define        PCB_DBREGS      0x02    /* process using debug registers */

Modified: stable/7/sys/i386/isa/npx.c
==============================================================================
--- stable/7/sys/i386/isa/npx.c Wed Mar 25 17:02:05 2009        (r190417)
+++ stable/7/sys/i386/isa/npx.c Wed Mar 25 17:22:15 2009        (r190418)
@@ -132,11 +132,19 @@ void      stop_emulating(void);
        (cpu_fxsr ? \
                (thread)->td_pcb->pcb_save.sv_xmm.sv_env.en_sw : \
                (thread)->td_pcb->pcb_save.sv_87.sv_env.en_sw)
+#define SET_FPU_CW(savefpu, value) do { \
+       if (cpu_fxsr) \
+               (savefpu)->sv_xmm.sv_env.en_cw = (value); \
+       else \
+               (savefpu)->sv_87.sv_env.en_cw = (value); \
+} while (0)
 #else /* CPU_ENABLE_SSE */
 #define GET_FPU_CW(thread) \
        (thread->td_pcb->pcb_save.sv_87.sv_env.en_cw)
 #define GET_FPU_SW(thread) \
        (thread->td_pcb->pcb_save.sv_87.sv_env.en_sw)
+#define SET_FPU_CW(savefpu, value) \
+       (savefpu)->sv_87.sv_env.en_cw = (value)
 #endif /* CPU_ENABLE_SSE */
 
 typedef u_char bool_t;
@@ -158,15 +166,13 @@ static    long    timezero(const char *funcnam
 
 int    hw_float;               /* XXX currently just alias for npx_exists */
 
-SYSCTL_INT(_hw,HW_FLOATINGPT, floatingpoint,
-       CTLFLAG_RD, &hw_float, 0, 
-       "Floatingpoint instructions executed in hardware");
+SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD,
+    &hw_float, 0, "Floating point instructions executed in hardware");
 
 static volatile u_int          npx_intrs_while_probing;
 static volatile u_int          npx_traps_while_probing;
 
 static union savefpu           npx_cleanstate;
-static bool_t                  npx_cleanstate_ready;
 static bool_t                  npx_ex16;
 static bool_t                  npx_exists;
 static bool_t                  npx_irq13;
@@ -368,19 +374,14 @@ npx_probe(dev)
                                return (0);
                        }
                        /*
-                        * Worse, even IRQ13 is broken.  Use emulator.
+                        * Worse, even IRQ13 is broken.
                         */
                }
        }
-       /*
-        * Probe failed, but we want to get to npxattach to initialize the
-        * emulator and say that it has been installed.  XXX handle devices
-        * that aren't really devices better.
-        */
-#ifdef SMP
-       if (mp_ncpus > 1)
-               panic("npx0 cannot be emulated on an SMP system");
-#endif
+
+       /* Probe failed.  Floating point simply won't work. */
+       device_printf(dev, "WARNING: no FPU!\n");
+
        /* FALLTHROUGH */
 no_irq13:
        idt[IDT_MF] = save_idt_npxtrap;
@@ -389,7 +390,7 @@ no_irq13:
                bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res);
        }
        bus_release_resource(dev, SYS_RES_IOPORT, ioport_rid, ioport_res);
-       return (0);
+       return (npx_exists ? 0 : ENXIO);
 }
 
 /*
@@ -406,32 +407,34 @@ npx_attach(dev)
 
        if (npx_irq13)
                device_printf(dev, "IRQ 13 interface\n");
-       else if (!npx_ex16)
-               device_printf(dev, "WARNING: no FPU!\n");
        else if (!device_is_quiet(dev) || bootverbose)
                device_printf(dev, "INT 16 interface\n");
 
-       npxinit(__INITIAL_NPXCW__);
+       npxinit();
 
-       if (npx_cleanstate_ready == 0) {
-               s = intr_disable();
-               stop_emulating();
-               fpusave(&npx_cleanstate);
-               start_emulating();
+       s = intr_disable();
+       stop_emulating();
+       fpusave(&npx_cleanstate);
+       start_emulating();
 #ifdef CPU_ENABLE_SSE
-               if (cpu_fxsr) {
-                       if (npx_cleanstate.sv_xmm.sv_env.en_mxcsr_mask)
-                               cpu_mxcsr_mask = 
-                                   npx_cleanstate.sv_xmm.sv_env.en_mxcsr_mask;
-                       else
-                               cpu_mxcsr_mask = 0xFFBF;
-               }
+       if (cpu_fxsr) {
+               if (npx_cleanstate.sv_xmm.sv_env.en_mxcsr_mask)
+                       cpu_mxcsr_mask = 
+                           npx_cleanstate.sv_xmm.sv_env.en_mxcsr_mask;
+               else
+                       cpu_mxcsr_mask = 0xFFBF;
+               bzero(npx_cleanstate.sv_xmm.sv_fp,
+                   sizeof(npx_cleanstate.sv_xmm.sv_fp));
+               bzero(npx_cleanstate.sv_xmm.sv_xmm,
+                   sizeof(npx_cleanstate.sv_xmm.sv_xmm));
+               /* XXX might need even more zeroing. */
+       } else
 #endif
-               npx_cleanstate_ready = 1;
-               intr_restore(s);
-       }
+               bzero(npx_cleanstate.sv_87.sv_ac,
+                   sizeof(npx_cleanstate.sv_87.sv_ac));
+       intr_restore(s);
 #ifdef I586_CPU_XXX
-       if (cpu_class == CPUCLASS_586 && npx_ex16 && npx_exists &&
+       if (cpu_class == CPUCLASS_586 && npx_ex16 &&
            timezero("i586_bzero()", i586_bzero) <
            timezero("bzero()", bzero) * 4 / 5) {
                if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BCOPY))
@@ -452,10 +455,11 @@ npx_attach(dev)
  * Initialize floating point unit.
  */
 void
-npxinit(u_short control)
+npxinit(void)
 {
        static union savefpu dummy;
        register_t savecrit;
+       u_short control;
 
        if (!npx_exists)
                return;
@@ -472,6 +476,7 @@ npxinit(u_short control)
        if (cpu_fxsr)
                fninit();
 #endif
+       control = __INITIAL_NPXCW__;
        fldcw(&control);
        start_emulating();
        intr_restore(savecrit);
@@ -752,14 +757,10 @@ npxtrap()
 static int err_count = 0;
 
 int
-npxdna()
+npxdna(void)
 {
        struct pcb *pcb;
        register_t s;
-#ifdef CPU_ENABLE_SSE
-       int mxcsr;
-#endif
-       u_short control;
 
        if (!npx_exists)
                return (0);
@@ -788,22 +789,16 @@ npxdna()
                /*
                 * This is the first time this thread has used the FPU or
                 * the PCB doesn't contain a clean FPU state.  Explicitly
-                * initialize the FPU and load the default control word.
+                * load sanitized registers.
                 */
-               fninit();
-               control = __INITIAL_NPXCW__;
-               fldcw(&control);
-#ifdef CPU_ENABLE_SSE
-               if (cpu_fxsr) {
-                       mxcsr = __INITIAL_MXCSR__;
-                       ldmxcsr(mxcsr);
-               }
-#endif
+               fpurstor(&npx_cleanstate);
+               if (pcb->pcb_initial_npxcw != __INITIAL_NPXCW__)
+                       fldcw(&pcb->pcb_initial_npxcw);
                pcb->pcb_flags |= PCB_NPXINITDONE;
        } else {
                /*
-                * The following frstor may cause an IRQ13 when the state
-                * being restored has a pending error.  The error will
+                * The following fpurstor() may cause an IRQ13 when the
+                * state being restored has a pending error.  The error will
                 * appear to have been triggered by the current (npx) user
                 * instruction even when that instruction is a no-wait
                 * instruction that should not trigger an error (e.g.,
@@ -896,10 +891,8 @@ npxgetregs(td, addr)
                return (_MC_FPOWNED_NONE);
 
        if ((td->td_pcb->pcb_flags & PCB_NPXINITDONE) == 0) {
-               if (npx_cleanstate_ready)
-                       bcopy(&npx_cleanstate, addr, sizeof(npx_cleanstate));
-               else
-                       bzero(addr, sizeof(*addr));
+               bcopy(&npx_cleanstate, addr, sizeof(npx_cleanstate));
+               SET_FPU_CW(addr, td->td_pcb->pcb_initial_npxcw);
                return (_MC_FPOWNED_NONE);
        }
        s = intr_disable();

Modified: stable/7/sys/i386/linux/linux_sysvec.c
==============================================================================
--- stable/7/sys/i386/linux/linux_sysvec.c      Wed Mar 25 17:02:05 2009        
(r190417)
+++ stable/7/sys/i386/linux/linux_sysvec.c      Wed Mar 25 17:22:15 2009        
(r190418)
@@ -86,9 +86,6 @@ MALLOC_DEFINE(M_LINUX, "linux", "Linux m
 #define        LINUX_SYS_linux_rt_sendsig      0
 #define        LINUX_SYS_linux_sendsig         0
 
-#define        fldcw(addr)             __asm("fldcw %0" : : "m" (*(addr)))
-#define        __LINUX_NPXCW__         0x37f
-
 extern char linux_sigcode[];
 extern int linux_szsigcode;
 
@@ -800,16 +797,15 @@ static void
 exec_linux_setregs(struct thread *td, u_long entry,
                   u_long stack, u_long ps_strings)
 {
-       static const u_short control = __LINUX_NPXCW__;
        struct pcb *pcb = td->td_pcb;
 
        exec_setregs(td, entry, stack, ps_strings);
 
        /* Linux sets %gs to 0, we default to _udatasel */
-       pcb->pcb_gs = 0; load_gs(0);
+       pcb->pcb_gs = 0;
+       load_gs(0);
 
-       /* Linux sets the i387 to extended precision. */
-       fldcw(&control);
+       pcb->pcb_initial_npxcw = __LINUX_NPXCW__;
 }
 
 struct sysentvec linux_sysvec = {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to