On Mon, Dec 27, 2010 at 12:07:55PM -0800, Philip Guenther wrote: > Okay, check out the revised diff below. I've tested the updated amd64 > part; I would appreciate a confirmation from an i386 w/X11 user for that > part.
Works for me, X runs and test program no longer drops us into ddb: OpenBSD 4.8-current (GENERIC) #43: Mon Dec 27 13:08:01 PST 2010 jo...@flint.joshe.fake:/usr/src/sys/arch/i386/compile/GENERIC cpu0: Intel(R) Celeron(R) M processor 1.40GHz ("GenuineIntel" 686-class) 1.40 GHz cpu0: FPU,V86,DE,PSE,TSC,MSR,PAE,MCE,CX8,SEP,MTRR,PGE,MCA,CMOV,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,TM,SBF It couldn't hurt to also test this on a machine where the fxsave instruction writes an empty mask. This should be any machine with SSE is in the cpu flags list and without SSE2. ok joshe@ > Index: amd64/amd64/fpu.c > =================================================================== > RCS file: /cvs/src/sys/arch/amd64/amd64/fpu.c,v > retrieving revision 1.21 > diff -u -p -r1.21 fpu.c > --- amd64/amd64/fpu.c 29 Sep 2010 15:11:31 -0000 1.21 > +++ amd64/amd64/fpu.c 27 Dec 2010 20:05:56 -0000 > @@ -95,6 +95,8 @@ > void fpudna(struct cpu_info *); > static int x86fpflags_to_siginfo(u_int32_t); > > +uint32_t fpu_mxcsr_mask; > + > /* > * Init the FPU. > */ > @@ -103,6 +105,16 @@ fpuinit(struct cpu_info *ci) > { > lcr0(rcr0() & ~(CR0_EM|CR0_TS)); > fninit(); > + if (fpu_mxcsr_mask == 0) { > + struct fxsave64 fx __attribute__((aligned(16))); > + > + bzero(&fx, sizeof(fx)); > + fxsave(&fx); > + if (fx.fx_mxcsr_mask) > + fpu_mxcsr_mask = fx.fx_mxcsr_mask; > + else > + fpu_mxcsr_mask = __INITIAL_MXCSR_MASK__; > + } > lcr0(rcr0() | (CR0_TS)); > } > > Index: amd64/amd64/machdep.c > =================================================================== > RCS file: /cvs/src/sys/arch/amd64/amd64/machdep.c,v > retrieving revision 1.129 > diff -u -p -r1.129 machdep.c > --- amd64/amd64/machdep.c 22 Nov 2010 21:07:16 -0000 1.129 > +++ amd64/amd64/machdep.c 27 Dec 2010 20:05:56 -0000 > @@ -658,9 +658,11 @@ sys_sigreturn(struct proc *p, void *v, r > fpusave_proc(p, 0); > > if (ksc.sc_fpstate) { > - if ((error = copyin(ksc.sc_fpstate, > - &p->p_addr->u_pcb.pcb_savefpu.fp_fxsave, sizeof (struct > fxsave64)))) > + struct fxsave64 *fx = &p->p_addr->u_pcb.pcb_savefpu.fp_fxsave; > + > + if ((error = copyin(ksc.sc_fpstate, fx, sizeof(*fx)))) > return (error); > + fx->fx_mxcsr &= fpu_mxcsr_mask; > p->p_md.md_flags |= MDP_USEDFPU; > } > > @@ -1506,6 +1508,7 @@ init_x86_64(paddr_t first_avail) > cpu_init_idt(); > > intr_default_setup(); > + fpuinit(&cpu_info_primary); > > softintr_init(); > splraise(IPL_IPI); > Index: amd64/amd64/process_machdep.c > =================================================================== > RCS file: /cvs/src/sys/arch/amd64/amd64/process_machdep.c,v > retrieving revision 1.9 > diff -u -p -r1.9 process_machdep.c > --- amd64/amd64/process_machdep.c 29 Sep 2010 15:11:31 -0000 1.9 > +++ amd64/amd64/process_machdep.c 27 Dec 2010 20:05:56 -0000 > @@ -137,7 +137,7 @@ process_read_fpregs(struct proc *p, stru > frame->fx_fsw = 0x0000; > frame->fx_ftw = 0xff; > frame->fx_mxcsr = __INITIAL_MXCSR__; > - frame->fx_mxcsr_mask = __INITIAL_MXCSR_MASK__; > + frame->fx_mxcsr_mask = fpu_mxcsr_mask; > p->p_md.md_flags |= MDP_USEDFPU; > } > > @@ -198,6 +198,7 @@ process_write_fpregs(struct proc *p, str > } > > memcpy(frame, ®s->fxstate, sizeof(*regs)); > + frame->fx_mxcsr &= fpu_mxcsr_mask; > return (0); > } > > Index: amd64/include/fpu.h > =================================================================== > RCS file: /cvs/src/sys/arch/amd64/include/fpu.h,v > retrieving revision 1.7 > diff -u -p -r1.7 fpu.h > --- amd64/include/fpu.h 20 Nov 2010 20:11:17 -0000 1.7 > +++ amd64/include/fpu.h 27 Dec 2010 20:05:56 -0000 > @@ -49,6 +49,8 @@ struct savefpu { > struct trapframe; > struct cpu_info; > > +extern uint32_t fpu_mxcsr_mask; > + > void fpuinit(struct cpu_info *); > void fpudrop(void); > void fpudiscard(struct proc *); > Index: i386/i386/machdep.c > =================================================================== > RCS file: /cvs/src/sys/arch/i386/i386/machdep.c,v > retrieving revision 1.485 > diff -u -p -r1.485 machdep.c > --- i386/i386/machdep.c 2 Oct 2010 23:31:34 -0000 1.485 > +++ i386/i386/machdep.c 27 Dec 2010 20:05:57 -0000 > @@ -2362,9 +2362,12 @@ sys_sigreturn(struct proc *p, void *v, r > npxsave_proc(p, 0); > > if (context.sc_fpstate) { > - if ((error = copyin(context.sc_fpstate, > - &p->p_addr->u_pcb.pcb_savefpu, sizeof (union savefpu)))) > + union savefpu *sfp = &p->p_addr->u_pcb.pcb_savefpu; > + > + if ((error = copyin(context.sc_fpstate, sfp, sizeof(*sfp)))) > return (error); > + if (i386_use_fxsave) > + sfp->sv_xmm.sv_env.en_mxcsr &= fpu_mxcsr_mask; > p->p_md.md_flags |= MDP_USEDFPU; > } > > Index: i386/i386/process_machdep.c > =================================================================== > RCS file: /cvs/src/sys/arch/i386/i386/process_machdep.c,v > retrieving revision 1.26 > diff -u -p -r1.26 process_machdep.c > --- i386/i386/process_machdep.c 27 Dec 2010 12:48:35 -0000 1.26 > +++ i386/i386/process_machdep.c 27 Dec 2010 20:05:57 -0000 > @@ -137,6 +137,7 @@ process_fninit_xmm(struct savexmm *sxmm) > memset(sxmm, 0, sizeof(*sxmm)); > sxmm->sv_env.en_cw = __OpenBSD_NPXCW__; > sxmm->sv_env.en_mxcsr = __INITIAL_MXCSR__; > + sxmm->sv_env.en_mxcsr_mask = fpu_mxcsr_mask; > sxmm->sv_env.en_sw = 0x0000; > sxmm->sv_env.en_tw = 0x00; > } > @@ -359,6 +360,7 @@ process_write_xmmregs(struct proc *p, co > p->p_md.md_flags |= MDP_USEDFPU; > > memcpy(&frame->sv_xmm, regs, sizeof(*regs)); > + frame->sv_xmm.sv_env.en_mxcsr &= fpu_mxcsr_mask; > return (0); > } > > Index: i386/include/npx.h > =================================================================== > RCS file: /cvs/src/sys/arch/i386/include/npx.h,v > retrieving revision 1.15 > diff -u -p -r1.15 npx.h > --- i386/include/npx.h 29 Sep 2010 15:11:31 -0000 1.15 > +++ i386/include/npx.h 27 Dec 2010 20:05:58 -0000 > @@ -96,7 +96,7 @@ struct envxmm { > uint16_t en_fos; /* FPU Data pointer selector */ > uint16_t en_rsvd2; > uint32_t en_mxcsr; /* MXCSR Register State */ > - uint32_t en_rsvd3; > + uint32_t en_mxcsr_mask; /* Mask for valid MXCSR bits (may be 0) */ > }; > > /* FPU regsters in the extended save format. */ > @@ -142,6 +142,7 @@ struct emcsts { > * Set Reference, pg. 3-369. > */ > #define __INITIAL_MXCSR__ 0x1f80 > +#define __INITIAL_MXCSR_MASK__ 0xffbf > > /* > * The standard control word from finit is 0x37F, giving: > @@ -157,6 +158,8 @@ void process_s87_to_xmm(const struct > > struct cpu_info; > struct trapframe; > + > +extern unsigned int fpu_mxcsr_mask; > > void npxinit(struct cpu_info *); > void npxtrap(struct trapframe *); > Index: i386/isa/npx.c > =================================================================== > RCS file: /cvs/src/sys/arch/i386/isa/npx.c,v > retrieving revision 1.53 > diff -u -p -r1.53 npx.c > --- i386/isa/npx.c 29 Sep 2010 15:11:31 -0000 1.53 > +++ i386/isa/npx.c 27 Dec 2010 20:05:58 -0000 > @@ -97,6 +97,11 @@ > #define clts() __asm("clts") > #define stts() lcr0(rcr0() | CR0_TS) > > +/* > + * The mxcsr_mask for this host, taken from fxsave() on the primary CPU > + */ > +unsigned int fpu_mxcsr_mask; > + > int npxintr(void *); > static int npxprobe1(struct isa_attach_args *); > static int x86fpflags_to_siginfo(u_int32_t); > @@ -350,6 +355,16 @@ npxinit(struct cpu_info *ci) > i386_fpu_fdivbug = 1; > printf("%s: WARNING: Pentium FDIV bug detected!\n", > ci->ci_dev.dv_xname); > + } > + if (fpu_mxcsr_mask == 0 && i386_use_fxsave) { > + struct savexmm xm __attribute__((aligned(16))); > + > + bzero(&xm, sizeof(xm)); > + fxsave(&xm); > + if (xm.sv_env.en_mxcsr_mask) > + fpu_mxcsr_mask = xm.sv_env.en_mxcsr_mask; > + else > + fpu_mxcsr_mask = __INITIAL_MXCSR_MASK__; > } > lcr0(rcr0() | (CR0_TS)); > }