Move all of the XSAVE support under #ifdef I686_CPU and fix the build
without I686_CPU.
This commit is contained in:
parent
361372e423
commit
2c3d3d2d72
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user