[CRIU] [PATCH 6/8] parasite: modify process memory only for executing syscalls

Andrey Vagin avagin at openvz.org
Thu Jul 11 05:46:53 EDT 2013


Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 arch/arm/crtools.c         |  8 ++------
 arch/x86/crtools.c         |  8 ++------
 include/parasite-syscall.h |  6 ++----
 parasite-syscall.c         | 48 +++++++++++++++++++++++++++++-----------------
 4 files changed, 36 insertions(+), 34 deletions(-)

diff --git a/arch/arm/crtools.c b/arch/arm/crtools.c
index bbc5cf9..db02fce 100644
--- a/arch/arm/crtools.c
+++ b/arch/arm/crtools.c
@@ -73,14 +73,10 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
 	regs.ARM_r4 = arg5;
 	regs.ARM_r5 = arg6;
 
-	parasite_setup_regs(ctl->syscall_ip, 0, &regs);
-	err = __parasite_execute_trap(ctl, ctl->pid.real, &regs,
-					&ctl->regs_orig, &ctl->sig_blocked);
-	if (err)
-		return err;
+	err = __parasite_execute_syscall(ctl, &regs);
 
 	*ret = regs.ARM_r0;
-	return 0;
+	return err;
 }
 
 #define assign_reg(dst, src, e)		dst->e = (__typeof__(dst->e))src.ARM_##e
diff --git a/arch/x86/crtools.c b/arch/x86/crtools.c
index c8c9433..474e731 100644
--- a/arch/x86/crtools.c
+++ b/arch/x86/crtools.c
@@ -100,14 +100,10 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
 	regs.r8  = arg5;
 	regs.r9  = arg6;
 
-	parasite_setup_regs(ctl->syscall_ip, 0, &regs);
-	err = __parasite_execute_trap(ctl, ctl->pid.real, &regs,
-					&ctl->regs_orig, &ctl->sig_blocked);
-	if (err)
-		return err;
+	err = __parasite_execute_syscall(ctl, &regs);
 
 	*ret = regs.ax;
-	return 0;
+	return err;
 }
 
 int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index fb1236d..45a1d63 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -101,10 +101,8 @@ extern int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
 			  unsigned long arg3, unsigned long arg4,
 			  unsigned long arg5, unsigned long arg6);
 
-extern int __parasite_execute_trap(struct parasite_ctl *ctl, pid_t pid,
-				   user_regs_struct_t *regs,
-				   user_regs_struct_t *regs_orig,
-				   k_rtsigset_t *sigmask);
+extern int __parasite_execute_syscall(struct parasite_ctl *ctl,
+				user_regs_struct_t *regs);
 extern bool arch_can_dump_task(pid_t pid);
 
 extern int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 07b45bc..e8b690f 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -66,7 +66,7 @@ static struct vma_area *get_vma_by_ip(struct list_head *vma_area_list, unsigned
 }
 
 /* we run at @regs->ip */
-int __parasite_execute_trap(struct parasite_ctl *ctl, pid_t pid,
+static int __parasite_execute_trap(struct parasite_ctl *ctl, pid_t pid,
 				user_regs_struct_t *regs,
 				user_regs_struct_t *regs_orig,
 				k_rtsigset_t *sigmask)
@@ -144,6 +144,35 @@ err_sigmask:
 	return ret;
 }
 
+int __parasite_execute_syscall(struct parasite_ctl *ctl, user_regs_struct_t *regs)
+{
+	pid_t pid = ctl->pid.real;
+	int err;
+
+	/*
+	 * Inject syscall instruction and remember original code,
+	 * we will need it to restore original program content.
+	 */
+	memcpy(ctl->code_orig, code_syscall, sizeof(ctl->code_orig));
+	if (ptrace_swap_area(pid, (void *)ctl->syscall_ip,
+			     (void *)ctl->code_orig, sizeof(ctl->code_orig))) {
+		pr_err("Can't inject syscall blob (pid: %d)\n", pid);
+		return -1;
+	}
+
+	parasite_setup_regs(ctl->syscall_ip, 0, regs);
+	err = __parasite_execute_trap(ctl, pid, regs, &ctl->regs_orig,
+							&ctl->sig_blocked);
+
+	if (ptrace_poke_area(pid, (void *)ctl->code_orig,
+			     (void *)ctl->syscall_ip, sizeof(ctl->code_orig))) {
+		pr_err("Can't restore syscall blob (pid: %d)\n", ctl->pid.real);
+		err = -1;
+	}
+
+	return err;
+}
+
 void *parasite_args_s(struct parasite_ctl *ctl, int args_size)
 {
 	BUG_ON(args_size > ctl->args_size);
@@ -858,12 +887,6 @@ int parasite_cure_remote(struct parasite_ctl *ctl)
 		}
 	}
 
-	if (ptrace_poke_area(ctl->pid.real, (void *)ctl->code_orig,
-			     (void *)ctl->syscall_ip, sizeof(ctl->code_orig))) {
-		pr_err("Can't restore syscall blob (pid: %d)\n", ctl->pid.real);
-		ret = -1;
-	}
-
 	return ret;
 }
 
@@ -933,17 +956,6 @@ struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct vm_area_list *vma_area_
 	ctl->pid.virt	= 0;
 	ctl->syscall_ip	= vma_area->vma.start;
 
-	/*
-	 * Inject syscall instruction and remember original code,
-	 * we will need it to restore original program content.
-	 */
-	memcpy(ctl->code_orig, code_syscall, sizeof(ctl->code_orig));
-	if (ptrace_swap_area(pid, (void *)ctl->syscall_ip,
-			     (void *)ctl->code_orig, sizeof(ctl->code_orig))) {
-		pr_err("Can't inject syscall blob (pid: %d)\n", pid);
-		goto err;
-	}
-
 	return ctl;
 
 err:
-- 
1.8.3.1



More information about the CRIU mailing list