[CRIU] [PATCH 06/22] parasite: introduced the multiarch support into the parasite.

Pavel Emelyanov xemul at parallels.com
Fri Dec 28 03:50:22 EST 2012


On 12/27/2012 10:50 AM, Alexander Kartashov wrote:
> * Introduced the TLS area retrieval in the routine parasite_dump_thread_seized
>   since ARM requires saving/restoring it.
> 
> * Introduced the macro ARCH_SI_TRAP to abstract from behavior of breakpoints:
>   they generate different values of the field siginfo.si_code on different architectures.
> 
> * Introduced the macro REG_RES to reference the syscall return value register in
>   the struct user_regs_struct_t.

This should be "one change -- one patch".

> Signed-off-by: Alexander Kartashov <alekskartashov at parallels.com>
> ---
>  arch/x86/include/asm/parasite-syscall.h |    2 ++
>  arch/x86/include/asm/parasite.h         |    8 ++++++++
>  arch/x86/include/asm/types.h            |    3 +++
>  include/parasite-syscall.h              |    3 ++-
>  include/parasite.h                      |    7 +++++++
>  parasite-syscall.c                      |   24 ++++++++++++++++++++----
>  pie/parasite.c                          |   12 +++++++++---
>  7 files changed, 51 insertions(+), 8 deletions(-)
>  create mode 100644 arch/x86/include/asm/parasite.h
> 
> diff --git a/arch/x86/include/asm/parasite-syscall.h b/arch/x86/include/asm/parasite-syscall.h
> index f3bd363..69b0bdf 100644
> --- a/arch/x86/include/asm/parasite-syscall.h
> +++ b/arch/x86/include/asm/parasite-syscall.h
> @@ -1,6 +1,8 @@
>  #ifndef __CR_ASM_PARASITE_SYSCALL_H__
>  #define __CR_ASM_PARASITE_SYSCALL_H__
>  
> +#define ARCH_SI_TRAP SI_KERNEL
> +
>  /*
>   * Injected syscall instruction
>   */
> diff --git a/arch/x86/include/asm/parasite.h b/arch/x86/include/asm/parasite.h
> new file mode 100644
> index 0000000..0c6bcb4
> --- /dev/null
> +++ b/arch/x86/include/asm/parasite.h
> @@ -0,0 +1,8 @@
> +#ifndef __ASM_PARASITE_H__
> +#define __ASM_PARASITE_H__
> +
> +static uint32_t arch_get_tls() {

Coding style.

> +	return 0;
> +}
> +
> +#endif
> diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h
> index 98c90d1..2b9f3ec 100644
> --- a/arch/x86/include/asm/types.h
> +++ b/arch/x86/include/asm/types.h
> @@ -249,6 +249,9 @@ typedef struct {
>  
>  typedef struct { } UserFPState;
>  
> +#define REG_RES(regs) ((regs).ax)
> +#define REG_IP(regs)  ((regs).ip)
> +
>  #define TASK_SIZE ((1UL << 47) - 1)
>  
>  typedef uint64_t auxv_t;
> diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
> index 6b0d659..bea74d3 100644
> --- a/include/parasite-syscall.h
> +++ b/include/parasite-syscall.h
> @@ -38,7 +38,7 @@ extern int parasite_dump_pages_seized(struct parasite_ctl *ctl,
>  struct parasite_dump_thread;
>  extern int parasite_dump_thread_seized(struct parasite_ctl *ctl, pid_t pid,
>  					unsigned int **tid_add, pid_t *tid,
> -					void *blocked);
> +					void *blocked, u32* tls);
>  
>  struct parasite_drain_fd;
>  struct fd_opts;
> @@ -49,6 +49,7 @@ extern int parasite_get_proc_fd_seized(struct parasite_ctl *ctl);
>  
>  struct pstree_item;
>  extern int parasite_cure_seized(struct parasite_ctl *ctl, struct pstree_item *item);
> +extern uint32_t parasite_get_tls_seized(struct parasite_ctl* ctl);
>  extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
>  						   struct pstree_item *item,
>  						   struct list_head *vma_area_list);
> diff --git a/include/parasite.h b/include/parasite.h
> index f743e06..b5e874a 100644
> --- a/include/parasite.h
> +++ b/include/parasite.h
> @@ -37,6 +37,8 @@ enum {
>  	PARASITE_CMD_GET_PROC_FD,
>  	PARASITE_CMD_DUMP_TTY,
>  
> +	PARASITE_CMD_GET_TLS,
> +
>  	PARASITE_CMD_MAX,
>  };
>  
> @@ -97,6 +99,7 @@ struct parasite_dump_thread {
>  	unsigned int		*tid_addr;
>  	pid_t			tid;
>  	k_rtsigset_t		blocked;
> +	u32			tls;
>  };
>  
>  #define PARASITE_MAX_FDS	(PAGE_SIZE / sizeof(int))
> @@ -106,6 +109,10 @@ struct parasite_drain_fd {
>  	int	fds[PARASITE_MAX_FDS];
>  };
>  
> +struct parasite_get_tls_args {
> +	uint32_t tls;
> +};
> +
>  static inline int drain_fds_size(struct parasite_drain_fd *dfds)
>  {
>  	return sizeof(dfds->nr_fds) + dfds->nr_fds * sizeof(dfds->fds[0]);
> diff --git a/parasite-syscall.c b/parasite-syscall.c
> index 85b7db6..ae91756 100644
> --- a/parasite-syscall.c
> +++ b/parasite-syscall.c
> @@ -1,4 +1,5 @@
>  #include <unistd.h>
> +#include <inttypes.h>
>  
>  #include <sys/stat.h>
>  #include <sys/wait.h>
> @@ -98,7 +99,7 @@ again:
>  			goto err;
>  	}
>  
> -	if (WSTOPSIG(status) != SIGTRAP || siginfo.si_code != SI_KERNEL) {
> +	if (WSTOPSIG(status) != SIGTRAP || siginfo.si_code != ARCH_SI_TRAP) {
>  retry_signal:
>  		pr_debug("** delivering signal %d si_code=%d\n",
>  			 siginfo.si_signo, siginfo.si_code);
> @@ -211,7 +212,7 @@ static int parasite_execute_by_pid(unsigned int cmd, struct parasite_ctl *ctl, p
>  
>  	ret = __parasite_execute(ctl, pid, &regs);
>  	if (ret == 0)
> -		ret = (int)regs.ax;
> +		ret = (int)REG_RES(regs);
>  
>  	if (ret)
>  		pr_err("Parasite exited with %d\n", ret);
> @@ -365,7 +366,8 @@ err:
>  
>  int parasite_dump_thread_seized(struct parasite_ctl *ctl, pid_t pid,
>  					unsigned int **tid_addr, pid_t *tid,
> -					void *blocked)
> +					void *blocked,
> +					u32* tls)
>  {
>  	struct parasite_dump_thread *args;
>  	int ret;
> @@ -377,6 +379,7 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, pid_t pid,
>  	memcpy(blocked, &args->blocked, sizeof(args->blocked));
>  	*tid_addr = args->tid_addr;
>  	*tid = args->tid;
> +	*tls = args->tls;
>  
>  	return ret;
>  }
> @@ -549,6 +552,10 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a
>  			continue;
>  		}
>  
> +		if (vma_area->vma.end > TASK_SIZE) {
> +			continue;
> +		}

This is not described in comment (and should probably belong to separate patch).

> +
>  		ret = parasite_execute(PARASITE_CMD_DUMPPAGES, ctl);
>  		if (ret) {
>  			pr_err("Dumping pages failed with %d\n", ret);
> @@ -676,6 +683,15 @@ int parasite_fini_threads_seized(struct parasite_ctl *ctl, struct pstree_item *i
>  	return ret;
>  }
>  
> +uint32_t parasite_get_tls_seized(struct parasite_ctl *ctl) {

Coding style.

> +	struct parasite_get_tls_args *tls_args;
> +
> +	tls_args = (struct parasite_get_tls_args*)parasite_args_s(ctl, sizeof(*tls_args));
> +	parasite_execute(PARASITE_CMD_GET_TLS, ctl);
> +
> +	return tls_args->tls;
> +}
> +
>  int parasite_cure_seized(struct parasite_ctl *ctl, struct pstree_item *item)
>  {
>  	int ret = 0;
> @@ -738,7 +754,7 @@ struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct list_head *vma_area_lis
>  		goto err;
>  	}
>  
> -	vma_area = get_vma_by_ip(vma_area_list, ctl->regs_orig.ip);
> +	vma_area = get_vma_by_ip(vma_area_list, REG_IP(ctl->regs_orig));
>  	if (!vma_area) {
>  		pr_err("No suitable VMA found to run parasite "
>  		       "bootstrap code (pid: %d)\n", pid);
> diff --git a/pie/parasite.c b/pie/parasite.c
> index d9e2a1d..3338e03 100644
> --- a/pie/parasite.c
> +++ b/pie/parasite.c
> @@ -12,9 +12,7 @@
>  
>  #include <string.h>
>  
> -#ifndef CONFIG_X86_64
> -#error non-x86-64 mode not yet implemented
> -#endif
> +#include "asm/parasite.h"
>  
>  static void *brk_start, *brk_end, *brk_tail;
>  
> @@ -372,6 +370,7 @@ static int dump_thread(struct parasite_dump_thread *args)
>  
>  	args->blocked = s->sig_blocked;
>  	args->tid = tid;
> +	args->tls = arch_get_tls();
>  
>  	return 0;
>  }
> @@ -584,6 +583,10 @@ static int parasite_cfg_log(struct parasite_log_args *args)
>  	return ret;
>  }
>  
> +static void parasite_get_tls(struct parasite_get_tls_args* args) {

Coding style.

> +	args->tls = arch_get_tls();
> +}
> +
>  static int fini(void)
>  {
>  	int ret;
> @@ -635,6 +638,9 @@ int __used parasite_service(unsigned int cmd, void *args)
>  		return parasite_get_proc_fd();
>  	case PARASITE_CMD_DUMP_TTY:
>  		return parasite_dump_tty(args);
> +	case PARASITE_CMD_GET_TLS:
> +		parasite_get_tls((struct parasite_get_tls_args*)args);
> +		return 0;
>  	}
>  
>  	pr_err("Unknown command to parasite\n");
> 




More information about the CRIU mailing list