[CRIU] [PATCH 07/21] parasite: allocate stack for each thread

Andrey Vagin avagin at openvz.org
Fri May 24 08:20:10 EDT 2013


It will be used for executed parasite as a daemon.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 arch/arm/crtools.c                      |  6 ++++--
 arch/arm/include/asm/parasite-syscall.h |  2 +-
 arch/arm/parasite-head.S                | 13 -------------
 arch/x86/crtools.c                      |  6 ++++--
 arch/x86/include/asm/parasite-syscall.h |  2 +-
 arch/x86/parasite-head.S                |  4 ----
 include/parasite-syscall.h              |  2 ++
 parasite-syscall.c                      | 16 +++++++++++++---
 8 files changed, 25 insertions(+), 26 deletions(-)

diff --git a/arch/arm/crtools.c b/arch/arm/crtools.c
index 81a819a..a07251b 100644
--- a/arch/arm/crtools.c
+++ b/arch/arm/crtools.c
@@ -35,9 +35,11 @@ static inline void __check_code_syscall(void)
 }
 
 
-void parasite_setup_regs(unsigned long new_ip, user_regs_struct_t *regs)
+void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
 {
 	regs->ARM_pc = new_ip;
+	if (stack)
+		regs->ARM_sp = stack;
 
 	/* Avoid end of syscall processing */
 	regs->ARM_ORIG_r0 = -1;
@@ -73,7 +75,7 @@ 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, &regs);
+	parasite_setup_regs(ctl->syscall_ip, 0, &regs);
 	err = __parasite_execute_trap(ctl, ctl->pid.real, &regs);
 	if (err)
 		return err;
diff --git a/arch/arm/include/asm/parasite-syscall.h b/arch/arm/include/asm/parasite-syscall.h
index 8971277..0c66bf9 100644
--- a/arch/arm/include/asm/parasite-syscall.h
+++ b/arch/arm/include/asm/parasite-syscall.h
@@ -9,7 +9,7 @@ extern const char code_syscall[];
 extern const int code_syscall_size;
 
 
-void parasite_setup_regs(unsigned long new_ip, user_regs_struct_t *regs);
+void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs);
 
 void *mmap_seized(struct parasite_ctl *ctl,
 		  void *addr, size_t length, int prot,
diff --git a/arch/arm/parasite-head.S b/arch/arm/parasite-head.S
index c345ccd..b15fcba 100644
--- a/arch/arm/parasite-head.S
+++ b/arch/arm/parasite-head.S
@@ -5,11 +5,6 @@
 ENTRY(__export_parasite_head_start)
 	sub	%r2, %pc, #8			@ get the address of this instruction
 
-	adr	%sp, parasite_stack_ptr
-	ldr	%sp, [%sp]
-	add	%sp, %sp, %r2			@ fixup __export_parasite_stack
-	bic	%sp, %sp, #7			@ align the stack
-
         adr     %r0, __export_parasite_cmd
 	ldr	%r0, [%r0]
 
@@ -23,14 +18,6 @@ ENTRY(__export_parasite_head_start)
 parasite_args_ptr:
 	.long __export_parasite_args
 
-parasite_stack_ptr:
-	.long __export_parasite_stack
-
 __export_parasite_cmd:
 	.long 0
-	.space PARASITE_STACK_SIZE,0
-
-.align 3
-__export_parasite_stack:
-	.long 0
 END(__export_parasite_head_start)
diff --git a/arch/x86/crtools.c b/arch/x86/crtools.c
index 1fc0b63..3bed43a 100644
--- a/arch/x86/crtools.c
+++ b/arch/x86/crtools.c
@@ -35,9 +35,11 @@ static inline void __check_code_syscall(void)
 	BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
 }
 
