From 2c3d3d2d729a445db52e908ad8fdc44f80337cc0 Mon Sep 17 00:00:00 2001 From: jhb Date: Mon, 3 Nov 2014 19:16:25 +0000 Subject: [PATCH] Move all of the XSAVE support under #ifdef I686_CPU and fix the build without I686_CPU. --- sys/i386/i386/machdep.c | 16 ++++++++++++++++ sys/i386/i386/vm_machdep.c | 12 ++++++++++++ sys/i386/isa/npx.c | 37 ++++++++++++++++++++++++++++++++++--- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 2fd9110528d7..c3af9f62a705 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -670,10 +670,14 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) regs = td->td_frame; oonstack = sigonstack(regs->tf_esp); +#ifdef CPU_ENABLE_SSE if (cpu_max_ext_state_size > sizeof(union savefpu) && use_xsave) { xfpusave_len = cpu_max_ext_state_size - sizeof(union savefpu); xfpusave = __builtin_alloca(xfpusave_len); } else { +#else + { +#endif xfpusave_len = 0; xfpusave = NULL; } @@ -2908,7 +2912,9 @@ init386(first) unsigned long gdtmachpfn; int error, gsel_tss, metadata_missing, x, pa; struct pcpu *pc; +#ifdef CPU_ENABLE_SSE struct xstate_hdr *xhdr; +#endif struct callback_register event = { .type = CALLBACKTYPE_event, .address = {GSEL(GCODE_SEL, SEL_KPL), (unsigned long)Xhypervisor_callback }, @@ -3117,11 +3123,13 @@ init386(first) */ thread0.td_pcb = get_pcb_td(&thread0); bzero(get_pcb_user_save_td(&thread0), cpu_max_ext_state_size); +#ifdef CPU_ENABLE_SSE if (use_xsave) { xhdr = (struct xstate_hdr *)(get_pcb_user_save_td(&thread0) + 1); xhdr->xstate_bv = xsave_mask; } +#endif PCPU_SET(curpcb, thread0.td_pcb); /* make an initial tss so cpu can get interrupt stack on syscall! */ /* Note: -16 is so we can grow the trapframe if we came from vm86 */ @@ -3162,7 +3170,9 @@ init386(first) struct gate_descriptor *gdp; int gsel_tss, metadata_missing, x, pa; struct pcpu *pc; +#ifdef CPU_ENABLE_SSE struct xstate_hdr *xhdr; +#endif thread0.td_kstack = proc0kstack; thread0.td_kstack_pages = KSTACK_PAGES; @@ -3417,11 +3427,13 @@ init386(first) */ thread0.td_pcb = get_pcb_td(&thread0); bzero(get_pcb_user_save_td(&thread0), cpu_max_ext_state_size); +#ifdef CPU_ENABLE_SSE if (use_xsave) { xhdr = (struct xstate_hdr *)(get_pcb_user_save_td(&thread0) + 1); xhdr->xstate_bv = xsave_mask; } +#endif PCPU_SET(curpcb, thread0.td_pcb); /* make an initial tss so cpu can get interrupt stack on syscall! */ /* Note: -16 is so we can grow the trapframe if we came from vm86 */ @@ -3886,7 +3898,9 @@ static void get_fpcontext(struct thread *td, mcontext_t *mcp, char *xfpusave, size_t xfpusave_len) { +#ifdef CPU_ENABLE_SSE size_t max_len, len; +#endif #ifndef DEV_NPX mcp->mc_fpformat = _MC_FPFMT_NODEV; @@ -3897,6 +3911,7 @@ get_fpcontext(struct thread *td, mcontext_t *mcp, char *xfpusave, bcopy(get_pcb_user_save_td(td), &mcp->mc_fpstate[0], sizeof(mcp->mc_fpstate)); mcp->mc_fpformat = npxformat(); +#ifdef CPU_ENABLE_SSE if (!use_xsave || xfpusave_len == 0) return; max_len = cpu_max_ext_state_size - sizeof(union savefpu); @@ -3909,6 +3924,7 @@ get_fpcontext(struct thread *td, mcontext_t *mcp, char *xfpusave, mcp->mc_xfpustate_len = len; bcopy(get_pcb_user_save_td(td) + 1, xfpusave, len); #endif +#endif } static int diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c index 45151263fbb3..ebd177a529e7 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -106,6 +106,10 @@ __FBSDID("$FreeBSD$"); #define NSFBUFS (512 + maxusers * 16) #endif +#if !defined(CPU_DISABLE_SSE) && defined(I686_CPU) +#define CPU_ENABLE_SSE +#endif + _Static_assert(OFFSETOF_CURTHREAD == offsetof(struct pcpu, pc_curthread), "OFFSETOF_CURTHREAD does not correspond with offset of pc_curthread."); _Static_assert(OFFSETOF_CURPCB == offsetof(struct pcpu, pc_curpcb), @@ -152,14 +156,18 @@ void * alloc_fpusave(int flags) { void *res; +#ifdef CPU_ENABLE_SSE struct savefpu_ymm *sf; +#endif res = malloc(cpu_max_ext_state_size, M_DEVBUF, flags); +#ifdef CPU_ENABLE_SSE if (use_xsave) { sf = (struct savefpu_ymm *)res; bzero(&sf->sv_xstate.sx_hd, sizeof(sf->sv_xstate.sx_hd)); sf->sv_xstate.sx_hd.xstate_bv = xsave_mask; } +#endif return (res); } /* @@ -398,17 +406,21 @@ void cpu_thread_alloc(struct thread *td) { struct pcb *pcb; +#ifdef CPU_ENABLE_SSE struct xstate_hdr *xhdr; +#endif td->td_pcb = pcb = get_pcb_td(td); td->td_frame = (struct trapframe *)((caddr_t)pcb - 16) - 1; pcb->pcb_ext = NULL; pcb->pcb_save = get_pcb_user_save_pcb(pcb); +#ifdef CPU_ENABLE_SSE if (use_xsave) { xhdr = (struct xstate_hdr *)(pcb->pcb_save + 1); bzero(xhdr, sizeof(*xhdr)); xhdr->xstate_bv = xsave_mask; } +#endif } void diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c index 099319df6dc8..0034f2d674dd 100644 --- a/sys/i386/isa/npx.c +++ b/sys/i386/isa/npx.c @@ -212,17 +212,21 @@ int hw_float; SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD, &hw_float, 0, "Floating point instructions executed in hardware"); +#ifdef CPU_ENABLE_SSE int use_xsave; uint64_t xsave_mask; +#endif static uma_zone_t fpu_save_area_zone; static union savefpu *npx_initialstate; +#ifdef CPU_ENABLE_SSE struct xsave_area_elm_descr { u_int offset; u_int size; } *xsave_area_desc; static int use_xsaveopt; +#endif static volatile u_int npx_traps_while_probing; @@ -338,6 +342,7 @@ npx_probe(void) return (hw_float); } +#ifdef CPU_ENABLE_SSE /* * Enable XSAVE if supported and allowed by user. * Calculate the xsave_mask. @@ -373,13 +378,15 @@ npxinit_bsp1(void) if ((cp[0] & CPUID_EXTSTATE_XSAVEOPT) != 0) use_xsaveopt = 1; } - +#endif /* + * Calculate the fpu save area size. */ static void npxinit_bsp2(void) { +#ifdef CPU_ENABLE_SSE u_int cp[4]; if (use_xsave) { @@ -392,6 +399,7 @@ npxinit_bsp2(void) do_cpuid(1, cp); cpu_feature2 = cp[2]; } else +#endif cpu_max_ext_state_size = sizeof(union savefpu); } @@ -403,19 +411,25 @@ npxinit(bool bsp) { static union savefpu dummy; register_t saveintr; +#ifdef CPU_ENABLE_SSE u_int mxcsr; +#endif u_short control; if (bsp) { if (!npx_probe()) return; +#ifdef CPU_ENABLE_SSE npxinit_bsp1(); +#endif } +#ifdef CPU_ENABLE_SSE if (use_xsave) { load_cr4(rcr4() | CR4_XSAVE); load_xcr(XCR0, xsave_mask); } +#endif /* * XCR0 shall be set up before CPU can report the save area size. @@ -459,7 +473,9 @@ static void npxinitstate(void *arg __unused) { register_t saveintr; +#ifdef CPU_ENABLE_SSE int cp[4], i, max_ext_n; +#endif if (!hw_float) return; @@ -495,6 +511,7 @@ npxinitstate(void *arg __unused) bzero(npx_initialstate->sv_87.sv_ac, sizeof(npx_initialstate->sv_87.sv_ac)); +#ifdef CPU_ENABLE_SSE /* * Create a table describing the layout of the CPU Extended * Save Area. @@ -519,6 +536,7 @@ npxinitstate(void *arg __unused) xsave_area_desc[i].size = cp[0]; } } +#endif fpu_save_area_zone = uma_zcreate("FPU_save_area", cpu_max_ext_state_size, NULL, NULL, NULL, NULL, @@ -897,9 +915,11 @@ npxsave(addr) { stop_emulating(); +#ifdef CPU_ENABLE_SSE if (use_xsaveopt) xsaveopt((char *)addr, xsave_mask); else +#endif fpusave(addr); start_emulating(); PCPU_SET(fpcurthread, NULL); @@ -972,9 +992,12 @@ int npxgetregs(struct thread *td) { struct pcb *pcb; +#ifdef CPU_ENABLE_SSE uint64_t *xstate_bv, bit; char *sa; - int max_ext_n, i, owned; + int max_ext_n, i; +#endif + int owned; if (!hw_float) return (_MC_FPOWNED_NONE); @@ -1004,6 +1027,7 @@ npxgetregs(struct thread *td) owned = _MC_FPOWNED_PCB; } critical_exit(); +#ifdef CPU_ENABLE_SSE if (use_xsave) { /* * Handle partially saved state. @@ -1026,6 +1050,7 @@ npxgetregs(struct thread *td) *xstate_bv |= bit; } } +#endif return (owned); } @@ -1040,6 +1065,7 @@ npxuserinited(struct thread *td) pcb->pcb_flags |= PCB_NPXUSERINITDONE; } +#ifdef CPU_ENABLE_SSE int npxsetxstate(struct thread *td, char *xfpustate, size_t xfpustate_size) { @@ -1077,13 +1103,16 @@ npxsetxstate(struct thread *td, char *xfpustate, size_t xfpustate_size) return (0); } +#endif int npxsetregs(struct thread *td, union savefpu *addr, char *xfpustate, size_t xfpustate_size) { struct pcb *pcb; +#ifdef CPU_ENABLE_SSE int error; +#endif if (!hw_float) return (ENXIO); @@ -1091,12 +1120,12 @@ npxsetregs(struct thread *td, union savefpu *addr, char *xfpustate, pcb = td->td_pcb; critical_enter(); if (td == PCPU_GET(fpcurthread) && PCB_USER_FPU(pcb)) { +#ifdef CPU_ENABLE_SSE error = npxsetxstate(td, xfpustate, xfpustate_size); if (error != 0) { critical_exit(); return (error); } -#ifdef CPU_ENABLE_SSE if (!cpu_fxsr) #endif fnclex(); /* As in npxdrop(). */ @@ -1106,9 +1135,11 @@ npxsetregs(struct thread *td, union savefpu *addr, char *xfpustate, pcb->pcb_flags |= PCB_NPXUSERINITDONE | PCB_NPXINITDONE; } else { critical_exit(); +#ifdef CPU_ENABLE_SSE error = npxsetxstate(td, xfpustate, xfpustate_size); if (error != 0) return (error); +#endif bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr)); npxuserinited(td); }