Move all of the XSAVE support under #ifdef I686_CPU and fix the build

without I686_CPU.
This commit is contained in:
jhb 2014-11-03 19:16:25 +00:00
parent 361372e423
commit 2c3d3d2d72
3 changed files with 62 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

@ -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);
}