Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
30e52506
Commit
30e52506
authored
Sep 02, 2020
by
Paul Gofman
Committed by
Alexandre Julliard
Sep 02, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Implement saving AVX registers in NtGetContextThread().
Signed-off-by:
Paul Gofman
<
pgofman@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
1c2b14a5
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
113 additions
and
4 deletions
+113
-4
signal_i386.c
dlls/ntdll/unix/signal_i386.c
+56
-2
signal_x86_64.c
dlls/ntdll/unix/signal_x86_64.c
+57
-2
No files found.
dlls/ntdll/unix/signal_i386.c
View file @
30e52506
...
...
@@ -684,6 +684,56 @@ static inline void save_fpux( CONTEXT *context )
/***********************************************************************
* save_xstate
*
* Save the XState context
*/
static
inline
NTSTATUS
save_xstate
(
CONTEXT
*
context
)
{
CONTEXT_EX
*
context_ex
=
(
CONTEXT_EX
*
)(
context
+
1
);
DECLSPEC_ALIGN
(
64
)
struct
{
XSAVE_FORMAT
xsave
;
XSTATE
xstate
;
}
xsave_area
;
XSTATE
*
xs
;
if
(
!
(
user_shared_data
->
XState
.
EnabledFeatures
&&
(
xs
=
xstate_from_context
(
context
))))
return
STATUS_SUCCESS
;
if
(
context_ex
->
XState
.
Length
<
offsetof
(
XSTATE
,
YmmContext
)
||
context_ex
->
XState
.
Length
>
sizeof
(
XSTATE
))
return
STATUS_INVALID_PARAMETER
;
if
(
user_shared_data
->
XState
.
CompactionEnabled
)
{
/* xsavec doesn't use anything from the save area. */
__asm__
volatile
(
"xsavec %0"
:
"=m"
(
xsave_area
)
:
"a"
((
unsigned
int
)(
xs
->
CompactionMask
&
(
1
<<
XSTATE_AVX
))),
"d"
(
0
)
);
}
else
{
/* xsave preserves those bits in the mask which are not in EDX:EAX, so zero it. */
xsave_area
.
xstate
.
Mask
=
xsave_area
.
xstate
.
CompactionMask
=
0
;
__asm__
volatile
(
"xsave %0"
:
"=m"
(
xsave_area
)
:
"a"
((
unsigned
int
)(
xs
->
Mask
&
(
1
<<
XSTATE_AVX
))),
"d"
(
0
)
);
}
memcpy
(
xs
,
&
xsave_area
.
xstate
,
offsetof
(
XSTATE
,
YmmContext
));
if
(
xs
->
Mask
&
(
1
<<
XSTATE_AVX
))
{
if
(
context_ex
->
XState
.
Length
<
sizeof
(
XSTATE
))
return
STATUS_BUFFER_OVERFLOW
;
memcpy
(
&
xs
->
YmmContext
,
&
xsave_area
.
xstate
.
YmmContext
,
sizeof
(
xs
->
YmmContext
));
}
return
STATUS_SUCCESS
;
}
/***********************************************************************
* restore_fpu
*
* Restore the x87 FPU context
...
...
@@ -1189,11 +1239,15 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
*/
NTSTATUS
WINAPI
NtGetContextThread
(
HANDLE
handle
,
CONTEXT
*
context
)
{
NTSTATUS
ret
;
NTSTATUS
ret
,
xsave_status
;
struct
syscall_frame
*
frame
=
x86_thread_data
()
->
syscall_frame
;
DWORD
needed_flags
=
context
->
ContextFlags
&
~
CONTEXT_i386
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
/* Save xstate before any calls which can potentially change volatile ymm registers.
* E. g., debug output will clobber ymm registers. */
xsave_status
=
self
?
save_xstate
(
context
)
:
STATUS_SUCCESS
;
/* FIXME: other thread. */
/* debug registers require a server call */
if
(
needed_flags
&
CONTEXT_DEBUG_REGISTERS
)
self
=
FALSE
;
...
...
@@ -1265,7 +1319,7 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
TRACE
(
"%p: dr0=%08x dr1=%08x dr2=%08x dr3=%08x dr6=%08x dr7=%08x
\n
"
,
handle
,
context
->
Dr0
,
context
->
Dr1
,
context
->
Dr2
,
context
->
Dr3
,
context
->
Dr6
,
context
->
Dr7
);
return
STATUS_SUCCESS
;
return
xsave_status
;
}
...
...
dlls/ntdll/unix/signal_x86_64.c
View file @
30e52506
...
...
@@ -1474,6 +1474,56 @@ static void save_context( struct xcontext *xcontext, const ucontext_t *sigcontex
/***********************************************************************
* save_xstate
*
* Save the XState context
*/
static
inline
NTSTATUS
save_xstate
(
CONTEXT
*
context
)
{
CONTEXT_EX
*
context_ex
=
(
CONTEXT_EX
*
)(
context
+
1
);
DECLSPEC_ALIGN
(
64
)
struct
{
XSAVE_FORMAT
xsave
;
XSTATE
xstate
;
}
xsave_area
;
XSTATE
*
xs
;
if
(
!
(
user_shared_data
->
XState
.
EnabledFeatures
&&
(
xs
=
xstate_from_context
(
context
))))
return
STATUS_SUCCESS
;
if
(
context_ex
->
XState
.
Length
<
offsetof
(
XSTATE
,
YmmContext
)
||
context_ex
->
XState
.
Length
>
sizeof
(
XSTATE
))
return
STATUS_INVALID_PARAMETER
;
if
(
user_shared_data
->
XState
.
CompactionEnabled
)
{
/* xsavec doesn't use anything from the save area. */
__asm__
volatile
(
"xsavec %0"
:
"=m"
(
xsave_area
)
:
"a"
((
unsigned
int
)(
xs
->
CompactionMask
&
(
1
<<
XSTATE_AVX
))),
"d"
(
0
)
);
}
else
{
/* xsave preserves those bits in the mask which are not in EDX:EAX, so zero it. */
xsave_area
.
xstate
.
Mask
=
xsave_area
.
xstate
.
CompactionMask
=
0
;
__asm__
volatile
(
"xsave %0"
:
"=m"
(
xsave_area
)
:
"a"
((
unsigned
int
)(
xs
->
Mask
&
(
1
<<
XSTATE_AVX
))),
"d"
(
0
)
);
}
memcpy
(
xs
,
&
xsave_area
.
xstate
,
offsetof
(
XSTATE
,
YmmContext
));
if
(
xs
->
Mask
&
(
1
<<
XSTATE_AVX
))
{
if
(
context_ex
->
XState
.
Length
<
sizeof
(
XSTATE
))
return
STATUS_BUFFER_OVERFLOW
;
memcpy
(
&
xs
->
YmmContext
,
&
xsave_area
.
xstate
.
YmmContext
,
sizeof
(
xs
->
YmmContext
));
}
return
STATUS_SUCCESS
;
}
/***********************************************************************
* restore_context
*
* Build a sigcontext from the register values.
...
...
@@ -1772,13 +1822,17 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
*/
NTSTATUS
WINAPI
NtGetContextThread
(
HANDLE
handle
,
CONTEXT
*
context
)
{
NTSTATUS
ret
;
NTSTATUS
ret
,
xsave_status
;
DWORD
needed_flags
;
struct
syscall_frame
*
frame
=
amd64_thread_data
()
->
syscall_frame
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
if
(
!
context
)
return
STATUS_INVALID_PARAMETER
;
/* Save xstate before any calls which can potentially change volatile ymm registers.
* E. g., debug output will clobber ymm registers. */
xsave_status
=
self
?
save_xstate
(
context
)
:
STATUS_SUCCESS
;
/* FIXME: other thread. */
needed_flags
=
context
->
ContextFlags
&
~
CONTEXT_AMD64
;
/* debug registers require a server call */
...
...
@@ -1851,7 +1905,8 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
amd64_thread_data
()
->
dr7
=
context
->
Dr7
;
}
}
return
STATUS_SUCCESS
;
return
xsave_status
;
}
extern
void
CDECL
raise_func_trampoline
(
void
*
dispatcher
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment