Convert i386 NPX hardware context save methods to ifuncs.

Since ifunc-capable linker is now required on i386, bring this code in
line with the amd64 counterpart.

Reviewed by:	alc, markj
Sponsored by:	The FreeBSD Foundation
Approved by:	re (gjb)
Differential revision:	https://reviews.freebsd.org/D16736
This commit is contained in:
kib 2018-09-19 16:37:43 +00:00
parent e4a8d038e7
commit 25624e135c

View File

@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$");
#include <machine/specialreg.h>
#include <machine/segments.h>
#include <machine/ucontext.h>
#include <x86/ifunc.h>
#include <machine/intr_machdep.h>
@ -183,7 +184,6 @@ CTASSERT(X86_XSTATE_XCR0_OFFSET >= offsetof(struct savexmm, sv_pad) &&
static void fpu_clean_state(void);
static void fpusave(union savefpu *);
static void fpurstor(union savefpu *);
int hw_float;
@ -206,8 +206,6 @@ struct xsave_area_elm_descr {
u_int size;
} *xsave_area_desc;
static int use_xsaveopt;
static volatile u_int npx_traps_while_probing;
alias_for_inthand_t probetrap;
@ -314,6 +312,69 @@ npx_probe(void)
return (hw_float);
}
static void
npxsave_xsaveopt(union savefpu *addr)
{
xsaveopt((char *)addr, xsave_mask);
}
static void
fpusave_xsave(union savefpu *addr)
{
xsave((char *)addr, xsave_mask);
}
static void
fpusave_fxsave(union savefpu *addr)
{
fxsave((char *)addr);
}
static void
fpusave_fnsave(union savefpu *addr)
{
fnsave((char *)addr);
}
static void
init_xsave(void)
{
if (use_xsave)
return;
if (!cpu_fxsr || (cpu_feature2 & CPUID2_XSAVE) == 0)
return;
use_xsave = 1;
TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave);
}
DEFINE_IFUNC(, void, npxsave_core, (union savefpu *), static)
{
init_xsave();
if (use_xsave)
return ((cpu_stdext_feature & CPUID_EXTSTATE_XSAVEOPT) != 0 ?
npxsave_xsaveopt : fpusave_xsave);
if (cpu_fxsr)
return (fpusave_fxsave);
return (fpusave_fnsave);
}
DEFINE_IFUNC(, void, fpusave, (union savefpu *), static)
{
init_xsave();
if (use_xsave)
return (fpusave_xsave);
if (cpu_fxsr)
return (fpusave_fxsave);
return (fpusave_fnsave);
}
/*
* Enable XSAVE if supported and allowed by user.
* Calculate the xsave_mask.
@ -325,13 +386,8 @@ npxinit_bsp1(void)
uint64_t xsave_mask_user;
TUNABLE_INT_FETCH("hw.lazy_fpu_switch", &lazy_fpu_switch);
if (cpu_fxsr && (cpu_feature2 & CPUID2_XSAVE) != 0) {
use_xsave = 1;
TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave);
}
if (!use_xsave)
return;
cpuid_count(0xd, 0x0, cp);
xsave_mask = XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE;
if ((cp[0] & xsave_mask) != xsave_mask)
@ -345,14 +401,9 @@ npxinit_bsp1(void)
xsave_mask &= ~XFEATURE_AVX512;
if ((xsave_mask & XFEATURE_MPX) != XFEATURE_MPX)
xsave_mask &= ~XFEATURE_MPX;
cpuid_count(0xd, 0x1, cp);
if ((cp[0] & CPUID_EXTSTATE_XSAVEOPT) != 0)
use_xsaveopt = 1;
}
/*
* Calculate the fpu save area size.
*/
static void
@ -867,15 +918,11 @@ npxdna(void)
* npxsave() atomically with checking fpcurthread.
*/
void
npxsave(addr)
union savefpu *addr;
npxsave(union savefpu *addr)
{
stop_emulating();
if (use_xsaveopt)
xsaveopt((char *)addr, xsave_mask);
else
fpusave(addr);
npxsave_core(addr);
}
void npxswitch(struct thread *td, struct pcb *pcb);
@ -1099,19 +1146,6 @@ npxsetregs(struct thread *td, union savefpu *addr, char *xfpustate,
return (error);
}
static void
fpusave(addr)
union savefpu *addr;
{
if (use_xsave)
xsave((char *)addr, xsave_mask);
else if (cpu_fxsr)
fxsave(addr);
else
fnsave(addr);
}
static void
npx_fill_fpregs_xmm1(struct savexmm *sv_xmm, struct save87 *sv_87)
{