Commit 7ac2d79c authored by Adrian Reber's avatar Adrian Reber Committed by Pavel Emelyanov

xsave: check for X86_FEATURE_OSXSAVE rather than for X86_FEATURE_XSAVE

Migrating a process between a system with the 'xsave' CPU flag and
another system without the 'xsave' CPU flags is not possible and
fails during restore. To avoid this situation it is possible to boot
the source system of the migration with 'noxsave' kernel command-line.

Unfortunately criu currently tries to detect the presence of 'xsave'
with the macro X86_FEATURE_XSAVE which represents the features of
the CPU without taking into account if the operating system has
disabled 'xsave'. Checking for 'xsave' availability with the macro
X86_FEATURE_OSXSAVE detects correctly if Linux has been booted
with disabled 'xsave' and thus migrating processes between hosts
with and without 'xsave' is possible if the kernel uses the flag
'noxsave'.

travis-ci: success for criu dump fails when using noxsave (rev2)
Signed-off-by: 's avatarAdrian Reber <areber@redhat.com>
Reviewed-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 730d374a
...@@ -220,7 +220,7 @@ int cpu_init(void) ...@@ -220,7 +220,7 @@ int cpu_init(void)
pr_debug("fpu:%d fxsr:%d xsave:%d\n", pr_debug("fpu:%d fxsr:%d xsave:%d\n",
!!cpu_has_feature(X86_FEATURE_FPU), !!cpu_has_feature(X86_FEATURE_FPU),
!!cpu_has_feature(X86_FEATURE_FXSR), !!cpu_has_feature(X86_FEATURE_FXSR),
!!cpu_has_feature(X86_FEATURE_XSAVE)); !!cpu_has_feature(X86_FEATURE_OSXSAVE));
return 0; return 0;
} }
...@@ -394,7 +394,7 @@ static int cpu_validate_features(CpuinfoX86Entry *img_x86_entry) ...@@ -394,7 +394,7 @@ static int cpu_validate_features(CpuinfoX86Entry *img_x86_entry)
!cpu_has_feature(__bit)) !cpu_has_feature(__bit))
if (__mismatch_fpu_bit(X86_FEATURE_FPU) || if (__mismatch_fpu_bit(X86_FEATURE_FPU) ||
__mismatch_fpu_bit(X86_FEATURE_FXSR) || __mismatch_fpu_bit(X86_FEATURE_FXSR) ||
__mismatch_fpu_bit(X86_FEATURE_XSAVE)) { __mismatch_fpu_bit(X86_FEATURE_OSXSAVE)) {
pr_err("FPU feature required by image " pr_err("FPU feature required by image "
"is not supported on host.\n"); "is not supported on host.\n");
return -1; return -1;
......
...@@ -153,7 +153,7 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core) ...@@ -153,7 +153,7 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
* thus decode it accrodingly. * thus decode it accrodingly.
*/ */
if (cpu_has_feature(X86_FEATURE_XSAVE)) { if (cpu_has_feature(X86_FEATURE_OSXSAVE)) {
iov.iov_base = &xsave; iov.iov_base = &xsave;
iov.iov_len = sizeof(xsave); iov.iov_len = sizeof(xsave);
...@@ -230,7 +230,7 @@ static int save_task_regs(CoreEntry *core, ...@@ -230,7 +230,7 @@ static int save_task_regs(CoreEntry *core,
assign_array(core->thread_info->fpregs, &fpregs->i387, st_space); assign_array(core->thread_info->fpregs, &fpregs->i387, st_space);
assign_array(core->thread_info->fpregs, &fpregs->i387, xmm_space); assign_array(core->thread_info->fpregs, &fpregs->i387, xmm_space);
if (cpu_has_feature(X86_FEATURE_XSAVE)) { if (cpu_has_feature(X86_FEATURE_OSXSAVE)) {
BUG_ON(core->thread_info->fpregs->xsave->n_ymmh_space != ARRAY_SIZE(fpregs->ymmh.ymmh_space)); BUG_ON(core->thread_info->fpregs->xsave->n_ymmh_space != ARRAY_SIZE(fpregs->ymmh.ymmh_space));
assign_reg(core->thread_info->fpregs->xsave, &fpregs->xsave_hdr, xstate_bv); assign_reg(core->thread_info->fpregs->xsave, &fpregs->xsave_hdr, xstate_bv);
...@@ -256,7 +256,7 @@ int arch_alloc_thread_info(CoreEntry *core) ...@@ -256,7 +256,7 @@ int arch_alloc_thread_info(CoreEntry *core)
sz = sizeof(ThreadInfoX86) + sizeof(UserX86RegsEntry); sz = sizeof(ThreadInfoX86) + sizeof(UserX86RegsEntry);
if (with_fpu) { if (with_fpu) {
sz += sizeof(UserX86FpregsEntry); sz += sizeof(UserX86FpregsEntry);
with_xsave = cpu_has_feature(X86_FEATURE_XSAVE); with_xsave = cpu_has_feature(X86_FEATURE_OSXSAVE);
if (with_xsave) if (with_xsave)
sz += sizeof(UserX86XsaveEntry); sz += sizeof(UserX86XsaveEntry);
} }
...@@ -336,7 +336,7 @@ static bool valid_xsave_frame(CoreEntry *core) ...@@ -336,7 +336,7 @@ static bool valid_xsave_frame(CoreEntry *core)
return false; return false;
} }
if (cpu_has_feature(X86_FEATURE_XSAVE)) { if (cpu_has_feature(X86_FEATURE_OSXSAVE)) {
if (core->thread_info->fpregs->xsave && if (core->thread_info->fpregs->xsave &&
core->thread_info->fpregs->xsave->n_ymmh_space < ARRAY_SIZE(x->ymmh.ymmh_space)) { core->thread_info->fpregs->xsave->n_ymmh_space < ARRAY_SIZE(x->ymmh.ymmh_space)) {
pr_err("Corruption in FPU ymmh_space area " pr_err("Corruption in FPU ymmh_space area "
...@@ -348,7 +348,7 @@ static bool valid_xsave_frame(CoreEntry *core) ...@@ -348,7 +348,7 @@ static bool valid_xsave_frame(CoreEntry *core)
} else { } else {
/* /*
* If the image has xsave area present then CPU we're restoring * If the image has xsave area present then CPU we're restoring
* on must have X86_FEATURE_XSAVE feature until explicitly * on must have X86_FEATURE_OSXSAVE feature until explicitly
* stated in options. * stated in options.
*/ */
if (core->thread_info->fpregs->xsave) { if (core->thread_info->fpregs->xsave) {
...@@ -420,7 +420,7 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core) ...@@ -420,7 +420,7 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
assign_array(x->i387, core->thread_info->fpregs, st_space); assign_array(x->i387, core->thread_info->fpregs, st_space);
assign_array(x->i387, core->thread_info->fpregs, xmm_space); assign_array(x->i387, core->thread_info->fpregs, xmm_space);
if (cpu_has_feature(X86_FEATURE_XSAVE)) { if (cpu_has_feature(X86_FEATURE_OSXSAVE)) {
struct fpx_sw_bytes *fpx_sw = (void *)&x->i387.sw_reserved; struct fpx_sw_bytes *fpx_sw = (void *)&x->i387.sw_reserved;
void *magic2; void *magic2;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment