[CRIU] [PATCH 2/2] Customize AArch64 VDSO code

Christopher Covington cov at codeaurora.org
Tue Aug 5 13:20:24 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               | 22 ++++++++++++++++++++++
 arch/aarch64/vdso-pie.c                     | 22 +++++-----------------
 arch/aarch64/vdso.c                         |  6 ++++++
 pie/Makefile                                |  3 +++
 7 files changed, 50 insertions(+), 26 deletions(-)
 create mode 100644 arch/aarch64/intraprocedure.S

diff --git a/Makefile b/Makefile
index 2cdf14b..fc83e8d 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..e139dc8
--- /dev/null
+++ b/arch/aarch64/intraprocedure.S
@@ -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:
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