diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2018-05-10 15:01:43 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2018-05-10 15:01:43 +0000 |
commit | 8b4fc8b11ca93e4e9929a26733c7a14579a4a0e9 (patch) | |
tree | 140cffeed4ff2ad42dbe6c0cf318f166e5f4f9e8 /sys | |
parent | 4072ae4e0291f97a2cc69fa4151988a99b06090c (diff) | |
download | src-8b4fc8b11ca93e4e9929a26733c7a14579a4a0e9.tar.gz src-8b4fc8b11ca93e4e9929a26733c7a14579a4a0e9.zip |
Make fpusave() and fpurestore() on amd64 ifuncs.
From now on, linking amd64 kernel requires either lld or newer ld.bfd.
Reviewed by: jhb (as part of the large patch)
Discussed with: emaste
Sponsored by: The FreeBSD Foundation
Differential revision: https://reviews.freebsd.org/D13838
Notes
Notes:
svn path=/head/; revision=333461
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/amd64/fpu.c | 62 |
1 files changed, 46 insertions, 16 deletions
diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c index c3b254ef5ab9..5abd82f665df 100644 --- a/sys/amd64/amd64/fpu.c +++ b/sys/amd64/amd64/fpu.c @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include <machine/specialreg.h> #include <machine/segments.h> #include <machine/ucontext.h> +#include <x86/ifunc.h> /* * Floating point support. @@ -151,24 +152,58 @@ struct xsave_area_elm_descr { u_int size; } *xsave_area_desc; -void -fpusave(void *addr) +static void +fpusave_xsave(void *addr) { - if (use_xsave) - xsave((char *)addr, xsave_mask); - else - fxsave((char *)addr); + xsave((char *)addr, xsave_mask); } -void -fpurestore(void *addr) +static void +fpurestore_xrstor(void *addr) +{ + + xrstor((char *)addr, xsave_mask); +} + +static void +fpusave_fxsave(void *addr) +{ + + fxsave((char *)addr); +} + +static void +fpurestore_fxrstor(void *addr) +{ + + fxrstor((char *)addr); +} + +static void +init_xsave(void) { if (use_xsave) - xrstor((char *)addr, xsave_mask); - else - fxrstor((char *)addr); + return; + if ((cpu_feature2 & CPUID2_XSAVE) == 0) + return; + use_xsave = 1; + TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave); +} + +DEFINE_IFUNC(, void, fpusave, (void *), static) +{ + + init_xsave(); + return (use_xsave ? fpusave_xsave : fpusave_fxsave); +} + +DEFINE_IFUNC(, void, fpurestore, (void *), static) +{ + + init_xsave(); + return (use_xsave ? fpurestore_xrstor : fpurestore_fxrstor); } void @@ -207,13 +242,8 @@ fpuinit_bsp1(void) uint64_t xsave_mask_user; bool old_wp; - if ((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) |