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) ...@@ -72,6 +72,9 @@ ifeq ($(shell echo $(ARCH) | sed -e 's/arm.*/arm/'),arm)
USERCFLAGS += -march=armv7-a USERCFLAGS += -march=armv7-a
endif endif
endif endif
ifeq ($(ARCH),aarch64)
VDSO := y
endif
SRCARCH ?= $(ARCH) SRCARCH ?= $(ARCH)
LDARCH ?= $(SRCARCH) LDARCH ?= $(SRCARCH)
...@@ -175,6 +178,9 @@ ifeq ($(VDSO),y) ...@@ -175,6 +178,9 @@ ifeq ($(VDSO),y)
$(ARCH_DIR)/vdso-pie.o: pie $(ARCH_DIR)/vdso-pie.o: pie
$(Q) $(MAKE) $(build)=pie $(ARCH_DIR)/vdso-pie.o $(Q) $(MAKE) $(build)=pie $(ARCH_DIR)/vdso-pie.o
PROGRAM-BUILTINS += $(ARCH_DIR)/vdso-pie.o PROGRAM-BUILTINS += $(ARCH_DIR)/vdso-pie.o
ifeq ($(SRCARCH),aarch64)
PROGRAM-BUILTINS += $(ARCH_DIR)/intraprocedure.o
endif
endif endif
PROGRAM-BUILTINS += pie/util-fd.o PROGRAM-BUILTINS += pie/util-fd.o
......
#ifndef __CR_ASM_PARASITE_SYSCALL_H__ #ifndef __CR_ASM_PARASITE_SYSCALL_H__
#define __CR_ASM_PARASITE_SYSCALL_H__ #define __CR_ASM_PARASITE_SYSCALL_H__
struct parasite_ctl;
#define ARCH_SI_TRAP TRAP_BRKPT #define ARCH_SI_TRAP TRAP_BRKPT
...@@ -8,7 +9,6 @@ ...@@ -8,7 +9,6 @@
extern const char code_syscall[]; extern const char code_syscall[];
extern const int code_syscall_size; extern const int code_syscall_size;
void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs); void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs);
void *mmap_seized(struct parasite_ctl *ctl, void *mmap_seized(struct parasite_ctl *ctl,
......
...@@ -35,10 +35,10 @@ static inline bool vdso_symbol_empty(struct vdso_symbol *s) ...@@ -35,10 +35,10 @@ static inline bool vdso_symbol_empty(struct vdso_symbol *s)
* we should support at the moment. * we should support at the moment.
*/ */
enum { enum {
VDSO_SYMBOL_CLOCK_GETRES,
VDSO_SYMBOL_CLOCK_GETTIME, VDSO_SYMBOL_CLOCK_GETTIME,
VDSO_SYMBOL_GETCPU,
VDSO_SYMBOL_GETTIMEOFDAY, VDSO_SYMBOL_GETTIMEOFDAY,
VDSO_SYMBOL_TIME, VDSO_SYMBOL_RT_SIGRETURN,
VDSO_SYMBOL_MAX VDSO_SYMBOL_MAX
}; };
...@@ -135,12 +135,10 @@ static inline bool is_vdso_mark(void *addr) ...@@ -135,12 +135,10 @@ static inline bool is_vdso_mark(void *addr)
return false; return false;
} }
#define VDSO_SYMBOL_CLOCK_GETTIME_NAME "__vdso_clock_gettime" #define VDSO_SYMBOL_CLOCK_GETRES_NAME "__kernel_clock_getres"
#define VDSO_SYMBOL_GETCPU_NAME "__vdso_getcpu" #define VDSO_SYMBOL_CLOCK_GETTIME_NAME "__kernel_clock_gettime"
#define VDSO_SYMBOL_GETTIMEOFDAY_NAME "__vdso_gettimeofday" #define VDSO_SYMBOL_GETTIMEOFDAY_NAME "__kernel_gettimeofday"
#define VDSO_SYMBOL_TIME_NAME "__vdso_time" #define VDSO_SYMBOL_RT_SIGRETURN_NAME "__kernel_rt_sigreturn"
extern struct vdso_symtable vdso_sym_rt; extern struct vdso_symtable vdso_sym_rt;
extern u64 vdso_pfn; extern u64 vdso_pfn;
...@@ -155,5 +153,6 @@ extern int vdso_proxify(char *who, struct vdso_symtable *sym_rt, ...@@ -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 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, extern int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
struct vm_area_list *vma_area_list); struct vm_area_list *vma_area_list);
extern void write_intraprocedure_branch(void *to, void *from);
#endif /* __CR_ASM_VDSO_H__ */ #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 @@ ...@@ -26,34 +26,22 @@
#endif #endif
#define LOG_PREFIX "vdso: " #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, int vdso_redirect_calls(void *base_to, void *base_from,
struct vdso_symtable *to, struct vdso_symtable *to,
struct vdso_symtable *from) struct vdso_symtable *from)
{ {
jmp_t jmp = {
.movabs = 0xb848,
.jmp_rax = 0xe0ff,
.guards = 0xcccccccc,
};
unsigned int i; unsigned int i;
for (i = 0; i < ARRAY_SIZE(to->symbols); i++) { for (i = 0; i < ARRAY_SIZE(to->symbols); i++) {
if (vdso_symbol_empty(&from->symbols[i])) if (vdso_symbol_empty(&from->symbols[i]))
continue; 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_from, from->symbols[i].offset,
(unsigned long)base_to, to->symbols[i].offset, i); (unsigned long)base_to, to->symbols[i].offset, i);
jmp.imm64 = (unsigned long)base_to + to->symbols[i].offset; write_intraprocedure_branch(base_to + to->symbols[i].offset,
builtin_memcpy((void *)(base_from + from->symbols[i].offset), &jmp, sizeof(jmp)); base_from + from->symbols[i].offset);
} }
return 0; return 0;
...@@ -109,10 +97,10 @@ int vdso_fill_symtable(char *mem, size_t size, struct vdso_symtable *t) ...@@ -109,10 +97,10 @@ int vdso_fill_symtable(char *mem, size_t size, struct vdso_symtable *t)
}; };
const char *vdso_symbols[VDSO_SYMBOL_MAX] = { 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_CLOCK_GETTIME] = VDSO_SYMBOL_CLOCK_GETTIME_NAME,
[VDSO_SYMBOL_GETCPU] = VDSO_SYMBOL_GETCPU_NAME,
[VDSO_SYMBOL_GETTIMEOFDAY] = VDSO_SYMBOL_GETTIMEOFDAY_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; char *dynsymbol_names;
......
...@@ -81,6 +81,12 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid, ...@@ -81,6 +81,12 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
if ((vma->e->prot & VDSO_PROT) != VDSO_PROT) if ((vma->e->prot & VDSO_PROT) != VDSO_PROT)
continue; 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) if (vma->e->start > TASK_SIZE)
continue; continue;
......
...@@ -7,6 +7,9 @@ obj-y += util-fd.o ...@@ -7,6 +7,9 @@ obj-y += util-fd.o
ifeq ($(VDSO),y) ifeq ($(VDSO),y)
obj-e += $(ARCH_DIR)/vdso-pie.o obj-e += $(ARCH_DIR)/vdso-pie.o
ifeq ($(SRCARCH),aarch64)
asm-e += $(ARCH_DIR)/intraprocedure.o
endif
endif endif
parasite-obj-y += parasite.o 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