tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[PATCH] Issue 64-bit (REX.W=1) versions of *XSAVE* on amd64



When calling FXSAVE, XSAVE, FXRSTOR, ... on amd64 use the "64"-suffixed
variant in order to prefix the operand with REX.W=1.  This causes them
to use the FXSAVE64 variant of x87 area that includes complete FIP/FDP
registers.

The difference between the two variants is that the FXSAVE64 (new)
variant represents FIP/FDP as 64-bit fields (union fp_addr.fa_64),
while the legacy FXSAVE variant uses split fields: 32-bit offset,
16-bit segment and 16-bit reserved field (union fp_addr.fa_32).
The latter implies that the actual addresses are truncated to 32 bits
which is insufficient in modern programs.

This is a potentially breaking change.  However, I don't think it likely
to actually break anything because the data provided by the old variant
were not meaningful (because of the truncated pointer).
---
 sys/arch/x86/include/cpufunc.h | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/sys/arch/x86/include/cpufunc.h b/sys/arch/x86/include/cpufunc.h
index 38534c305544..e0ea1e3210b8 100644
--- a/sys/arch/x86/include/cpufunc.h
+++ b/sys/arch/x86/include/cpufunc.h
@@ -411,13 +411,19 @@ frstor(const void *addr)
 	);
 }
 
+#ifdef __x86_64__
+#define XSAVE_SUFFIX "64"
+#else
+#define XSAVE_SUFFIX
+#endif
+
 static inline void
 fxsave(void *addr)
 {
 	uint8_t *area = addr;
 
 	__asm volatile (
-		"fxsave	%[area]"
+		"fxsave" XSAVE_SUFFIX "	%[area]"
 		: [area] "=m" (*area)
 		:
 		: "memory"
@@ -430,7 +436,7 @@ fxrstor(const void *addr)
 	const uint8_t *area = addr;
 
 	__asm volatile (
-		"fxrstor %[area]"
+		"fxrstor" XSAVE_SUFFIX " %[area]"
 		:
 		: [area] "m" (*area)
 		: "memory"
@@ -446,7 +452,7 @@ xsave(void *addr, uint64_t mask)
 	low = mask;
 	high = mask >> 32;
 	__asm volatile (
-		"xsave	%[area]"
+		"xsave" XSAVE_SUFFIX "	%[area]"
 		: [area] "=m" (*area)
 		: "a" (low), "d" (high)
 		: "memory"
@@ -462,7 +468,7 @@ xsaveopt(void *addr, uint64_t mask)
 	low = mask;
 	high = mask >> 32;
 	__asm volatile (
-		"xsaveopt %[area]"
+		"xsaveopt" XSAVE_SUFFIX " %[area]"
 		: [area] "=m" (*area)
 		: "a" (low), "d" (high)
 		: "memory"
@@ -478,7 +484,7 @@ xrstor(const void *addr, uint64_t mask)
 	low = mask;
 	high = mask >> 32;
 	__asm volatile (
-		"xrstor %[area]"
+		"xrstor" XSAVE_SUFFIX " %[area]"
 		:
 		: [area] "m" (*area), "a" (low), "d" (high)
 		: "memory"
-- 
2.28.0



Home | Main Index | Thread Index | Old Index