diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 93183794bf6..4deeec37abb 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1542,7 +1542,8 @@ static inline void init_handler( const ucontext_t *sigcontext ) static inline void leave_handler( const ucontext_t *sigcontext ) { #ifdef __linux__ - if (fs32_sel) __asm__ volatile( "movw %0,%%fs" :: "r" (fs32_sel) ); + if (fs32_sel && !is_inside_signal_stack( (void *)RSP_sig(sigcontext ))) + __asm__ volatile( "movw %0,%%fs" :: "r" (fs32_sel) ); #endif } @@ -1997,7 +1998,7 @@ NTSTATUS set_thread_wow64_context( HANDLE handle, const void *ctx, ULONG size ) memcpy( &frame->xstate.YmmContext, &xs->YmmContext, sizeof(xs->YmmContext) ); } else frame->xstate.Mask &= ~XSTATE_MASK_GSSE; - frame->restore_flags |= CONTEXT_I386_XSTATE; + frame->restore_flags |= CONTEXT_XSTATE; } return STATUS_SUCCESS; } diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index e7320dbc1af..3bb763a5eda 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -318,6 +318,12 @@ static inline void *get_signal_stack(void) return (void *)(((ULONG_PTR)NtCurrentTeb() & ~signal_stack_mask) + teb_size); } +static inline BOOL is_inside_signal_stack( void *ptr ) +{ + return ((char *)ptr >= (char *)get_signal_stack() && + (char *)ptr < (char *)get_signal_stack() + signal_stack_size); +} + static inline void mutex_lock( pthread_mutex_t *mutex ) { if (!process_exiting) pthread_mutex_lock( mutex ); diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 1838e9d9791..8976cb88f90 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -237,12 +237,6 @@ static struct range_entry *free_ranges; static struct range_entry *free_ranges_end; -static inline BOOL is_inside_signal_stack( void *ptr ) -{ - return ((char *)ptr >= (char *)get_signal_stack() && - (char *)ptr < (char *)get_signal_stack() + signal_stack_size); -} - static inline BOOL is_beyond_limit( const void *addr, size_t size, const void *limit ) { return (addr >= limit || (const char *)addr + size > (const char *)limit);