[CRIU] [PATCH 4/5] vdso: parasite -- Prepare new vdso mark structure.

Cyrill Gorcunov gorcunov at openvz.org
Fri Jun 6 07:07:19 PDT 2014


Because of new vvar area we need to carry the
address of vvar proxy inside the mark. Thus
add members needed and update routines.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 arch/x86/include/asm/vdso.h | 32 +++++++++++++++++++++++++-------
 arch/x86/vdso-pie.c         |  2 +-
 arch/x86/vdso.c             |  4 ++--
 include/parasite.h          |  3 ++-
 pie/parasite.c              |  6 ++++--
 5 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/arch/x86/include/asm/vdso.h b/arch/x86/include/asm/vdso.h
index d341ef40aee1..bab8456531b4 100644
--- a/arch/x86/include/asm/vdso.h
+++ b/arch/x86/include/asm/vdso.h
@@ -12,7 +12,9 @@ struct vm_area_list;
 #define VDSO_PROT		(PROT_READ | PROT_EXEC)
 
 #define VDSO_BAD_ADDR		(-1ul)
+#define VVAR_BAD_ADDR		VDSO_BAD_ADDR
 #define VDSO_BAD_PFN		(-1ull)
+#define VVAR_BAD_PFN		VDSO_BAD_PFN
 
 struct vdso_symbol {
 	char			name[32];
@@ -43,6 +45,8 @@ enum {
 struct vdso_symtable {
 	unsigned long		vma_start;
 	unsigned long		vma_end;
+	unsigned long		vvar_start;
+	unsigned long		vvar_end;
 	struct vdso_symbol	symbols[VDSO_SYMBOL_MAX];
 };
 
@@ -50,6 +54,8 @@ struct vdso_symtable {
 	{								\
 		.vma_start	= VDSO_BAD_ADDR,			\
 		.vma_end	= VDSO_BAD_ADDR,			\
+		.vvar_start	= VVAR_BAD_ADDR,			\
+		.vvar_end	= VVAR_BAD_ADDR,			\
 		.symbols		= {				\
 			[0 ... VDSO_SYMBOL_MAX - 1] =			\
 				(struct vdso_symbol)VDSO_SYMBOL_INIT,	\
@@ -78,26 +84,38 @@ static inline unsigned long vdso_vma_size(struct vdso_symtable *t)
  */
 struct vdso_mark {
 	u64			signature;
-	unsigned long		proxy_addr;
-};
+	unsigned long		proxy_vdso_addr;
+
+	unsigned long		version;
 
+	/*
+	 * In case of new vDSO format the VVAR area address
+	 * neeed for easier discovering where it lives without
+	 * relying on procfs output.
+	 */
+	unsigned long		proxy_vvar_addr;
+};
 /* Magic number (criuvdso) */
 #define VDSO_MARK_SIGNATURE	(0x6f73647675697263ULL)
+#define VDSO_MARK_SIGNATURE_V2	(0x4f53447675697263ULL)	/* Magic number (criuvDSO) */
 
 static inline bool is_vdso_mark(void *addr)
 {
 	struct vdso_mark *m = addr;
 
-	return m->signature == VDSO_MARK_SIGNATURE &&
-		m->proxy_addr != VDSO_BAD_ADDR;
+	return (m->signature == VDSO_MARK_SIGNATURE_V2 ||
+		m->signature == VDSO_MARK_SIGNATURE) &&
+		m->proxy_vdso_addr != VDSO_BAD_ADDR;
 }
 
-static inline void vdso_put_mark(void *where, unsigned long proxy_addr)
+static inline void vdso_put_mark(void *where, unsigned long proxy_vdso_addr, unsigned long proxy_vvar_addr)
 {
 	struct vdso_mark *m = where;
 
-	m->signature = VDSO_MARK_SIGNATURE;
-	m->proxy_addr = proxy_addr;
+	m->signature		= VDSO_MARK_SIGNATURE_V2;
+	m->proxy_vdso_addr	= proxy_vdso_addr;
+	m->version		= 2;
+	m->proxy_vvar_addr	= proxy_vvar_addr;
 }
 
 #define VDSO_SYMBOL_CLOCK_GETTIME_NAME	"__vdso_clock_gettime"
diff --git a/arch/x86/vdso-pie.c b/arch/x86/vdso-pie.c
index ec8f6aa581f1..967108d8fea1 100644
--- a/arch/x86/vdso-pie.c
+++ b/arch/x86/vdso-pie.c
@@ -321,7 +321,7 @@ int vdso_proxify(char *who, struct vdso_symtable *sym_rt, VmaEntry *vma, unsigne
 	 * it's auto-generated every new session if proxy required.
 	 */
 	sys_mprotect((void *)vdso_rt_parked_at,  vdso_vma_size(sym_rt), PROT_WRITE);
-	vdso_put_mark((void *)vdso_rt_parked_at, vma->start);
+	vdso_put_mark((void *)vdso_rt_parked_at, vma->start, VVAR_BAD_ADDR);
 	sys_mprotect((void *)vdso_rt_parked_at,  vdso_vma_size(sym_rt), VDSO_PROT);
 	return 0;
 }
diff --git a/arch/x86/vdso.c b/arch/x86/vdso.c
index 6e24d38118c3..674afbed7bb6 100644
--- a/arch/x86/vdso.c
+++ b/arch/x86/vdso.c
@@ -84,10 +84,10 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
 		 * Defer handling marked vdso.
 		 */
 		if (unlikely(args->is_marked)) {
-			BUG_ON(args->proxy_addr == VDSO_BAD_ADDR);
+			BUG_ON(args->proxy_vdso_addr == VDSO_BAD_ADDR);
 			BUG_ON(marked);
 			marked = vma;
-			proxy_addr = args->proxy_addr;
+			proxy_addr = args->proxy_vdso_addr;
 			continue;
 		}
 
diff --git a/include/parasite.h b/include/parasite.h
index 544a5a8ed932..ddfe97538eb6 100644
--- a/include/parasite.h
+++ b/include/parasite.h
@@ -87,7 +87,8 @@ struct parasite_vma_entry
 struct parasite_vdso_vma_entry {
 	unsigned long	start;
 	unsigned long	len;
-	unsigned long	proxy_addr;
+	unsigned long	proxy_vdso_addr;
+	unsigned long	proxy_vvar_addr;
 	int		is_marked;
 };
 
diff --git a/pie/parasite.c b/pie/parasite.c
index 40974911e7fb..972229b9b6b9 100644
--- a/pie/parasite.c
+++ b/pie/parasite.c
@@ -332,10 +332,12 @@ static int parasite_check_vdso_mark(struct parasite_vdso_vma_entry *args)
 
 	if (is_vdso_mark(m)) {
 		args->is_marked = 1;
-		args->proxy_addr = m->proxy_addr;
+		args->proxy_vdso_addr = m->proxy_vdso_addr;
+		args->proxy_vvar_addr = m->proxy_vvar_addr;
 	} else {
 		args->is_marked = 0;
-		args->proxy_addr = VDSO_BAD_ADDR;
+		args->proxy_vdso_addr = VDSO_BAD_ADDR;
+		args->proxy_vvar_addr = VVAR_BAD_ADDR;
 	}
 
 	return 0;
-- 
1.9.3



More information about the CRIU mailing list