Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/checkpoint-restore/criu.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Vagin <avagin@gmail.com>2019-09-14 10:26:22 +0300
committerAndrei Vagin <avagin@gmail.com>2020-02-04 23:37:37 +0300
commit8bdc60d50e5b990aa8debd06785175da3e0ba34a (patch)
tree760cd3564e8dbaf7b24a2f13e33a717f438ee4ad
parent4f24786b36058ab82e669fd5686cc9f5cfc573db (diff)
arch/x86: fpu_state->fpu_state_ia32.xsave hast to be 64-byte aligned
Before the 5.2 kernel, only fpu_state->fpu_state_64.xsave has to be 64-byte aligned. But staring with the 5.2 kernel, the same is required for pu_state->fpu_state_ia32.xsave. The behavior was changed in: c2ff9e9a3d9d ("x86/fpu: Merge the two code paths in __fpu__restore_sig()") Signed-off-by: Andrei Vagin <avagin@gmail.com>
-rw-r--r--compel/arch/x86/src/lib/include/uapi/asm/fpu.h8
-rw-r--r--criu/arch/x86/sigframe.c6
2 files changed, 12 insertions, 2 deletions
diff --git a/compel/arch/x86/src/lib/include/uapi/asm/fpu.h b/compel/arch/x86/src/lib/include/uapi/asm/fpu.h
index 509f4488b..4ff531fb9 100644
--- a/compel/arch/x86/src/lib/include/uapi/asm/fpu.h
+++ b/compel/arch/x86/src/lib/include/uapi/asm/fpu.h
@@ -263,7 +263,7 @@ struct xsave_struct_ia32 {
struct ymmh_struct ymmh;
uint8_t extended_state_area[EXTENDED_STATE_AREA_SIZE];
};
-} __aligned(FXSAVE_ALIGN_BYTES);
+};
typedef struct {
/*
@@ -309,7 +309,11 @@ typedef struct {
typedef struct {
union {
fpu_state_64_t fpu_state_64;
- fpu_state_ia32_t fpu_state_ia32;
+ struct {
+ /* fpu_state_ia32->xsave has to be 64-byte aligned. */
+ uint32_t __pad[2];
+ fpu_state_ia32_t fpu_state_ia32;
+ };
};
uint8_t has_fpu;
diff --git a/criu/arch/x86/sigframe.c b/criu/arch/x86/sigframe.c
index 11b0d640d..33ba14387 100644
--- a/criu/arch/x86/sigframe.c
+++ b/criu/arch/x86/sigframe.c
@@ -28,8 +28,14 @@ int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
sigframe->native.uc.uc_mcontext.fpstate = (uint64_t)addr;
} else if (!sigframe->is_native) {
+ unsigned long addr = (unsigned long)(void *)&fpu_state->fpu_state_ia32.xsave;
sigframe->compat.uc.uc_mcontext.fpstate =
(uint32_t)(unsigned long)(void *)&fpu_state->fpu_state_ia32;
+ if ((addr % 64ul)) {
+ pr_err("Unaligned address passed: %lx (native %d)\n",
+ addr, sigframe->is_native);
+ return -1;
+ }
}
return 0;