[CRIU] [PATCH 11/22] restorer: wrapped the assembly calling sys_rt_sigreturn into the macro ARCH_RT_SIGRETURN

Pavel Emelyanov xemul at parallels.com
Fri Dec 28 04:30:05 EST 2012


On 12/28/2012 01:23 PM, Cyrill Gorcunov wrote:
> On Fri, Dec 28, 2012 at 01:06:57PM +0400, Pavel Emelyanov wrote:
>> On 12/28/2012 01:00 PM, Alexander Kartashov wrote:
>>> On 12/28/2012 12:54 PM, Pavel Emelyanov wrote:
>>>> I'd prefer seeing this in some .S file, rather than in a header. How complex
>>>> would it be to do so?
>>>
>>> We will have to implement C calling convention by hand
>>> for every supported architecture if it goes there.
>>
>> I see.
>>
>>> Is it OK to do this?
>>
>> Let's do the following -- for now keep this as macro, but some time
>> later, in the background, move it into a .S file.
> 
> I think moving a couple of instruction into .S file actually doesn't worth much.

It's just about code readability. Reading .S file is more comfortable that
doing the same with preprocessor stuff in .h

> When being working on restorer redesign I've implemented the following
> patch (just for info).

I mean "move it to some .c file with asm() code inside"? Why do we have the
parasite-head.S then, not parasite-head.c?

