[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, &regs)) {
-			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