mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 22:35:33 +00:00
Fill FPU init state if it's not provided by kernel.
Apparently Skylake uses init-optimization when saving FPU state, and ptrace() returns XSTATE_BV[0] = 0 meaning FPU was not used by a task (in init state). Since CRIU restore uses sigreturn to restore registers, FPU state is always restored. Fill the state with default values on dump to make restore happy. Signed-off-by: Michał Mirosław <emmir@google.com>
This commit is contained in:
committed by
Andrei Vagin
parent
c75c017e4c
commit
c6ee1ba05e
@@ -220,6 +220,16 @@ int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe, struct rt_sigfr
|
|||||||
#define get_signed_user_reg(pregs, name) \
|
#define get_signed_user_reg(pregs, name) \
|
||||||
((user_regs_native(pregs)) ? (int64_t)((pregs)->native.name) : (int32_t)((pregs)->compat.name))
|
((user_regs_native(pregs)) ? (int64_t)((pregs)->native.name) : (int32_t)((pregs)->compat.name))
|
||||||
|
|
||||||
|
static int get_task_fpregs(pid_t pid, user_fpregs_struct_t *xsave)
|
||||||
|
{
|
||||||
|
if (ptrace(PTRACE_GETFPREGS, pid, NULL, xsave)) {
|
||||||
|
pr_perror("Can't obtain FPU registers for %d", pid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int get_task_xsave(pid_t pid, user_fpregs_struct_t *xsave)
|
static int get_task_xsave(pid_t pid, user_fpregs_struct_t *xsave)
|
||||||
{
|
{
|
||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
@@ -232,14 +242,15 @@ static int get_task_xsave(pid_t pid, user_fpregs_struct_t *xsave)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
if ((xsave->xsave_hdr.xstate_bv & 3) != 3) {
|
||||||
}
|
// Due to init-optimisation [1] x87 FPU or SSE state may not be filled in.
|
||||||
|
// Since those are restored unconditionally, make sure the init values are
|
||||||
static int get_task_fpregs(pid_t pid, user_fpregs_struct_t *xsave)
|
// filled by retrying with old PTRACE_GETFPREGS.
|
||||||
{
|
//
|
||||||
if (ptrace(PTRACE_GETFPREGS, pid, NULL, xsave)) {
|
// [1] Intel® 64 and IA-32 Architectures Software Developer's
|
||||||
pr_perror("Can't obtain FPU registers for %d", pid);
|
// Manual Volume 1: Basic Architecture
|
||||||
return -1;
|
// Section 13.6: Processor tracking of XSAVE-managed state
|
||||||
|
return get_task_fpregs(pid, xsave);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user