aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2018-05-10 15:01:43 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2018-05-10 15:01:43 +0000
commit8b4fc8b11ca93e4e9929a26733c7a14579a4a0e9 (patch)
tree140cffeed4ff2ad42dbe6c0cf318f166e5f4f9e8 /sys
parent4072ae4e0291f97a2cc69fa4151988a99b06090c (diff)
downloadsrc-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.c62
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)