Commit 443f2489 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

sigframe: Move sigframe-related code into sigframe.*

There's a lot of code making sigframes for PIE spread all over the
asm/restorer.h and arch/crtools.c. This patch collects it all into
asm/sigframe.h and arch/sigframe.c for better modularity and for
the sake of compel.

The patch is huge, but it just moves the code around (making u32/u64
types conversions to uint32/64_t-s where appropriate).

travis-ci: success for sigframe: Move sigframe-related code into sigframe.*
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-and-ported-on-dev-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 9117dd66
......@@ -6,3 +6,4 @@ ccflags-y += -iquote $(SRC_DIR)/include
obj-y += cpu.o
obj-y += crtools.o
obj-y += sigframe.o
......@@ -7,46 +7,8 @@
#include "asm/types.h"
#include "images/core.pb-c.h"
/* Copied from the kernel header arch/arm64/include/uapi/asm/sigcontext.h */
#define FPSIMD_MAGIC 0x46508001
typedef struct fpsimd_context fpu_state_t;
struct aux_context {
struct fpsimd_context fpsimd;
/* additional context to be added before "end" */
struct _aarch64_ctx end;
};
// XXX: the idetifier rt_sigcontext is expected to be struct by the CRIU code
#define rt_sigcontext sigcontext
#include "sigframe.h"
/* Copied from the kernel source arch/arm64/kernel/signal.c */
struct rt_sigframe {
siginfo_t info;
struct ucontext uc;
u64 fp;
u64 lr;
};
#define ARCH_RT_SIGRETURN(new_sp) \
asm volatile( \
"mov sp, %0 \n" \
"mov x8, #"__stringify(__NR_rt_sigreturn)" \n" \
"svc #0 \n" \
: \
: "r"(new_sp) \
: "sp", "x8", "memory")
#define RUN_CLONE_RESTORE_FN(ret, clone_flags, new_sp, parent_tid, \
thread_args, clone_restore_fn) \
asm volatile( \
......@@ -90,25 +52,10 @@ struct rt_sigframe {
: "sp", "x0", "memory")
#define RT_SIGFRAME_UC(rt_sigframe) (&rt_sigframe->uc)
#define RT_SIGFRAME_REGIP(rt_sigframe) ((long unsigned int)(rt_sigframe)->uc.uc_mcontext.pc)
#define RT_SIGFRAME_HAS_FPU(rt_sigframe) (1)
#define RT_SIGFRAME_AUX_CONTEXT(rt_sigframe) \
((struct aux_context*)&(rt_sigframe)->uc.uc_mcontext.__reserved)
#define RT_SIGFRAME_FPU(rt_sigframe) \
(&RT_SIGFRAME_AUX_CONTEXT(rt_sigframe)->fpsimd)
#define RT_SIGFRAME_OFFSET(rt_sigframe) 0
int restore_gpregs(struct rt_sigframe *f, UserAarch64RegsEntry *r);
int restore_nonsigframe_gpregs(UserAarch64RegsEntry *r);
static inline int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe)
{
return 0;
}
static inline void restore_tls(tls_t *ptls)
{
asm("msr tpidr_el0, %0" : : "r" (*ptls));
......
#ifndef UAPI_COMPEL_ASM_SIGFRAME_H__
#define UAPI_COMPEL_ASM_SIGFRAME_H__
#include <asm/sigcontext.h>
#include <sys/ucontext.h>
#include <stdint.h>
/* Copied from the kernel header arch/arm64/include/uapi/asm/sigcontext.h */
#define FPSIMD_MAGIC 0x46508001
typedef struct fpsimd_context fpu_state_t;
struct aux_context {
struct fpsimd_context fpsimd;
/* additional context to be added before "end" */
struct _aarch64_ctx end;
};
// XXX: the idetifier rt_sigcontext is expected to be struct by the CRIU code
#define rt_sigcontext sigcontext
#include "sigframe-common.h"
/* Copied from the kernel source arch/arm64/kernel/signal.c */
struct rt_sigframe {
siginfo_t info;
struct ucontext uc;
uint64_t fp;
uint64_t lr;
};
#define ARCH_RT_SIGRETURN(new_sp) \
asm volatile( \
"mov sp, %0 \n" \
"mov x8, #"__stringify(__NR_rt_sigreturn)" \n" \
"svc #0 \n" \
: \
: "r"(new_sp) \
: "sp", "x8", "memory")
#define RT_SIGFRAME_UC(rt_sigframe) (&rt_sigframe->uc)
#define RT_SIGFRAME_REGIP(rt_sigframe) ((long unsigned int)(rt_sigframe)->uc.uc_mcontext.pc)
#define RT_SIGFRAME_HAS_FPU(rt_sigframe) (1)
#define RT_SIGFRAME_AUX_CONTEXT(rt_sigframe) ((struct aux_context*)&(rt_sigframe)->uc.uc_mcontext.__reserved)
#define RT_SIGFRAME_FPU(rt_sigframe) (&RT_SIGFRAME_AUX_CONTEXT(rt_sigframe)->fpsimd)
#define RT_SIGFRAME_OFFSET(rt_sigframe) 0
#endif /* UAPI_COMPEL_ASM_SIGFRAME_H__ */
#include "asm/types.h"
#include "asm/sigframe.h"
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe)
{
return 0;
}
......@@ -5,3 +5,4 @@ ccflags-y += -iquote $(SRC_DIR)/criu/include -iquote $(SRC_DIR)/include
obj-y += cpu.o
obj-y += crtools.o
obj-y += sigframe.o
......@@ -4,78 +4,8 @@
#include "asm/types.h"
#include "images/core.pb-c.h"
/* Copied from the Linux kernel header arch/arm/include/asm/sigcontext.h */
struct rt_sigcontext {
unsigned long trap_no;
unsigned long error_code;
unsigned long oldmask;
unsigned long arm_r0;
unsigned long arm_r1;
unsigned long arm_r2;
unsigned long arm_r3;
unsigned long arm_r4;
unsigned long arm_r5;
unsigned long arm_r6;
unsigned long arm_r7;
unsigned long arm_r8;
unsigned long arm_r9;
unsigned long arm_r10;
unsigned long arm_fp;
unsigned long arm_ip;
unsigned long arm_sp;
unsigned long arm_lr;
unsigned long arm_pc;
unsigned long arm_cpsr;
unsigned long fault_address;
};
/* Copied from the Linux kernel header arch/arm/include/asm/ucontext.h */
#define VFP_MAGIC 0x56465001
#define VFP_STORAGE_SIZE sizeof(struct vfp_sigframe)
struct vfp_sigframe {
unsigned long magic;
unsigned long size;
struct user_vfp ufp;
struct user_vfp_exc ufp_exc;
};
typedef struct vfp_sigframe fpu_state_t;
struct aux_sigframe {
/*
struct crunch_sigframe crunch;
struct iwmmxt_sigframe iwmmxt;
*/
struct vfp_sigframe vfp;
unsigned long end_magic;
} __attribute__((__aligned__(8)));
#include "sigframe.h"
struct sigframe {
struct rt_ucontext uc;
unsigned long retcode[2];
};
struct rt_sigframe {
struct rt_siginfo info;
struct sigframe sig;
};
#define ARCH_RT_SIGRETURN(new_sp) \
asm volatile( \
"mov sp, %0 \n" \
"mov r7, #"__stringify(__NR_rt_sigreturn)" \n" \
"svc #0 \n" \
: \
: "r"(new_sp) \
: "sp","memory")
#define RUN_CLONE_RESTORE_FN(ret, clone_flags, new_sp, parent_tid, \
thread_args, clone_restore_fn) \
asm volatile( \
......@@ -123,25 +53,11 @@ struct rt_sigframe {
: "memory")
#define RT_SIGFRAME_UC(rt_sigframe) (&rt_sigframe->sig.uc)
#define RT_SIGFRAME_REGIP(rt_sigframe) (rt_sigframe)->sig.uc.uc_mcontext.arm_ip
#define RT_SIGFRAME_HAS_FPU(rt_sigframe) 1
#define RT_SIGFRAME_AUX_SIGFRAME(rt_sigframe) \
((struct aux_sigframe *)&(rt_sigframe)->sig.uc.uc_regspace)
#define RT_SIGFRAME_FPU(rt_sigframe) \
(&RT_SIGFRAME_AUX_SIGFRAME(rt_sigframe)->vfp)
#define RT_SIGFRAME_OFFSET(rt_sigframe) 0
int restore_gpregs(struct rt_sigframe *f, UserArmRegsEntry *r);
int restore_nonsigframe_gpregs(UserArmRegsEntry *r);
static inline int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe)
{
return 0;
}
static inline void restore_tls(tls_t *ptls) {
asm (
"mov r7, #15 \n"
......
#ifndef UAPI_COMPEL_ASM_SIGFRAME_H__
#define UAPI_COMPEL_ASM_SIGFRAME_H__
/* Copied from the Linux kernel header arch/arm/include/asm/sigcontext.h */
struct rt_sigcontext {
unsigned long trap_no;
unsigned long error_code;
unsigned long oldmask;
unsigned long arm_r0;
unsigned long arm_r1;
unsigned long arm_r2;
unsigned long arm_r3;
unsigned long arm_r4;
unsigned long arm_r5;
unsigned long arm_r6;
unsigned long arm_r7;
unsigned long arm_r8;
unsigned long arm_r9;
unsigned long arm_r10;
unsigned long arm_fp;
unsigned long arm_ip;
unsigned long arm_sp;
unsigned long arm_lr;
unsigned long arm_pc;
unsigned long arm_cpsr;
unsigned long fault_address;
};
/* Copied from the Linux kernel header arch/arm/include/asm/ucontext.h */
#define VFP_MAGIC 0x56465001
#define VFP_STORAGE_SIZE sizeof(struct vfp_sigframe)
struct vfp_sigframe {
unsigned long magic;
unsigned long size;
struct user_vfp ufp;
struct user_vfp_exc ufp_exc;
};
typedef struct vfp_sigframe fpu_state_t;
struct aux_sigframe {
/*
struct crunch_sigframe crunch;
struct iwmmxt_sigframe iwmmxt;
*/
struct vfp_sigframe vfp;
unsigned long end_magic;
} __attribute__((aligned(8)));
#include "sigframe-common.h"
struct sigframe {
struct rt_ucontext uc;
unsigned long retcode[2];
};
struct rt_sigframe {
struct rt_siginfo info;
struct sigframe sig;
};
#define ARCH_RT_SIGRETURN(new_sp) \
asm volatile( \
"mov sp, %0 \n" \
"mov r7, #"__stringify(__NR_rt_sigreturn)" \n" \
"svc #0 \n" \
: \
: "r"(new_sp) \
: "sp","memory")
#define RT_SIGFRAME_UC(rt_sigframe) (&rt_sigframe->sig.uc)
#define RT_SIGFRAME_REGIP(rt_sigframe) (rt_sigframe)->sig.uc.uc_mcontext.arm_ip
#define RT_SIGFRAME_HAS_FPU(rt_sigframe) 1
#define RT_SIGFRAME_AUX_SIGFRAME(rt_sigframe) ((struct aux_sigframe *)&(rt_sigframe)->sig.uc.uc_regspace)
#define RT_SIGFRAME_FPU(rt_sigframe) (&RT_SIGFRAME_AUX_SIGFRAME(rt_sigframe)->vfp)
#define RT_SIGFRAME_OFFSET(rt_sigframe) 0
#endif /* UAPI_COMPEL_ASM_SIGFRAME_H__ */
#include "asm/types.h"
#include "asm/sigframe.h"
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe)
{
return 0;
}
......@@ -5,3 +5,4 @@ ccflags-y += -iquote $(SRC_DIR)/criu/include -iquote $(SRC_DIR)/include
obj-y += cpu.o
obj-y += crtools.o
obj-y += sigframe.o
......@@ -22,14 +22,6 @@
#include "images/core.pb-c.h"
#include "images/creds.pb-c.h"
#define MSR_TMA (1UL<<34) /* bit 29 Trans Mem state: Transactional */
#define MSR_TMS (1UL<<33) /* bit 30 Trans Mem state: Suspended */
#define MSR_TM (1UL<<32) /* bit 31 Trans Mem Available */
#define MSR_VEC (1UL<<25)
#define MSR_VSX (1UL<<23)
#define MSR_TM_ACTIVE(x) ((((x) & MSR_TM) && ((x)&(MSR_TMA|MSR_TMS))) != 0)
#ifndef NT_PPC_TM_SPR
#define NT_PPC_TM_CGPR 0x108 /* TM checkpointed GPR Registers */
#define NT_PPC_TM_CFPR 0x109 /* TM checkpointed FPR Registers */
......@@ -792,46 +784,6 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
return ret;
}
/*
* The signal frame has been built using local addresses. Since it has to be
* used in the context of the checkpointed process, the v_regs pointer in the
* signal frame must be updated to match the address in the remote stack.
*/
static inline void update_vregs(mcontext_t *lcontext, mcontext_t *rcontext)
{
if (lcontext->v_regs) {
uint64_t offset = (uint64_t)(lcontext->v_regs) - (uint64_t)lcontext;
lcontext->v_regs = (vrregset_t *)((uint64_t)rcontext + offset);
pr_debug("Updated v_regs:%llx (rcontext:%llx)\n",
(unsigned long long) lcontext->v_regs,
(unsigned long long) rcontext);
}
}
int sigreturn_prep_fpu_frame(struct rt_sigframe *frame,
struct rt_sigframe *rframe)
{
uint64_t msr = frame->uc.uc_mcontext.gp_regs[PT_MSR];
update_vregs(&frame->uc.uc_mcontext, &rframe->uc.uc_mcontext);
/* Sanity check: If TM so uc_link should be set, otherwise not */
if (MSR_TM_ACTIVE(msr) ^ (!!(frame->uc.uc_link))) {
BUG();
return 1;
}
/* Updating the transactional state address if any */
if (frame->uc.uc_link) {
update_vregs(&frame->uc_transact.uc_mcontext,
&rframe->uc_transact.uc_mcontext);
frame->uc.uc_link = &rframe->uc_transact;
}
return 0;
}
int restore_gpregs(struct rt_sigframe *f, UserPpc64RegsEntry *r)
{
restore_gp_regs(&f->uc.uc_mcontext, r);
......
......@@ -6,62 +6,13 @@
#include <asm/types.h>
#include "asm/types.h"
/*
* sigcontext structure defined in file
* /usr/include/powerpc64le-linux-gnu/bits/sigcontext.h,
* included from /usr/include/signal.h
*
* Kernel definition can be found in arch/powerpc/include/uapi/asm/sigcontext.h
*/
#include <signal.h>
// XXX: the idetifier rt_sigcontext is expected to be struct by the CRIU code
#define rt_sigcontext sigcontext
#include "sigframe.h"
#define RT_SIGFRAME_OFFSET(rt_sigframe) 0
/* Copied from the Linux kernel header arch/powerpc/include/asm/ptrace.h */
#define USER_REDZONE_SIZE 512
/* Copied from the Linux kernel source file arch/powerpc/kernel/signal_64.c */
#define TRAMP_SIZE 6
/*
* ucontext defined in /usr/include/powerpc64le-linux-gnu/sys/ucontext.h
*/
struct rt_sigframe {
/* sys_rt_sigreturn requires the ucontext be the first field */
struct ucontext uc;
struct ucontext uc_transact; /* Transactional state */
unsigned long _unused[2];
unsigned int tramp[TRAMP_SIZE];
struct rt_siginfo *pinfo;
void *puc;
struct rt_siginfo info;
/* New 64 bit little-endian ABI allows redzone of 512 bytes below sp */
char abigap[USER_REDZONE_SIZE];
} __attribute__ ((aligned (16)));
#define ARCH_RT_SIGRETURN(new_sp) \
asm volatile( \
"mr 1, %0 \n" \
"li 0, "__stringify(__NR_rt_sigreturn)" \n" \
"sc \n" \
: \
: "r"(new_sp) \
: "1", "memory")
/*
* Clone trampoline
*
* See glibc sysdeps/powerpc/powerpc64/sysdep.h for FRAME_MIN_SIZE defines
*/
#if _CALL_ELF != 2
#error Only supporting ABIv2.
#else
#define FRAME_MIN_SIZE_PARM 96
#endif
#define RUN_CLONE_RESTORE_FN(ret, clone_flags, new_sp, parent_tid, \
thread_args, clone_restore_fn) \
asm volatile( \
......@@ -96,10 +47,6 @@ struct rt_sigframe {
"r"(&thread_args[i]) /* %6 */ \
: "memory","0","3","4","5","6","7","14","15")
#define RT_SIGFRAME_UC(rt_sigframe) (&(rt_sigframe)->uc)
#define RT_SIGFRAME_REGIP(rt_sigframe) ((long unsigned int)(rt_sigframe)->uc.uc_mcontext.gp_regs[PT_NIP])
#define RT_SIGFRAME_HAS_FPU(rt_sigframe) (1)
#define RT_SIGFRAME_FPU(rt_sigframe) (&(rt_sigframe)->uc.uc_mcontext)
int restore_gpregs(struct rt_sigframe *f, UserPpc64RegsEntry *r);
int restore_nonsigframe_gpregs(UserPpc64RegsEntry *r);
......@@ -117,9 +64,6 @@ static inline int ptrace_flush_breakpoints(pid_t pid)
return 0;
}
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
struct rt_sigframe *rframe);
/*
* Defined in arch/ppc64/syscall-common-ppc64.S
*/
......
#ifndef UAPI_COMPEL_ASM_SIGFRAME_H__
#define UAPI_COMPEL_ASM_SIGFRAME_H__
#include <asm/ptrace.h>
#include <asm/elf.h>
#include <asm/types.h>
/*
* sigcontext structure defined in file
* /usr/include/powerpc64le-linux-gnu/bits/sigcontext.h,
* included from /usr/include/signal.h
*
* Kernel definition can be found in arch/powerpc/include/uapi/asm/sigcontext.h
*/
#include <signal.h>
// XXX: the idetifier rt_sigcontext is expected to be struct by the CRIU code
#define rt_sigcontext sigcontext
#include "sigframe-common.h"
#define RT_SIGFRAME_OFFSET(rt_sigframe) 0
/* Copied from the Linux kernel header arch/powerpc/include/asm/ptrace.h */
#define USER_REDZONE_SIZE 512
/* Copied from the Linux kernel source file arch/powerpc/kernel/signal_64.c */
#define TRAMP_SIZE 6
/*
* ucontext defined in /usr/include/powerpc64le-linux-gnu/sys/ucontext.h
*/
struct rt_sigframe {
/* sys_rt_sigreturn requires the ucontext be the first field */
struct ucontext uc;
struct ucontext uc_transact; /* Transactional state */
unsigned long _unused[2];
unsigned int tramp[TRAMP_SIZE];
struct rt_siginfo *pinfo;
void *puc;
struct rt_siginfo info;
/* New 64 bit little-endian ABI allows redzone of 512 bytes below sp */
char abigap[USER_REDZONE_SIZE];
} __attribute__((aligned(16)));
#define ARCH_RT_SIGRETURN(new_sp) \
asm volatile( \
"mr 1, %0 \n" \
"li 0, "__stringify(__NR_rt_sigreturn)" \n" \
"sc \n" \
: \
: "r"(new_sp) \
: "1", "memory")
#if _CALL_ELF != 2
# error Only supporting ABIv2.
#else
# define FRAME_MIN_SIZE_PARM 96
#endif
#define RT_SIGFRAME_UC(rt_sigframe) (&(rt_sigframe)->uc)
#define RT_SIGFRAME_REGIP(rt_sigframe) ((long unsigned int)(rt_sigframe)->uc.uc_mcontext.gp_regs[PT_NIP])
#define RT_SIGFRAME_HAS_FPU(rt_sigframe) (1)
#define RT_SIGFRAME_FPU(rt_sigframe) (&(rt_sigframe)->uc.uc_mcontext)
#define MSR_TMA (1UL<<34) /* bit 29 Trans Mem state: Transactional */
#define MSR_TMS (1UL<<33) /* bit 30 Trans Mem state: Suspended */
#define MSR_TM (1UL<<32) /* bit 31 Trans Mem Available */
#define MSR_VEC (1UL<<25)
#define MSR_VSX (1UL<<23)
#define MSR_TM_ACTIVE(x) ((((x) & MSR_TM) && ((x)&(MSR_TMA|MSR_TMS))) != 0)
#endif /* UAPI_COMPEL_ASM_SIGFRAME_H__ */
#include <stdlib.h>
#include <stdint.h>
#include "asm/sigframe.h"
#include "asm/types.h"
#include "log.h"
#include "common/bug.h"
/*
* The signal frame has been built using local addresses. Since it has to be
* used in the context of the checkpointed process, the v_regs pointer in the
* signal frame must be updated to match the address in the remote stack.
*/
static inline void update_vregs(mcontext_t *lcontext, mcontext_t *rcontext)
{
if (lcontext->v_regs) {
uint64_t offset = (uint64_t)(lcontext->v_regs) - (uint64_t)lcontext;
lcontext->v_regs = (vrregset_t *)((uint64_t)rcontext + offset);
pr_debug("Updated v_regs:%llx (rcontext:%llx)\n",
(unsigned long long) lcontext->v_regs,
(unsigned long long) rcontext);
}
}
int sigreturn_prep_fpu_frame(struct rt_sigframe *frame,
struct rt_sigframe *rframe)
{
uint64_t msr = frame->uc.uc_mcontext.gp_regs[PT_MSR];
update_vregs(&frame->uc.uc_mcontext, &rframe->uc.uc_mcontext);
/* Sanity check: If TM so uc_link should be set, otherwise not */
if (MSR_TM_ACTIVE(msr) ^ (!!(frame->uc.uc_link))) {
BUG();
return 1;
}
/* Updating the transactional state address if any */
if (frame->uc.uc_link) {
update_vregs(&frame->uc_transact.uc_mcontext,
&rframe->uc_transact.uc_mcontext);
frame->uc.uc_link = &rframe->uc_transact;
}
return 0;
}
......@@ -5,3 +5,4 @@ ccflags-y += -iquote $(SRC_DIR)/criu/include -iquote $(SRC_DIR)/include
obj-y += cpu.o
obj-y += crtools.o
obj-y += sigframe.o
......@@ -501,22 +501,6 @@ int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r)
return 0;
}
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe)
{
fpu_state_t *fpu_state = RT_SIGFRAME_FPU(rsigframe);
unsigned long addr = (unsigned long)(void *)&fpu_state->xsave;
if ((addr % 64ul) == 0ul) {
sigframe->uc.uc_mcontext.fpstate = &fpu_state->xsave;
} else {
pr_err("Unaligned address passed: %lx\n", addr);
return -1;
}
return 0;
}
/* Copied from the gdb header gdb/nat/x86-dregs.h */
/* Debug registers' indices. */
......
......@@ -5,60 +5,9 @@
#include "asm/fpu.h"
#include "images/core.pb-c.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 ss;
unsigned long err;
unsigned long trapno;
unsigned long oldmask;
unsigned long cr2;
void *fpstate;
unsigned long reserved1[8];
};
#define SIGFRAME_MAX_OFFSET 8
#include "sigframe.h"
struct rt_sigframe {
char *pretcode;
struct rt_ucontext uc;
struct rt_siginfo info;
fpu_state_t fpu_state;
};
#ifdef CONFIG_X86_64
#define ARCH_RT_SIGRETURN(new_sp) \
asm volatile( \
"movq %0, %%rax \n" \
"movq %%rax, %%rsp \n" \
"movl $"__stringify(__NR_rt_sigreturn)", %%eax \n" \
"syscall \n" \
: \
: "r"(new_sp) \
: "rax","rsp","memory")
#define RUN_CLONE_RESTORE_FN(ret, clone_flags, new_sp, parent_tid, \
thread_args, clone_restore_fn) \
asm volatile( \
......@@ -106,16 +55,6 @@ struct rt_sigframe {
: "r"(ret) \
: "memory")
#else /* CONFIG_X86_64 */
#define ARCH_RT_SIGRETURN(new_sp) \
asm volatile( \
"movl %0, %%eax \n" \
"movl %%eax, %%esp \n" \
"movl $"__stringify(__NR_rt_sigreturn)", %%eax \n" \
"int $0x80 \n" \
: \
: "r"(new_sp) \
: "eax","esp","memory")
#define RUN_CLONE_RESTORE_FN(ret, clone_flags, new_sp, parent_tid, \
thread_args, clone_restore_fn) \
(void)ret; \
......@@ -135,19 +74,9 @@ struct rt_sigframe {
: "memory")
#endif /* CONFIG_X86_64 */
#define RT_SIGFRAME_UC(rt_sigframe) (&rt_sigframe->uc)
#define RT_SIGFRAME_REGIP(rt_sigframe) (rt_sigframe)->uc.uc_mcontext.rip
#define RT_SIGFRAME_FPU(rt_sigframe) (&(rt_sigframe)->fpu_state)
#define RT_SIGFRAME_HAS_FPU(rt_sigframe) (RT_SIGFRAME_FPU(rt_sigframe)->has_fpu)
#define RT_SIGFRAME_OFFSET(rt_sigframe) 8
int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r);
int restore_nonsigframe_gpregs(UserX86RegsEntry *r);
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe);
static inline void restore_tls(tls_t *ptls) { (void)ptls; }
int ptrace_set_breakpoint(pid_t pid, void *addr);
......
#ifndef UAPI_COMPEL_ASM_SIGFRAME_H__
#define UAPI_COMPEL_ASM_SIGFRAME_H__
#include <stdint.h>
#include <stdbool.h>
#include "asm/fpu.h"
#define SIGFRAME_MAX_OFFSET 8
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 ss;
unsigned long err;
unsigned long trapno;
unsigned long oldmask;
unsigned long cr2;
void *fpstate;
unsigned long reserved1[8];
};
#include "sigframe-common.h"
struct rt_sigframe {
char *pretcode;
struct rt_ucontext uc;
struct rt_siginfo info;
fpu_state_t fpu_state;
};
#define RT_SIGFRAME_UC(rt_sigframe) (&rt_sigframe->uc)
#define RT_SIGFRAME_REGIP(rt_sigframe) (rt_sigframe)->uc.uc_mcontext.rip
#define RT_SIGFRAME_FPU(rt_sigframe) (&(rt_sigframe)->fpu_state)
#define RT_SIGFRAME_HAS_FPU(rt_sigframe) (RT_SIGFRAME_FPU(rt_sigframe)->has_fpu)
#define RT_SIGFRAME_OFFSET(rt_sigframe) 8
#ifdef CONFIG_X86_64
#define ARCH_RT_SIGRETURN(new_sp) \
asm volatile( \
"movq %0, %%rax \n" \
"movq %%rax, %%rsp \n" \
"movl $"__stringify(__NR_rt_sigreturn)", %%eax \n" \
"syscall \n" \
: \
: "r"(new_sp) \
: "rax","rsp","memory")
#else /* CONFIG_X86_64 */
#define ARCH_RT_SIGRETURN(new_sp) \
asm volatile( \
"movl %0, %%eax \n" \
"movl %%eax, %%esp \n" \
"movl $"__stringify(__NR_rt_sigreturn)", %%eax \n" \
"int $0x80 \n" \
: \
: "r"(new_sp) \
: "eax","esp","memory")
#endif /* CONFIG_X86_64 */
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe);
#endif /* UAPI_COMPEL_ASM_SIGFRAME_H__ */
#include <stdlib.h>
#include <stdint.h>
#include "asm/sigframe.h"
#include "asm/types.h"
#include "log.h"
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe)
{
fpu_state_t *fpu_state = RT_SIGFRAME_FPU(rsigframe);
unsigned long addr = (unsigned long)(void *)&fpu_state->xsave;
if ((addr % 64ul) == 0ul) {
sigframe->uc.uc_mcontext.fpstate = &fpu_state->xsave;
} else {
pr_err("Unaligned address passed: %lx\n", addr);
return -1;
}
return 0;
}
......@@ -74,6 +74,7 @@
#include "seccomp.h"
#include "fault-injection.h"
#include "sk-queue.h"
#include "sigframe.h"
#include "parasite-syscall.h"
#include "files-reg.h"
......
/*
* Don't include it directly but use "arch-sigframe.h" instead.
*/
#ifndef UAPI_COMPEL_SIGFRAME_COMMON_H__
#define UAPI_COMPEL_SIGFRAME_COMMON_H__
#ifndef UAPI_COMPEL_ASM_SIGFRAME_H__
# error "Direct inclusion is forbidden, use <compel/asm/sigframe.h> instead"
#endif
#include <signal.h>
#include "syscall-types.h"
#include "asm/types.h"
struct rt_sigframe;
#ifndef SIGFRAME_MAX_OFFSET
# define SIGFRAME_MAX_OFFSET RT_SIGFRAME_OFFSET(0)
#endif
#define RESTORE_STACK_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
/* sigframe should be aligned on 64 byte for x86 and 8 bytes for arm */
#define RESTORE_STACK_SIGFRAME \
RESTORE_STACK_ALIGN(sizeof(struct rt_sigframe) + SIGFRAME_MAX_OFFSET, 64)
#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;
k_rtsigset_t uc_sigmask; /* mask last for extensibility */
int __unused[32 - (sizeof (k_rtsigset_t) / sizeof (int))];
unsigned long uc_regspace[128] __attribute__((aligned(8)));
};
extern int sigreturn_prep_fpu_frame(struct rt_sigframe *frame,
struct rt_sigframe *rframe);
#endif /* UAPI_COMPEL_SIGFRAME_COMMON_H__ */
......@@ -5,50 +5,9 @@
#ifndef __CR_SIGFRAME_H__
#define __CR_SIGFRAME_H__
#include "asm/sigframe.h"
#include "images/core.pb-c.h"
struct rt_sigframe;
#ifndef SIGFRAME_MAX_OFFSET
#define SIGFRAME_MAX_OFFSET RT_SIGFRAME_OFFSET(0)
#endif
/* sigframe should be aligned on 64 byte for x86 and 8 bytes for arm */
#define RESTORE_STACK_SIGFRAME \
ALIGN(sizeof(struct rt_sigframe) + SIGFRAME_MAX_OFFSET, 64)
#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;
k_rtsigset_t uc_sigmask; /* mask last for extensibility */
int __unused[32 - (sizeof (k_rtsigset_t) / sizeof (int))];
unsigned long uc_regspace[128] __attribute__((__aligned__(8)));
};
extern int construct_sigframe(struct rt_sigframe *sigframe,
struct rt_sigframe *rsigframe,
k_rtsigset_t *blkset,
......
......@@ -32,6 +32,7 @@
#include "fault-injection.h"
#include "syscall-codes.h"
#include "signal.h"
#include "sigframe.h"
#include <string.h>
#include <stdlib.h>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment