mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-01-23 10:16:41 +00:00
Customize AArch64 VDSO code
This modifies the x86 VDSO code to work on AArch64. Signed-off-by: Christopher Covington <cov@codeaurora.org> Acked-by: Cyrill Gorcunov <gorcunov@openvz.org> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
parent
99e0a0ccae
commit
cf219f9284
7 changed files with 50 additions and 26 deletions
6
Makefile
6
Makefile
|
|
@ -72,6 +72,9 @@ ifeq ($(shell echo $(ARCH) | sed -e 's/arm.*/arm/'),arm)
|
|||
USERCFLAGS += -march=armv7-a
|
||||
endif
|
||||
endif
|
||||
ifeq ($(ARCH),aarch64)
|
||||
VDSO := y
|
||||
endif
|
||||
|
||||
SRCARCH ?= $(ARCH)
|
||||
LDARCH ?= $(SRCARCH)
|
||||
|
|
@ -175,6 +178,9 @@ ifeq ($(VDSO),y)
|
|||
$(ARCH_DIR)/vdso-pie.o: pie
|
||||
$(Q) $(MAKE) $(build)=pie $(ARCH_DIR)/vdso-pie.o
|
||||
PROGRAM-BUILTINS += $(ARCH_DIR)/vdso-pie.o
|
||||
ifeq ($(SRCARCH),aarch64)
|
||||
PROGRAM-BUILTINS += $(ARCH_DIR)/intraprocedure.o
|
||||
endif
|
||||
endif
|
||||
|
||||
PROGRAM-BUILTINS += pie/util-fd.o
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef __CR_ASM_PARASITE_SYSCALL_H__
|
||||
#define __CR_ASM_PARASITE_SYSCALL_H__
|
||||
|
||||
struct parasite_ctl;
|
||||
|
||||
#define ARCH_SI_TRAP TRAP_BRKPT
|
||||
|
||||
|
|
@ -8,7 +9,6 @@
|
|||
extern const char code_syscall[];
|
||||
extern const int code_syscall_size;
|
||||
|
||||
|
||||
void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs);
|
||||
|
||||
void *mmap_seized(struct parasite_ctl *ctl,
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@ static inline bool vdso_symbol_empty(struct vdso_symbol *s)
|
|||
* we should support at the moment.
|
||||
*/
|
||||
enum {
|
||||
VDSO_SYMBOL_CLOCK_GETRES,
|
||||
VDSO_SYMBOL_CLOCK_GETTIME,
|
||||
VDSO_SYMBOL_GETCPU,
|
||||
VDSO_SYMBOL_GETTIMEOFDAY,
|
||||
VDSO_SYMBOL_TIME,
|
||||
VDSO_SYMBOL_RT_SIGRETURN,
|
||||
|
||||
VDSO_SYMBOL_MAX
|
||||
};
|
||||
|
|
@ -135,12 +135,10 @@ static inline bool is_vdso_mark(void *addr)
|
|||
return false;
|
||||
}
|
||||
|
||||
#define VDSO_SYMBOL_CLOCK_GETTIME_NAME "__vdso_clock_gettime"
|
||||
#define VDSO_SYMBOL_GETCPU_NAME "__vdso_getcpu"
|
||||
#define VDSO_SYMBOL_GETTIMEOFDAY_NAME "__vdso_gettimeofday"
|
||||
#define VDSO_SYMBOL_TIME_NAME "__vdso_time"
|
||||
|
||||
|
||||
#define VDSO_SYMBOL_CLOCK_GETRES_NAME "__kernel_clock_getres"
|
||||
#define VDSO_SYMBOL_CLOCK_GETTIME_NAME "__kernel_clock_gettime"
|
||||
#define VDSO_SYMBOL_GETTIMEOFDAY_NAME "__kernel_gettimeofday"
|
||||
#define VDSO_SYMBOL_RT_SIGRETURN_NAME "__kernel_rt_sigreturn"
|
||||
|
||||
extern struct vdso_symtable vdso_sym_rt;
|
||||
extern u64 vdso_pfn;
|
||||
|
|
@ -155,5 +153,6 @@ extern int vdso_proxify(char *who, struct vdso_symtable *sym_rt,
|
|||
extern int vdso_redirect_calls(void *base_to, void *base_from, struct vdso_symtable *to, struct vdso_symtable *from);
|
||||
extern int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
|
||||
struct vm_area_list *vma_area_list);
|
||||
extern void write_intraprocedure_branch(void *to, void *from);
|
||||
|
||||
#endif /* __CR_ASM_VDSO_H__ */
|
||||
|
|
|
|||
22
arch/aarch64/intraprocedure.S
Normal file
22
arch/aarch64/intraprocedure.S
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
.global write_intraprocedure_branch
|
||||
|
||||
/* to is x0, from is x1 */
|
||||
write_intraprocedure_branch:
|
||||
/* load two 32-bit instructions */
|
||||
ldr x2, loadbranch
|
||||
/* store 64 bits of instructions and 64 bits of destination address */
|
||||
stp x2, x0, [x1]
|
||||
/* perform required cache maintenance and synronization operations */
|
||||
dc cvau, x1
|
||||
dsb ish
|
||||
ic ivau, x1
|
||||
dsb ish
|
||||
isb
|
||||
ret
|
||||
|
||||
/* intraprocedure trampoline instructions */
|
||||
loadbranch:
|
||||
ldr x16, =destination
|
||||
br x16
|
||||
/* label to get relative position of literal pool */
|
||||
destination:
|
||||
|
|
@ -26,34 +26,22 @@
|
|||
#endif
|
||||
#define LOG_PREFIX "vdso: "
|
||||
|
||||
typedef struct {
|
||||
u16 movabs;
|
||||
u64 imm64;
|
||||
u16 jmp_rax;
|
||||
u32 guards;
|
||||
} __packed jmp_t;
|
||||
|
||||
int vdso_redirect_calls(void *base_to, void *base_from,
|
||||
struct vdso_symtable *to,
|
||||
struct vdso_symtable *from)
|
||||
{
|
||||
jmp_t jmp = {
|
||||
.movabs = 0xb848,
|
||||
.jmp_rax = 0xe0ff,
|
||||
.guards = 0xcccccccc,
|
||||
};
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(to->symbols); i++) {
|
||||
if (vdso_symbol_empty(&from->symbols[i]))
|
||||
continue;
|
||||
|
||||
pr_debug("jmp: %lx/%lx -> %lx/%lx (index %d)\n",
|
||||
pr_debug("br: %lx/%lx -> %lx/%lx (index %d)\n",
|
||||
(unsigned long)base_from, from->symbols[i].offset,
|
||||
(unsigned long)base_to, to->symbols[i].offset, i);
|
||||
|
||||
jmp.imm64 = (unsigned long)base_to + to->symbols[i].offset;
|
||||
builtin_memcpy((void *)(base_from + from->symbols[i].offset), &jmp, sizeof(jmp));
|
||||
write_intraprocedure_branch(base_to + to->symbols[i].offset,
|
||||
base_from + from->symbols[i].offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -109,10 +97,10 @@ int vdso_fill_symtable(char *mem, size_t size, struct vdso_symtable *t)
|
|||
};
|
||||
|
||||
const char *vdso_symbols[VDSO_SYMBOL_MAX] = {
|
||||
[VDSO_SYMBOL_CLOCK_GETRES] = VDSO_SYMBOL_CLOCK_GETRES_NAME,
|
||||
[VDSO_SYMBOL_CLOCK_GETTIME] = VDSO_SYMBOL_CLOCK_GETTIME_NAME,
|
||||
[VDSO_SYMBOL_GETCPU] = VDSO_SYMBOL_GETCPU_NAME,
|
||||
[VDSO_SYMBOL_GETTIMEOFDAY] = VDSO_SYMBOL_GETTIMEOFDAY_NAME,
|
||||
[VDSO_SYMBOL_TIME] = VDSO_SYMBOL_TIME_NAME,
|
||||
[VDSO_SYMBOL_RT_SIGRETURN] = VDSO_SYMBOL_RT_SIGRETURN_NAME,
|
||||
};
|
||||
|
||||
char *dynsymbol_names;
|
||||
|
|
|
|||
|
|
@ -81,6 +81,12 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
|
|||
if ((vma->e->prot & VDSO_PROT) != VDSO_PROT)
|
||||
continue;
|
||||
|
||||
if (vma->e->prot != VDSO_PROT) {
|
||||
pr_debug("Dropping %lx using extra protection test\n",
|
||||
vma->e->start);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vma->e->start > TASK_SIZE)
|
||||
continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ obj-y += util-fd.o
|
|||
|
||||
ifeq ($(VDSO),y)
|
||||
obj-e += $(ARCH_DIR)/vdso-pie.o
|
||||
ifeq ($(SRCARCH),aarch64)
|
||||
asm-e += $(ARCH_DIR)/intraprocedure.o
|
||||
endif
|
||||
endif
|
||||
|
||||
parasite-obj-y += parasite.o
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue