[CRIU] [PATCH 25/44] cr-dump.c: moved the routine get_task_regs() to the file arch/x86/crtools.c.
Alexander Kartashov
alekskartashov at parallels.com
Mon Jan 7 10:04:54 EST 2013
Signed-off-by: Alexander Kartashov <alekskartashov at parallels.com>
---
arch/x86/crtools.c | 127 ++++++++++++++++++++++++++++++++++++++++++
arch/x86/include/asm/dump.h | 6 ++
cr-dump.c | 128 +------------------------------------------
3 files changed, 134 insertions(+), 127 deletions(-)
create mode 100644 arch/x86/include/asm/dump.h
diff --git a/arch/x86/crtools.c b/arch/x86/crtools.c
index c630ac3..be35aa8 100644
--- a/arch/x86/crtools.c
+++ b/arch/x86/crtools.c
@@ -73,3 +73,130 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
*ret = regs.ax;
return 0;
}
+
+int get_task_regs(pid_t pid, CoreEntry *core, const struct parasite_ctl *ctl)
+{
+ struct xsave_struct xsave = { };
+ user_regs_struct_t regs = {-1};
+
+ struct iovec iov;
+ int ret = -1;
+
+ pr_info("Dumping GP/FPU registers ... ");
+
+ if (ctl)
+ regs = ctl->regs_orig;
+ else {
+ if (ptrace(PTRACE_GETREGS, pid, NULL, ®s)) {
+ pr_err("Can't obtain GP registers for %d\n", pid);
+ goto err;
+ }
+ }
+
+ /* Did we come from a system call? */
+ if ((int)regs.orig_ax >= 0) {
+ /* Restart the system call */
+ switch ((long)(int)regs.ax) {
+ case -ERESTARTNOHAND:
+ case -ERESTARTSYS:
+ case -ERESTARTNOINTR:
+ regs.ax = regs.orig_ax;
+ regs.ip -= 2;
+ break;
+ case -ERESTART_RESTARTBLOCK:
+ regs.ax = __NR_restart_syscall;
+ regs.ip -= 2;
+ break;
+ }
+ }
+
+#define assign_reg(dst, src, e) do { dst->e = (__typeof__(dst->e))src.e; } while (0)
+#define assign_array(dst, src, e) memcpy(dst->e, &src.e, sizeof(src.e))
+
+ assign_reg(core->thread_info->gpregs, regs, r15);
+ assign_reg(core->thread_info->gpregs, regs, r14);
+ assign_reg(core->thread_info->gpregs, regs, r13);
+ assign_reg(core->thread_info->gpregs, regs, r12);
+ assign_reg(core->thread_info->gpregs, regs, bp);
+ assign_reg(core->thread_info->gpregs, regs, bx);
+ assign_reg(core->thread_info->gpregs, regs, r11);
+ assign_reg(core->thread_info->gpregs, regs, r10);
+ assign_reg(core->thread_info->gpregs, regs, r9);
+ assign_reg(core->thread_info->gpregs, regs, r8);
+ assign_reg(core->thread_info->gpregs, regs, ax);
+ assign_reg(core->thread_info->gpregs, regs, cx);
+ assign_reg(core->thread_info->gpregs, regs, dx);
+ assign_reg(core->thread_info->gpregs, regs, si);
+ assign_reg(core->thread_info->gpregs, regs, di);
+ assign_reg(core->thread_info->gpregs, regs, orig_ax);
+ assign_reg(core->thread_info->gpregs, regs, ip);
+ assign_reg(core->thread_info->gpregs, regs, cs);
+ assign_reg(core->thread_info->gpregs, regs, flags);
+ assign_reg(core->thread_info->gpregs, regs, sp);
+ assign_reg(core->thread_info->gpregs, regs, ss);
+ assign_reg(core->thread_info->gpregs, regs, fs_base);
+ assign_reg(core->thread_info->gpregs, regs, gs_base);
+ assign_reg(core->thread_info->gpregs, regs, ds);
+ assign_reg(core->thread_info->gpregs, regs, es);
+ assign_reg(core->thread_info->gpregs, regs, fs);
+ assign_reg(core->thread_info->gpregs, regs, gs);
+
+#ifndef PTRACE_GETREGSET
+# define PTRACE_GETREGSET 0x4204
+#endif
+
+ if (!cpu_has_feature(X86_FEATURE_FPU))
+ goto out;
+
+ /*
+ * FPU fetched either via fxsave or via xsave,
+ * thus decode it accrodingly.
+ */
+
+ if (cpu_has_feature(X86_FEATURE_XSAVE)) {
+ iov.iov_base = &xsave;
+ iov.iov_len = sizeof(xsave);
+
+ if (ptrace(PTRACE_GETREGSET, pid, (unsigned int)NT_X86_XSTATE, &iov) < 0) {
+ pr_err("Can't obtain FPU registers for %d\n", pid);
+ goto err;
+ }
+ } else {
+ if (ptrace(PTRACE_GETFPREGS, pid, NULL, &xsave)) {
+ pr_err("Can't obtain FPU registers for %d\n", pid);
+ goto err;
+ }
+ }
+
+ assign_reg(core->thread_info->fpregs, xsave.i387, cwd);
+ assign_reg(core->thread_info->fpregs, xsave.i387, swd);
+ assign_reg(core->thread_info->fpregs, xsave.i387, twd);
+ assign_reg(core->thread_info->fpregs, xsave.i387, fop);
+ assign_reg(core->thread_info->fpregs, xsave.i387, rip);
+ assign_reg(core->thread_info->fpregs, xsave.i387, rdp);
+ assign_reg(core->thread_info->fpregs, xsave.i387, mxcsr);
+ assign_reg(core->thread_info->fpregs, xsave.i387, mxcsr_mask);
+
+ /* Make sure we have enough space */
+ BUG_ON(core->thread_info->fpregs->n_st_space != ARRAY_SIZE(xsave.i387.st_space));
+ BUG_ON(core->thread_info->fpregs->n_xmm_space != ARRAY_SIZE(xsave.i387.xmm_space));
+
+ assign_array(core->thread_info->fpregs, xsave.i387, st_space);
+ assign_array(core->thread_info->fpregs, xsave.i387, xmm_space);
+
+ if (cpu_has_feature(X86_FEATURE_XSAVE)) {
+ BUG_ON(core->thread_info->fpregs->xsave->n_ymmh_space != ARRAY_SIZE(xsave.ymmh.ymmh_space));
+
+ assign_reg(core->thread_info->fpregs->xsave, xsave.xsave_hdr, xstate_bv);
+ assign_array(core->thread_info->fpregs->xsave, xsave.ymmh, ymmh_space);
+ }
+
+#undef assign_reg
+#undef assign_array
+
+out:
+ ret = 0;
+
+err:
+ return ret;
+}
diff --git a/arch/x86/include/asm/dump.h b/arch/x86/include/asm/dump.h
new file mode 100644
index 0000000..fb86f50
--- /dev/null
+++ b/arch/x86/include/asm/dump.h
@@ -0,0 +1,6 @@
+#ifndef __CR_ASM_DUMP_H__
+#define __CR_ASM_DUMP_H__
+
+extern int get_task_regs(pid_t pid, CoreEntry *core, const struct parasite_ctl *ctl);
+
+#endif
diff --git a/cr-dump.c b/cr-dump.c
index d69bddb..9a288d0 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -64,6 +64,7 @@
#include "fpu.h"
#include "elf.h"
+#include "asm/dump.h"
static char loc_buf[PAGE_SIZE];
static int pidns_proc = -1;
@@ -646,133 +647,6 @@ err:
return ret;
}
-static int get_task_regs(pid_t pid, CoreEntry *core, const struct parasite_ctl *ctl)
-{
- struct xsave_struct xsave = { };
- user_regs_struct_t regs = {-1};
-
- struct iovec iov;
- int ret = -1;
-
- pr_info("Dumping GP/FPU registers ... ");
-
- if (ctl)
- regs = ctl->regs_orig;
- else {
- if (ptrace(PTRACE_GETREGS, pid, NULL, ®s)) {
- pr_err("Can't obtain GP registers for %d\n", pid);
- goto err;
- }
- }
-
- /* Did we come from a system call? */
- if ((int)regs.orig_ax >= 0) {
- /* Restart the system call */
- switch ((long)(int)regs.ax) {
- case -ERESTARTNOHAND:
- case -ERESTARTSYS:
- case -ERESTARTNOINTR:
- regs.ax = regs.orig_ax;
- regs.ip -= 2;
- break;
- case -ERESTART_RESTARTBLOCK:
- regs.ax = __NR_restart_syscall;
- regs.ip -= 2;
- break;
- }
- }
-
-#define assign_reg(dst, src, e) do { dst->e = (__typeof__(dst->e))src.e; } while (0)
-#define assign_array(dst, src, e) memcpy(dst->e, &src.e, sizeof(src.e))
-
- assign_reg(core->thread_info->gpregs, regs, r15);
- assign_reg(core->thread_info->gpregs, regs, r14);
- assign_reg(core->thread_info->gpregs, regs, r13);
- assign_reg(core->thread_info->gpregs, regs, r12);
- assign_reg(core->thread_info->gpregs, regs, bp);
- assign_reg(core->thread_info->gpregs, regs, bx);
- assign_reg(core->thread_info->gpregs, regs, r11);
- assign_reg(core->thread_info->gpregs, regs, r10);
- assign_reg(core->thread_info->gpregs, regs, r9);
- assign_reg(core->thread_info->gpregs, regs, r8);
- assign_reg(core->thread_info->gpregs, regs, ax);
- assign_reg(core->thread_info->gpregs, regs, cx);
- assign_reg(core->thread_info->gpregs, regs, dx);
- assign_reg(core->thread_info->gpregs, regs, si);
- assign_reg(core->thread_info->gpregs, regs, di);
- assign_reg(core->thread_info->gpregs, regs, orig_ax);
- assign_reg(core->thread_info->gpregs, regs, ip);
- assign_reg(core->thread_info->gpregs, regs, cs);
- assign_reg(core->thread_info->gpregs, regs, flags);
- assign_reg(core->thread_info->gpregs, regs, sp);
- assign_reg(core->thread_info->gpregs, regs, ss);
- assign_reg(core->thread_info->gpregs, regs, fs_base);
- assign_reg(core->thread_info->gpregs, regs, gs_base);
- assign_reg(core->thread_info->gpregs, regs, ds);
- assign_reg(core->thread_info->gpregs, regs, es);
- assign_reg(core->thread_info->gpregs, regs, fs);
- assign_reg(core->thread_info->gpregs, regs, gs);
-
-#ifndef PTRACE_GETREGSET
-# define PTRACE_GETREGSET 0x4204
-#endif
-
- if (!cpu_has_feature(X86_FEATURE_FPU))
- goto out;
-
- /*
- * FPU fetched either via fxsave or via xsave,
- * thus decode it accrodingly.
- */
-
- if (cpu_has_feature(X86_FEATURE_XSAVE)) {
- iov.iov_base = &xsave;
- iov.iov_len = sizeof(xsave);
-
- if (ptrace(PTRACE_GETREGSET, pid, (unsigned int)NT_X86_XSTATE, &iov) < 0) {
- pr_err("Can't obtain FPU registers for %d\n", pid);
- goto err;
- }
- } else {
- if (ptrace(PTRACE_GETFPREGS, pid, NULL, &xsave)) {
- pr_err("Can't obtain FPU registers for %d\n", pid);
- goto err;
- }
- }
-
- assign_reg(core->thread_info->fpregs, xsave.i387, cwd);
- assign_reg(core->thread_info->fpregs, xsave.i387, swd);
- assign_reg(core->thread_info->fpregs, xsave.i387, twd);
- assign_reg(core->thread_info->fpregs, xsave.i387, fop);
- assign_reg(core->thread_info->fpregs, xsave.i387, rip);
- assign_reg(core->thread_info->fpregs, xsave.i387, rdp);
- assign_reg(core->thread_info->fpregs, xsave.i387, mxcsr);
- assign_reg(core->thread_info->fpregs, xsave.i387, mxcsr_mask);
-
- /* Make sure we have enough space */
- BUG_ON(core->thread_info->fpregs->n_st_space != ARRAY_SIZE(xsave.i387.st_space));
- BUG_ON(core->thread_info->fpregs->n_xmm_space != ARRAY_SIZE(xsave.i387.xmm_space));
-
- assign_array(core->thread_info->fpregs, xsave.i387, st_space);
- assign_array(core->thread_info->fpregs, xsave.i387, xmm_space);
-
- if (cpu_has_feature(X86_FEATURE_XSAVE)) {
- BUG_ON(core->thread_info->fpregs->xsave->n_ymmh_space != ARRAY_SIZE(xsave.ymmh.ymmh_space));
-
- assign_reg(core->thread_info->fpregs->xsave, xsave.xsave_hdr, xstate_bv);
- assign_array(core->thread_info->fpregs->xsave, xsave.ymmh, ymmh_space);
- }
-
-#undef assign_reg
-#undef assign_array
-
-out:
- ret = 0;
-
-err:
- return ret;
-}
-
static DECLARE_KCMP_TREE(vm_tree, KCMP_VM);
static DECLARE_KCMP_TREE(fs_tree, KCMP_FS);
static DECLARE_KCMP_TREE(files_tree, KCMP_FILES);
--
1.7.10.4
More information about the CRIU
mailing list