-void parasite_setup_regs(unsigned long new_ip, user_regs_struct_t *regs)
+void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
 {
 	regs->ip = new_ip;
+	if (stack)
+		regs->sp = (unsigned long) stack;
 
 	/* Avoid end of syscall processing */
 	regs->orig_ax = -1;
@@ -97,7 +99,7 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
 	regs.r8  = arg5;
 	regs.r9  = arg6;
 
-	parasite_setup_regs(ctl->syscall_ip, &regs);
+	parasite_setup_regs(ctl->syscall_ip, 0, &regs);
 	err = __parasite_execute_trap(ctl, ctl->pid.real, &regs);
 	if (err)
 		return err;
diff --git a/arch/x86/include/asm/parasite-syscall.h b/arch/x86/include/asm/parasite-syscall.h
index d6481c6..a0e2150 100644
--- a/arch/x86/include/asm/parasite-syscall.h
+++ b/arch/x86/include/asm/parasite-syscall.h
@@ -8,7 +8,7 @@
 extern const char code_syscall[];
 extern const int code_syscall_size;
 
-void parasite_setup_regs(unsigned long new_ip, user_regs_struct_t *regs);
+void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs);
 
 void *mmap_seized(struct parasite_ctl *ctl,
 		  void *addr, size_t length, int prot,
diff --git a/arch/x86/parasite-head.S b/arch/x86/parasite-head.S
index 0b62750..8caf9b3 100644
--- a/arch/x86/parasite-head.S
+++ b/arch/x86/parasite-head.S
@@ -3,7 +3,6 @@
 
 	.section .head.text, "ax"
 ENTRY(__export_parasite_head_start)
-	leaq	__export_parasite_stack(%rip), %rsp
 	subq	$16, %rsp
 	andq	$~15, %rsp
 	pushq	$0
@@ -15,7 +14,4 @@ ENTRY(__export_parasite_head_start)
 	.align 8
 __export_parasite_cmd:
 	.long 0
-	.space PARASITE_STACK_SIZE,0
-__export_parasite_stack:
-	.long 0
 END(__export_parasite_head_start)
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index 689fe90..543fa67 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -9,6 +9,8 @@ struct parasite_thread_ctl
 {
 	pid_t			tid;
 	user_regs_struct_t	regs_orig;				/* original registers */
+
+	void			*rstack;
 };
 
 /* parasite control block */
diff --git a/parasite-syscall.c b/parasite-syscall.c
index b82fc7c..9ab8a5b 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -204,7 +204,7 @@ static int parasite_execute_trap_by_id(unsigned int cmd, struct parasite_ctl *ct
 
 	*ctl->addr_cmd = cmd;
 
-	parasite_setup_regs(ctl->parasite_ip, &regs);
+	parasite_setup_regs(ctl->parasite_ip, thread->rstack, &regs);
 
 	ret = __parasite_execute_trap(ctl, pid, &regs);
 	if (ret == 0)
@@ -762,8 +762,9 @@ static unsigned long parasite_args_size(struct vm_area_list *vmas, struct parasi
 struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 		struct vm_area_list *vma_area_list, struct parasite_drain_fd *dfds)
 {
-	int ret;
+	int ret, i;
 	struct parasite_ctl *ctl;
+	unsigned long p;
 
 	BUG_ON(item->threads[0].real != pid);
 
@@ -779,7 +780,8 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 	 */
 
 	ctl->args_size = parasite_args_size(vma_area_list, dfds);
-	ret = parasite_map_exchange(ctl, parasite_size + ctl->args_size);
+	ret = parasite_map_exchange(ctl, parasite_size + ctl->args_size +
+					 item->nr_threads * PARASITE_STACK_SIZE);
 	if (ret)
 		goto err_restore;
 
@@ -791,6 +793,14 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 	ctl->addr_cmd		= parasite_sym(ctl->local_map, __export_parasite_cmd);
 	ctl->addr_args		= parasite_sym(ctl->local_map, __export_parasite_args);
 
+	p = parasite_size + ctl->args_size;
+	for (i = 0; i < item->nr_threads; i++) {
+		struct parasite_thread_ctl *thread = &ctl->threads[i];
+
+		thread->rstack = ctl->remote_map + p;
+		p += PARASITE_STACK_SIZE;
+	}
+
 	ret = parasite_init(ctl, pid, item->nr_threads);
 	if (ret) {
 		pr_err("%d: Can't create a transport socket\n", pid);
-- 
1.8.2



More information about the CRIU mailing list