[CRIU] [PATCH 5/6] compel: Extend FPU structures to support ia32 mode
Cyrill Gorcunov
gorcunov at openvz.org
Mon Feb 13 07:03:22 PST 2017
Because it touches base types need to update criu
code accordingly.
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
compel/arch/x86/src/lib/include/uapi/asm/fpu.h | 37 +++++++++++++++++++++++---
compel/arch/x86/src/lib/infect.c | 12 ++++++---
criu/arch/x86/crtools.c | 8 ++++--
criu/arch/x86/sigframe.c | 6 ++---
4 files changed, 50 insertions(+), 13 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 d3245f256924..ee6e81bcd9d8 100644
--- a/compel/arch/x86/src/lib/include/uapi/asm/fpu.h
+++ b/compel/arch/x86/src/lib/include/uapi/asm/fpu.h
@@ -88,14 +88,43 @@ struct xsave_struct {
* This one is used in restorer.
*/
typedef struct {
- /*
- * The FPU xsave area must be continious and FP_MIN_ALIGN_BYTES
- * aligned, thus make sure the compiler won't insert any hole here.
- */
+ union {
+ struct xsave_struct xsave;
+ uint8_t __pad[sizeof(struct xsave_struct) + FP_XSTATE_MAGIC2_SIZE];
+ };
+} fpu_state_64_t;
+
+struct user_i387_ia32_struct {
+ uint32_t cwd; /* FPU Control Word */
+ uint32_t swd; /* FPU Status Word */
+ uint32_t twd; /* FPU Tag Word */
+ uint32_t fip; /* FPU IP Offset */
+ uint32_t fcs; /* FPU IP Selector */
+ uint32_t foo; /* FPU Operand Pointer Offset */
+ uint32_t fos; /* FPU Operand Pointer Selector */
+ uint32_t st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
+} __packed;
+
+typedef struct {
+ struct {
+ struct user_i387_ia32_struct i387_ia32;
+ /* Software status information [not touched by FSAVE]: */
+ uint32_t status;
+ } __packed fregs_state;
union {
struct xsave_struct xsave;
uint8_t __pad[sizeof(struct xsave_struct) + FP_XSTATE_MAGIC2_SIZE];
+ } __packed;
+} __packed fpu_state_ia32_t;
+
+/*
+ * This one is used in restorer.
+ */
+typedef struct {
+ union {
+ fpu_state_64_t fpu_state_64;
+ fpu_state_ia32_t fpu_state_ia32;
};
uint8_t has_fpu;
diff --git a/compel/arch/x86/src/lib/infect.c b/compel/arch/x86/src/lib/infect.c
index d5b4f7659c65..43b080000fe3 100644
--- a/compel/arch/x86/src/lib/infect.c
+++ b/compel/arch/x86/src/lib/infect.c
@@ -102,7 +102,11 @@ int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
}
fpu_state->has_fpu = true;
- memcpy(&fpu_state->xsave, fpregs, sizeof(*fpregs));
+ if (is_native) {
+ memcpy(&fpu_state->fpu_state_64.xsave, fpregs, sizeof(*fpregs));
+ } else {
+ memcpy(&fpu_state->fpu_state_ia32.xsave, fpregs, sizeof(*fpregs));
+ }
return 0;
}
@@ -113,12 +117,12 @@ int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe,
fpu_state_t *fpu_state = (sigframe->is_native) ?
&rsigframe->native.fpu_state :
&rsigframe->compat.fpu_state;
- unsigned long addr = (unsigned long)(void *)&fpu_state->xsave;
if (sigframe->is_native)
- sigframe->native.uc.uc_mcontext.fpstate = &fpu_state->xsave;
+ sigframe->native.uc.uc_mcontext.fpstate = &fpu_state->fpu_state_64.xsave;
else if (!sigframe->is_native)
- sigframe->compat.uc.uc_mcontext.fpstate = (uint32_t)addr;
+ sigframe->compat.uc.uc_mcontext.fpstate =
+ (uint32_t)(long)(void *)&fpu_state->fpu_state_ia32;
return 0;
}
diff --git a/criu/arch/x86/crtools.c b/criu/arch/x86/crtools.c
index 33f4048704ff..0986055d53fa 100644
--- a/criu/arch/x86/crtools.c
+++ b/criu/arch/x86/crtools.c
@@ -303,7 +303,9 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
fpu_state_t *fpu_state = core_is_compat(core) ?
&sigframe->compat.fpu_state :
&sigframe->native.fpu_state;
- struct xsave_struct *x = &fpu_state->xsave;
+ struct xsave_struct *x = core_is_compat(core) ?
+ &fpu_state->fpu_state_ia32.xsave :
+ &fpu_state->fpu_state_64.xsave;
/*
* If no FPU information provided -- we're restoring
@@ -356,7 +358,9 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
/*
* This should be at the end of xsave frame.
*/
- magic2 = fpu_state->__pad + sizeof(struct xsave_struct);
+ magic2 = (core_is_compat(core) ?
+ fpu_state->fpu_state_ia32.__pad :
+ fpu_state->fpu_state_64.__pad) + sizeof(struct xsave_struct);
*(u32 *)magic2 = FP_XSTATE_MAGIC2;
}
diff --git a/criu/arch/x86/sigframe.c b/criu/arch/x86/sigframe.c
index 24afb863f0b5..efe33c4c0512 100644
--- a/criu/arch/x86/sigframe.c
+++ b/criu/arch/x86/sigframe.c
@@ -16,12 +16,12 @@ int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
fpu_state_t *fpu_state = (sigframe->is_native) ?
&rsigframe->native.fpu_state :
&rsigframe->compat.fpu_state;
- unsigned long addr = (unsigned long)(void *)&fpu_state->xsave;
if (sigframe->is_native)
- sigframe->native.uc.uc_mcontext.fpstate = &fpu_state->xsave;
+ sigframe->native.uc.uc_mcontext.fpstate = &fpu_state->fpu_state_64.xsave;
else if (!sigframe->is_native)
- sigframe->compat.uc.uc_mcontext.fpstate = (uint32_t)addr;
+ sigframe->compat.uc.uc_mcontext.fpstate =
+ (uint32_t)(long)(void *)&fpu_state->fpu_state_ia32;
return 0;
}
--
2.7.4
More information about the CRIU
mailing list