Commit cf219f92 authored by Christopher Covington's avatar Christopher Covington Committed by Pavel Emelyanov

Customize AArch64 VDSO code

This modifies the x86 VDSO code to work on AArch64.
Signed-off-by: 's avatarChristopher Covington <cov@codeaurora.org>
Acked-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 99e0a0cc
......@@ -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
......
#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__ */
.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
......
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