Paul Gofman : ntdll: Restore AVX registers in NtSetContextThread() on x86_64.
Alexandre Julliard
julliard at winehq.org
Fri Aug 21 16:43:26 CDT 2020
Module: wine
Branch: master
Commit: 2c3719c7a9b370461d18c4422dd965dda80cb859
URL: https://source.winehq.org/git/wine.git/?a=commit;h=2c3719c7a9b370461d18c4422dd965dda80cb859
Author: Paul Gofman <pgofman at codeweavers.com>
Date: Fri Aug 21 02:42:13 2020 +0300
ntdll: Restore AVX registers in NtSetContextThread() on x86_64.
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/tests/exception.c | 4 ++--
dlls/ntdll/unix/signal_x86_64.c | 30 ++++++++++++++++++++++++++++++
2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 041a5f258d..f92491bb34 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -5562,7 +5562,7 @@ static void test_extended_context(void)
for (i = 0; i < 8; ++i)
{
/* Older Windows version do not reset AVX context to INIT_STATE on x86. */
- todo_wine_if(i >= 4)
+ todo_wine_if(i >= 4 && sizeof(void *) == 4)
ok(!data[i] || broken(i >= 4 && sizeof(void *) == 4 && data[i] == test_extended_context_spoil_data2[i]),
"Got unexpected data %#x, i %u.\n", data[i], i);
}
@@ -5573,7 +5573,7 @@ static void test_extended_context(void)
ARRAY_SIZE(except_code_set_ymm0), PAGE_EXECUTE_READ);
for (i = 0; i < 8; ++i)
- todo_wine_if(i >= 4)
+ todo_wine_if(i >= 4 && sizeof(void *) == 4)
ok(data[i] == test_extended_context_data[i], "Got unexpected data %#x, i %u.\n", data[i], i);
}
#endif
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index a98dc8657d..7c13b4f7d2 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -1535,6 +1535,34 @@ __ASM_GLOBAL_FUNC( set_full_cpu_context,
"iretq" );
+/***********************************************************************
+ * restore_xstate
+ *
+ * Restore the XState context.
+ */
+static void restore_xstate( const CONTEXT *context )
+{
+ XSAVE_FORMAT *xrstor_base;
+ XSTATE *xs;
+
+ if (!(xs = xstate_from_context( context )))
+ return;
+
+ xrstor_base = (XSAVE_FORMAT *)xs - 1;
+
+ if (!(xs->CompactionMask & ((ULONG64)1 << 63)))
+ {
+ /* Non-compacted xrstor will load Mxcsr regardless of the specified mask. Loading garbage there
+ * may lead to fault. We have only padding, no more used EXCEPTION_RECORD or unused context fields
+ * at the MxCsr restore location, so just put it there. */
+ assert( (void *)&xrstor_base->MxCsr > (void *)context->VectorRegister );
+ xrstor_base->MxCsr = context->u.FltSave.MxCsr;
+ xrstor_base->MxCsr_Mask = context->u.FltSave.MxCsr_Mask;
+ }
+
+ __asm__ volatile( "xrstor64 %0" : : "m"(*xrstor_base), "a" (4), "d" (0) );
+}
+
/***********************************************************************
* get_server_context_flags
*
@@ -1725,6 +1753,8 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
}
}
+ restore_xstate( context );
+
if (flags & CONTEXT_FULL)
{
if (!(flags & CONTEXT_CONTROL))
More information about the wine-cvs
mailing list