ntdll: Use syscall dispatcher for restoring context in x86_64 NtSetContextThread implementation.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2021-02-22 18:04:16 +01:00 committed by Alexandre Julliard
parent bdf4b3b400
commit 437bef6ac1
7 changed files with 70 additions and 9 deletions

View File

@ -726,7 +726,10 @@ NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable )
status = server_select( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, 0, NULL, NULL, &apc );
if (status == STATUS_USER_APC) invoke_apc( context, &apc );
}
return NtSetContextThread( GetCurrentThread(), context );
status = NtSetContextThread( GetCurrentThread(), context );
if (!status && (context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
signal_restore_full_cpu_context();
return status;
}

View File

@ -332,6 +332,16 @@ __ASM_GLOBAL_FUNC( set_cpu_context,
"pop {pc}" )
/***********************************************************************
* signal_restore_full_cpu_context
*
* Restore full context from syscall frame
*/
void signal_restore_full_cpu_context(void)
{
}
/***********************************************************************
* get_server_context_flags
*

View File

@ -406,6 +406,16 @@ static void restore_fpu( CONTEXT *context, ucontext_t *sigcontext )
}
/***********************************************************************
* signal_restore_full_cpu_context
*
* Restore full context from syscall frame
*/
void signal_restore_full_cpu_context(void)
{
}
/***********************************************************************
* get_server_context_flags
*

View File

@ -807,6 +807,17 @@ static inline void restore_xstate( const CONTEXT *context )
__asm__ volatile( "xrstor %0" : : "m"(*xrstor_base), "a" (4), "d" (0) );
}
/***********************************************************************
* signal_restore_full_cpu_context
*
* Restore full context from syscall frame
*/
void signal_restore_full_cpu_context(void)
{
}
/***********************************************************************
* fpux_to_fpu
*

View File

@ -1591,7 +1591,12 @@ __ASM_GLOBAL_FUNC( set_full_cpu_context,
"leaq 0x70(%rsp),%rsp\n\t"
"iretq" )
static void signal_restore_full_cpu_context(void)
/***********************************************************************
* signal_restore_full_cpu_context
*
* Restore full context from syscall frame
*/
void signal_restore_full_cpu_context(void)
{
struct syscall_xsave *xsave = get_syscall_xsave( get_syscall_frame() );
SYSTEM_CPU_INFORMATION cpu_info;
@ -1863,9 +1868,6 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
else if (xs->CompactionMask & XSTATE_MASK_GSSE)
xsave->xstate.Mask &= ~XSTATE_MASK_GSSE;
}
if (!(flags & CONTEXT_INTEGER)) frame->rax = STATUS_SUCCESS;
signal_restore_full_cpu_context();
return STATUS_SUCCESS;
}
@ -2614,11 +2616,24 @@ static void quit_handler( int signal, siginfo_t *siginfo, void *ucontext )
*/
static void usr1_handler( int signal, siginfo_t *siginfo, void *ucontext )
{
struct syscall_frame *frame = amd64_thread_data()->syscall_frame;
struct xcontext context;
if (frame)
{
DECLSPEC_ALIGN(64) XSTATE xs;
context.c.ContextFlags = CONTEXT_FULL;
context_init_xstate( &context.c, &xs );
save_context( &context, ucontext );
wait_suspend( &context.c );
restore_context( &context, ucontext );
NtGetContextThread( GetCurrentThread(), &context.c );
wait_suspend( &context.c );
NtSetContextThread( GetCurrentThread(), &context.c );
}
else
{
save_context( &context, ucontext );
wait_suspend( &context.c );
restore_context( &context, ucontext );
}
}

View File

@ -214,6 +214,7 @@ extern void DECLSPEC_NORETURN signal_start_thread( PRTL_THREAD_START_ROUTINE ent
extern void DECLSPEC_NORETURN signal_exit_thread( int status, void (*func)(int) ) DECLSPEC_HIDDEN;
extern void DECLSPEC_NORETURN exec_process( NTSTATUS status ) DECLSPEC_HIDDEN;
extern void __wine_syscall_dispatcher(void) DECLSPEC_HIDDEN;
extern void signal_restore_full_cpu_context(void) DECLSPEC_HIDDEN;
extern void fill_vm_counters( VM_COUNTERS_EX *pvmi, int unix_pid ) DECLSPEC_HIDDEN;
extern NTSTATUS cdrom_DeviceIoControl( HANDLE device, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user,

View File

@ -1559,7 +1559,18 @@ static void output_syscall_dispatcher( int count, const char *variant )
output( "\tcallq *(%%r10,%%r11,8)\n" );
output( "2:\tmovq %%gs:0x30,%%rcx\n" );
output( "\tmovq $0,0x328(%%rcx)\n" );
output( "\tfxrstor64 (%%r12)\n" );
if (!*variant)
{
output( "\tfxrstor64 (%%r12)\n" );
}
else
{
output( "\tmovq %%rax,%%r11\n" );
output( "\tmovl $7,%%eax\n" );
output( "\txorq %%rdx,%%rdx\n" );
output( "\txrstor64 (%%r12)\n" );
output( "\tmovq %%r11,%%rax\n" );
}
output( "\tmovq -0x30(%%rbp),%%r15\n" );
output( "\tmovq -0x38(%%rbp),%%r14\n" );
output( "\tmovq -0x40(%%rbp),%%r13\n" );