> 	Cyrill
> ---
>>From f0caa8c9ad52f014f38cc7b6b2d1fecd89ecb03e Mon Sep 17 00:00:00 2001
> From: Cyrill Gorcunov <gorcunov at openvz.org>
> Date: Wed, 12 Dec 2012 16:17:43 +0400
> Subject: [PATCH] restorer: Move rt-sigreturn functionality to rt-sigreturn.[ch] files
> 
> We will need to use this code in parasite dumper thus make
> it standalone one.
> 
> Note we use __maybe_unused attribue on functions since otherwise
> we will have a warning about unused functions. This will be changed
> in next patch where we start applicate this helpers.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
>  include/restorer.h     | 70 ----------------------------------------------
>  include/rt-sigreturn.h | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  pie/Makefile           |  2 +-
>  pie/restorer.c         |  1 +
>  pie/rt-sigreturn.c     | 71 ++++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 149 insertions(+), 71 deletions(-)
>  create mode 100644 include/rt-sigreturn.h
>  create mode 100644 pie/rt-sigreturn.c
> 
> diff --git a/include/restorer.h b/include/restorer.h
> index 8e3eb64..64163b5 100644
> --- a/include/restorer.h
> +++ b/include/restorer.h
> @@ -131,76 +131,6 @@ struct task_restore_core_args {
>  	int				rst_tcp_socks_size;
>  } __aligned(sizeof(long));
>  
> -struct rt_sigcontext {
> -	unsigned long			r8;
> -	unsigned long			r9;
> -	unsigned long			r10;
> -	unsigned long			r11;
> -	unsigned long			r12;
> -	unsigned long			r13;
> -	unsigned long			r14;
> -	unsigned long			r15;
> -	unsigned long			rdi;
> -	unsigned long			rsi;
> -	unsigned long			rbp;
> -	unsigned long			rbx;
> -	unsigned long			rdx;
> -	unsigned long			rax;
> -	unsigned long			rcx;
> -	unsigned long			rsp;
> -	unsigned long			rip;
> -	unsigned long			eflags;
> -	unsigned short			cs;
> -	unsigned short			gs;
> -	unsigned short			fs;
> -	unsigned short			__pad0;
> -	unsigned long			err;
> -	unsigned long			trapno;
> -	unsigned long			oldmask;
> -	unsigned long			cr2;
> -	void				*fpstate;;
> -	unsigned long			reserved1[8];
> -};
> -
> -#ifndef __ARCH_SI_PREAMBLE_SIZE
> -#define __ARCH_SI_PREAMBLE_SIZE	(3 * sizeof(int))
> -#endif
> -
> -#define SI_MAX_SIZE	128
> -#ifndef SI_PAD_SIZE
> -#define SI_PAD_SIZE	((SI_MAX_SIZE - __ARCH_SI_PREAMBLE_SIZE) / sizeof(int))
> -#endif
> -
> -typedef struct rt_siginfo {
> -	int	si_signo;
> -	int	si_errno;
> -	int	si_code;
> -	int	_pad[SI_PAD_SIZE];
> -} rt_siginfo_t;
> -
> -typedef struct rt_sigaltstack {
> -	void	*ss_sp;
> -	int	ss_flags;
> -	size_t	ss_size;
> -} rt_stack_t;
> -
> -struct rt_ucontext {
> -	unsigned long		uc_flags;
> -	struct rt_ucontext	*uc_link;
> -	rt_stack_t		uc_stack;
> -	struct rt_sigcontext	uc_mcontext;
> -	rt_sigset_t		uc_sigmask;	/* mask last for extensibility */
> -};
> -
> -struct rt_sigframe {
> -	char			*pretcode;
> -	struct rt_ucontext	uc;
> -	struct rt_siginfo	info;
> -
> -	/* fp state follows here */
> -};
> -
> -
>  #define SHMEMS_SIZE	4096
>  
>  /*
> diff --git a/include/rt-sigreturn.h b/include/rt-sigreturn.h
> new file mode 100644
> index 0000000..35f8b27
> --- /dev/null
> +++ b/include/rt-sigreturn.h
> @@ -0,0 +1,76 @@
> +#ifndef CR_RT_SIGRETURN_H__
> +#define CR_RT_SIGRETURN_H__
> +
> +struct rt_sigcontext {
> +	unsigned long			r8;
> +	unsigned long			r9;
> +	unsigned long			r10;
> +	unsigned long			r11;
> +	unsigned long			r12;
> +	unsigned long			r13;
> +	unsigned long			r14;
> +	unsigned long			r15;
> +	unsigned long			rdi;
> +	unsigned long			rsi;
> +	unsigned long			rbp;
> +	unsigned long			rbx;
> +	unsigned long			rdx;
> +	unsigned long			rax;
> +	unsigned long			rcx;
> +	unsigned long			rsp;
> +	unsigned long			rip;
> +	unsigned long			eflags;
> +	unsigned short			cs;
> +	unsigned short			gs;
> +	unsigned short			fs;
> +	unsigned short			__pad0;
> +	unsigned long			err;
> +	unsigned long			trapno;
> +	unsigned long			oldmask;
> +	unsigned long			cr2;
> +	struct user_fpregs_entry	*fpstate;
> +	unsigned long			reserved1[8];
> +};
> +
> +#ifndef __ARCH_SI_PREAMBLE_SIZE
> +#define __ARCH_SI_PREAMBLE_SIZE	(3 * sizeof(int))
> +#endif
> +
> +#define SI_MAX_SIZE	128
> +#ifndef SI_PAD_SIZE
> +#define SI_PAD_SIZE	((SI_MAX_SIZE - __ARCH_SI_PREAMBLE_SIZE) / sizeof(int))
> +#endif
> +
> +typedef struct rt_siginfo {
> +	int	si_signo;
> +	int	si_errno;
> +	int	si_code;
> +	int	_pad[SI_PAD_SIZE];
> +} rt_siginfo_t;
> +
> +typedef struct rt_sigaltstack {
> +	void	*ss_sp;
> +	int	ss_flags;
> +	size_t	ss_size;
> +} rt_stack_t;
> +
> +struct rt_ucontext {
> +	unsigned long		uc_flags;
> +	struct rt_ucontext	*uc_link;
> +	rt_stack_t		uc_stack;
> +	struct rt_sigcontext	uc_mcontext;
> +	rt_sigset_t		uc_sigmask;	/* mask last for extensibility */
> +};
> +
> +struct rt_sigframe {
> +	char			*pretcode;
> +	struct rt_ucontext	uc;
> +	struct rt_siginfo	info;
> +
> +	/* fp state follows here */
> +};
> +
> +extern int prep_rt_sigreturn(struct rt_sigframe *rt_sigframe, void *regs, u64 blk_sigset);
> +extern int do_rt_sigreturn(struct rt_sigframe *rt_sigframe);
> +
> +#endif /* CR_RT_SIGRETURN_H__ */
> diff --git a/pie/Makefile b/pie/Makefile
> index efb7532..5cc5473 100644
> --- a/pie/Makefile
> +++ b/pie/Makefile
> @@ -13,7 +13,7 @@ ASMFLAGS	:= -D__ASSEMBLY__
>  
>  .DEFAULT_GOAL	:= pie
>  
> -LIB-OBJS	= log-simple.o blob-util-net.o $(SYSCALL-LIB)
> +LIB-OBJS	= rt-sigreturn.o log-simple.o blob-util-net.o $(SYSCALL-LIB)
>  
>  $(PARASITE): $(LIB-OBJS) $(PASM-OBJS) $(PIELDS)
>  $(RESTORER): $(LIB-OBJS) $(PIELDS)
> diff --git a/pie/restorer.c b/pie/restorer.c
> index 03536ae..d970d6c 100644
> --- a/pie/restorer.c
> +++ b/pie/restorer.c
> @@ -23,6 +23,7 @@
>  
>  #include "crtools.h"
>  #include "lock.h"
> +#include "rt-sigreturn.h"
>  #include "restorer.h"
>  
>  #include "creds.pb-c.h"
> diff --git a/pie/rt-sigreturn.c b/pie/rt-sigreturn.c
> new file mode 100644
> index 0000000..56195a7
> --- /dev/null
> +++ b/pie/rt-sigreturn.c
> @@ -0,0 +1,71 @@
> +#define CR_NOGLIBC
> +
> +#include <sys/types.h>
> +#include <unistd.h>
> +
> +#include "compiler.h"
> +#include "types.h"
> +#include "syscall.h"
> +#include "log.h"
> +
> +#include "core.pb-c.h"
> +
> +#include "rt-sigreturn.h"
> +
> +int __maybe_unused prep_rt_sigreturn(struct rt_sigframe *rt_sigframe, void *regs, u64 blk_sigset)
> +{
> +	UserX86RegsEntry *r = regs;
> +
> +#define CPREG1(d)	rt_sigframe->uc.uc_mcontext.d = r->d
> +#define CPREG2(d, s)	rt_sigframe->uc.uc_mcontext.d = r->s
> +
> +	CPREG1(r8);
> +	CPREG1(r9);
> +	CPREG1(r10);
> +	CPREG1(r11);
> +	CPREG1(r12);
> +	CPREG1(r13);
> +	CPREG1(r14);
> +	CPREG1(r15);
> +	CPREG2(rdi, di);
> +	CPREG2(rsi, si);
> +	CPREG2(rbp, bp);
> +	CPREG2(rbx, bx);
> +	CPREG2(rdx, dx);
> +	CPREG2(rax, ax);
> +	CPREG2(rcx, cx);
> +	CPREG2(rsp, sp);
> +	CPREG2(rip, ip);
> +	CPREG2(eflags, flags);
> +	CPREG1(cs);
> +	CPREG1(gs);
> +	CPREG1(fs);
> +
> +	if (sys_arch_prctl(ARCH_SET_FS, r->fs_base)) {
> +		pr_info("SET_FS failed\n");
> +		return -1;
> +	}
> +
> +	if (sys_arch_prctl(ARCH_SET_GS, r->gs_base)) {
> +		pr_info("SET_GS failed\n");
> +		return -1;
> +	}
> +
> +	rt_sigframe->uc.uc_sigmask.sig[0] = blk_sigset;
> +
> +	return 0;
> +}
> +
> +int __maybe_unused do_rt_sigreturn(struct rt_sigframe *rt_sigframe)
> +{
> +	unsigned long new_sp = (long)rt_sigframe + 8;
> +
> +	asm volatile("movq %0, %%rsp					\n"
> +		     "movl $"__stringify(__NR_rt_sigreturn)", %%eax	\n"
> +		     "syscall						\n"
> +		     :
> +		     : "r" (new_sp)
> +		     : "rsp", "memory");
> +
> +	return -1;
> +}
> 




More information about the CRIU mailing list