arch/x86: fpu_state->fpu_state_ia32.xsave hast to be 64-byte aligned

Submitted by Andrei Vagin on Sept. 14, 2019, 7:26 a.m.

Details

Message ID 20190914072622.16725-1-avagin@gmail.com
State New
Series "arch/x86: fpu_state->fpu_state_ia32.xsave hast to be 64-byte aligned"
Headers show

Commit Message

Andrei Vagin Sept. 14, 2019, 7:26 a.m.
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>
---
 compel/arch/x86/src/lib/include/uapi/asm/fpu.h | 8 ++++++--
 criu/arch/x86/sigframe.c                       | 6 ++++++
 2 files changed, 12 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

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;

Comments

Cyrill Gorcunov Sept. 16, 2019, 4:01 p.m.
Acked-by: Cyrill Gorcunov <gorcunov@gmail.com>

Thanks a lot!
Dmitry Safonov Sept. 16, 2019, 4:55 p.m.
On Sat, 14 Sep 2019 at 08:27, Andrei Vagin <avagin@gmail.com> wrote:
>
> 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>

Reviewed-by: Dmitry Safonov <0x7f454c46@gmail.com>

Thanks,
             Dmitry