[CRIU] [PATCH 2/2] Customize AArch64 VDSO code
Christopher Covington
cov at codeaurora.org
Fri Jul 25 12:19:59 PDT 2014
This modifies the x86 VDSO code to work on AArch64.
Signed-off-by: Christopher Covington <cov at codeaurora.org>
---
Makefile | 6 ++++++
arch/aarch64/include/asm/parasite-syscall.h | 2 +-
arch/aarch64/include/asm/vdso.h | 15 +++++++--------
arch/aarch64/intraprocedure.S | 17 +++++++++++++++++
arch/aarch64/vdso-pie.c | 22 +++++-----------------
arch/aarch64/vdso.c | 6 ++++++
pie/Makefile | 3 +++
7 files changed, 45 insertions(+), 26 deletions(-)
create mode 100644 arch/aarch64/intraprocedure.S
diff --git a/Makefile b/Makefile
index a422614..847673c 100644
--- a/Makefile
+++ b/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
diff --git a/arch/aarch64/include/asm/parasite-syscall.h b/arch/aarch64/include/asm/parasite-syscall.h
index 0c66bf9..0c07121 100644
--- a/arch/aarch64/include/asm/parasite-syscall.h
+++ b/arch/aarch64/include/asm/parasite-syscall.h
@@ -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,
diff --git a/arch/aarch64/include/asm/vdso.h b/arch/aarch64/include/asm/vdso.h
index 56761fa..f8d1556 100644
--- a/arch/aarch64/include/asm/vdso.h
+++ b/arch/aarch64/include/asm/vdso.h
@@ -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__ */
diff --git a/arch/aarch64/intraprocedure.S b/arch/aarch64/intraprocedure.S
new file mode 100644
index 0000000..d6bf92f
--- /dev/null
+++ b/arch/aarch64/intraprocedure.S
@@ -0,0 +1,17 @@
+.global write_intraprocedure_branch
+
+/* to x0, from x1 */
+write_intraprocedure_branch:
+ ldr x2, loadbranch
+ stp x2, x0, [x1]
+ dc cvau, x1
+ dsb ish
+ ic ivau, x1
+ dsb ish
+ isb
+ ret
+loadbranch:
+ ldr x16, =destination
+ br x16
+destination:
+
diff --git a/arch/aarch64/vdso-pie.c b/arch/aarch64/vdso-pie.c
index 0a55d71..c1eece3 100644
--- a/arch/aarch64/vdso-pie.c
+++ b/arch/aarch64/vdso-pie.c
@@ -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;
diff --git a/arch/aarch64/vdso.c b/arch/aarch64/vdso.c
index ac47a1e..6a9c597 100644
--- a/arch/aarch64/vdso.c
+++ b/arch/aarch64/vdso.c
@@ -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;
diff --git a/pie/Makefile b/pie/Makefile
index f2bb030..3e0b3a7 100644
--- a/pie/Makefile
+++ b/pie/Makefile
@@ -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
--
Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by the Linux Foundation.
More information about the CRIU
mailing list