[CRIU] [PATCH 09/20] cr-dump.c: introduced the multiarch support.
alekskartashov at parallels.com
alekskartashov at parallels.com
Wed Dec 12 08:34:19 EST 2012
From: Alexander Kartashov <alekskartashov at parallels.com>
* Implemented achitecture-specific versions of the following routines:
- get_task_regs,
- core_entry_free.
* Introduced the macro CORE_ENTRY__MARCH to rpresent the target architecture.
* Introduced the routine thread_core_entry__init to initialize an instance
of ThreadCoreEntry in a machine-dependent way.
* Introduced the macro CORE_THREAD_INFO to access the machine-specific
part of CoreEntry.
Signed-off-by: Alexander Kartashov <alekskartashov at parallels.com>
---
cr-dump.c | 197 +++++++++++--------------------------------------------------
1 file changed, 33 insertions(+), 164 deletions(-)
diff --git a/cr-dump.c b/cr-dump.c
index e8783db..e09dd62 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -61,9 +61,7 @@
#include "net.h"
#include "sk-packet.h"
-#ifndef CONFIG_X86_64
-# error No x86-32 support yet
-#endif
+#include <arch_cr_dump.h>
static char loc_buf[PAGE_SIZE];
static int pidns_proc = -1;
@@ -535,9 +533,6 @@ static int dump_task_creds(struct parasite_ctl *ctl, const struct cr_fdset *fds)
return pb_write_one(fdset_fd(fds, CR_FD_CREDS), &ce, PB_CREDS);
}
-#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))
-
static int get_task_auxv(pid_t pid, MmEntry *mm, size_t *size)
{
int fd, ret, i;
@@ -550,10 +545,10 @@ static int get_task_auxv(pid_t pid, MmEntry *mm, size_t *size)
for (i = 0; i < AT_VECTOR_SIZE; i++) {
ret = read(fd, &mm->mm_saved_auxv[i],
- sizeof(mm->mm_saved_auxv[0]));
+ sizeof(auxv_t));
if (ret == 0)
break;
- else if (ret != sizeof(mm->mm_saved_auxv[0])) {
+ else if (ret != sizeof(auxv_t)) {
ret = -1;
pr_perror("Error readind %d's auxv[%d]",
pid, i);
@@ -649,98 +644,6 @@ err:
return ret;
}
-static int get_task_regs(pid_t pid, CoreEntry *core, const struct parasite_ctl *ctl)
-{
- user_fpregs_struct_t fpregs = {-1};
- user_regs_struct_t regs = {-1};
-
- 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;
- }
- }
-
- if (ptrace(PTRACE_GETFPREGS, pid, NULL, &fpregs)) {
- pr_err("Can't obtain FPU 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;
- }
- }
-
- 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);
-
- assign_reg(core->thread_info->fpregs, fpregs, cwd);
- assign_reg(core->thread_info->fpregs, fpregs, swd);
- assign_reg(core->thread_info->fpregs, fpregs, twd);
- assign_reg(core->thread_info->fpregs, fpregs, fop);
- assign_reg(core->thread_info->fpregs, fpregs, rip);
- assign_reg(core->thread_info->fpregs, fpregs, rdp);
- assign_reg(core->thread_info->fpregs, fpregs, mxcsr);
- assign_reg(core->thread_info->fpregs, fpregs, mxcsr_mask);
-
- /* Make sure we have enough space */
- BUG_ON(core->thread_info->fpregs->n_st_space != ARRAY_SIZE(fpregs.st_space));
- BUG_ON(core->thread_info->fpregs->n_xmm_space != ARRAY_SIZE(fpregs.xmm_space));
- BUG_ON(core->thread_info->fpregs->n_padding != ARRAY_SIZE(fpregs.padding));
-
- assign_array(core->thread_info->fpregs, fpregs, st_space);
- assign_array(core->thread_info->fpregs, fpregs, xmm_space);
- assign_array(core->thread_info->fpregs, fpregs, padding);
-
- 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);
@@ -786,33 +689,11 @@ static int dump_task_kobj_ids(pid_t pid, CoreEntry *core)
return 0;
}
-static void core_entry_free(CoreEntry *core)
-{
- if (core) {
- if (core->thread_info) {
- if (core->thread_info->fpregs) {
- xfree(core->thread_info->fpregs->st_space);
- xfree(core->thread_info->fpregs->xmm_space);
- xfree(core->thread_info->fpregs->padding);
- }
- xfree(core->thread_info->gpregs);
- xfree(core->thread_info->fpregs);
- }
- xfree(core->thread_info);
- xfree(core->thread_core);
- xfree(core->tc);
- xfree(core->ids);
- }
-}
-
static CoreEntry *core_entry_alloc(int alloc_thread_info,
int alloc_tc,
int alloc_ids)
{
CoreEntry *core;
- ThreadInfoX86 *thread_info;
- UserX86RegsEntry *gpregs;
- UserX86FpregsEntry *fpregs;
TaskCoreEntry *tc;
TaskKobjIdsEntry *ids;
ThreadCoreEntry *thread_core;
@@ -822,45 +703,16 @@ static CoreEntry *core_entry_alloc(int alloc_thread_info,
return NULL;
core_entry__init(core);
- core->mtype = CORE_ENTRY__MARCH__X86_64;
-
- if (alloc_thread_info) {
- thread_info = xmalloc(sizeof(*thread_info));
- if (!thread_info)
- goto err;
- thread_info_x86__init(thread_info);
- core->thread_info = thread_info;
-
- thread_core = xmalloc(sizeof(*thread_core));
- if (!thread_core)
- goto err;
- thread_core_entry__init(thread_core);
- core->thread_core = thread_core;
-
- gpregs = xmalloc(sizeof(*gpregs));
- if (!gpregs)
- goto err;
- user_x86_regs_entry__init(gpregs);
- thread_info->gpregs = gpregs;
-
- fpregs = xmalloc(sizeof(*fpregs));
- if (!fpregs)
- goto err;
- user_x86_fpregs_entry__init(fpregs);
- thread_info->fpregs = fpregs;
+ core->mtype = CORE_ENTRY__MARCH;
- /* These are numbers from kernel */
- fpregs->n_st_space = 32;
- fpregs->n_xmm_space = 64;
- fpregs->n_padding = 24;
-
- fpregs->st_space = xzalloc(pb_repeated_size(fpregs, st_space));
- fpregs->xmm_space = xzalloc(pb_repeated_size(fpregs, xmm_space));
- fpregs->padding = xzalloc(pb_repeated_size(fpregs, padding));
-
- if (!fpregs->st_space || !fpregs->xmm_space || !fpregs->padding)
- goto err;
+ thread_core = xmalloc(sizeof(*thread_core));
+ if (!thread_core)
+ goto err;
+ thread_core_entry__init(thread_core);
+ core->thread_core = thread_core;
+ if (alloc_thread_info) {
+ arch_alloc_thread_info(core);
}
if (alloc_tc) {
@@ -887,7 +739,7 @@ err:
}
static int dump_task_core_all(pid_t pid, const struct proc_pid_stat *stat,
- const struct parasite_dump_misc *misc, const struct parasite_ctl *ctl,
+ const struct parasite_dump_misc *misc, struct parasite_ctl *ctl,
const struct cr_fdset *cr_fdset,
struct list_head *vma_area_list)
{
@@ -915,7 +767,7 @@ static int dump_task_core_all(pid_t pid, const struct proc_pid_stat *stat,
if (ret)
goto err_free;
- mark_stack_vma(core->thread_info->gpregs->sp, vma_area_list);
+ mark_stack_vma(TI_SP(core), vma_area_list);
ret = get_task_futex_robust_list(pid, core->thread_core);
if (ret)
@@ -937,6 +789,10 @@ static int dump_task_core_all(pid_t pid, const struct proc_pid_stat *stat,
if (ret)
goto err_free;
+#ifdef CONFIG_HAS_TLS
+ CORE_TLS(core) = parasite_get_tls_seized(ctl);
+#endif
+
ret = pb_write_one(fd_core, core, PB_CORE);
if (ret < 0) {
pr_info("ERROR\n");
@@ -1307,6 +1163,10 @@ static int dump_task_thread(struct parasite_ctl *parasite_ctl, struct pid *tid)
unsigned int *taddr;
pid_t pid = tid->real;
+#ifdef CONFIG_HAS_TLS
+ u32 tls;
+#endif
+
pr_info("\n");
pr_info("Dumping core for thread (pid: %d)\n", pid);
pr_info("----------------------------------------\n");
@@ -1324,16 +1184,25 @@ static int dump_task_thread(struct parasite_ctl *parasite_ctl, struct pid *tid)
goto err_free;
ret = parasite_dump_thread_seized(parasite_ctl, pid, &taddr,
- &tid->virt, &core->thread_core->blk_sigset);
+ &tid->virt, &core->thread_core->blk_sigset
+#ifdef CONFIG_HAS_TLS
+ , &tls
+#endif
+ );
+
if (ret) {
pr_err("Can't dump thread for pid %d\n", pid);
goto err_free;
}
core->thread_core->has_blk_sigset = true;
- pr_info("%d: virt_pid=%d tid_address=%p sig_blocked=0x%lx\n", pid,
+#ifdef CONFIG_HAS_TLS
+ CORE_THREAD_INFO(core)->tls = tls;
+#endif
+
+ pr_info("%d: virt_pid=%d tid_address=%p sig_blocked=0x%"PRIx64"\n", pid,
tid->virt, taddr, core->thread_core->blk_sigset);
- core->thread_info->clear_tid_addr = (u64) taddr;
+ CORE_THREAD_INFO(core)->clear_tid_addr = (u64) taddr;
ret = dump_sched_info(pid, core->thread_core);
if (ret)
--
1.7.9.5
More information about the CRIU
mailing list