[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