Signed-off-by: Paul Gofman pgofman@codeweavers.com --- 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 cf704093fce..1bbf9f4f912 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -5600,7 +5600,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); } @@ -5611,7 +5611,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 370f1f36fd7..53b9d98e80c 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1543,6 +1543,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("xor %%edx,%%edx; mov $4,%%eax; xrstor64 %0" : : "m"(*xrstor_base) : "eax", "edx"); +} + /*********************************************************************** * get_server_context_flags * @@ -1733,6 +1761,8 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) } }
+ restore_xstate( context ); + if (flags & CONTEXT_FULL) { if (!(flags & CONTEXT_CONTROL))