vdso: Rework vdso processing files

There were multiple copy of the same code spread over the different
architectures handling the vDSO.

This patch is merging the duplicated code in arch/*/vdso-pie.c and
arch/*/include/asm/vdso.h in the common files and let only the architecture
specific part in the arch/*/* files.

The file are now organized this way:

include/asm-generic/vdso.h
	contains basic definition which could be overwritten by
	architectures.

arch/*/include/asm/vdso.h
	contains per architecture definitions.
	It may includes include/asm-generic/vdso.h

pie/util-vdso.c
include/util-vdso.h
	These files contains code and definitions common to both criu and
	the parasite code.
	The file include/util-vdso.h includes arch/*/include/asm/vdso.h.

pie/parsite-vdso.c
include/parasite-vdso.h
	contains code and definition specific to the parasite code handling
	the vDSO.
	The file include/parasite-vdso.h includes include/util-vdso.h.

arch/*/vdso-pie.c
	contains the architecture specific code installing the vDSO
	trampoline.

vdso.c
include/vdso.h
	contains code and definition specific to the criu code handling the
	vDSO.
	The file include/vdso.h includes include/util-vdso.h.

CC: Christopher Covington <cov@codeaurora.org>
CC: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
Acked-by: Cyrill Gorcunov <gorcunov@gmail.com>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
Laurent Dufour 2015-09-03 16:26:30 +02:00 committed by Pavel Emelyanov
parent 6eaa4e92bf
commit 7f01d691c7
18 changed files with 684 additions and 1688 deletions

View file

@ -0,0 +1,12 @@
#ifndef __CR_ASM_GENERIC_VDSO_H__
#define __CR_ASM_GENERIC_VDSO_H__
#define VDSO_PROT (PROT_READ | PROT_EXEC)
#define VVAR_PROT (PROT_READ)
#define VDSO_BAD_ADDR (-1ul)
#define VVAR_BAD_ADDR VDSO_BAD_ADDR
#define VDSO_BAD_PFN (-1ull)
#define VVAR_BAD_PFN VDSO_BAD_PFN
#endif /* __CR_ASM_GENERIC_VDSO_H__ */

View file

@ -118,11 +118,6 @@ extern int __parasite_execute_syscall(struct parasite_ctl *ctl,
user_regs_struct_t *regs);
extern bool arch_can_dump_task(pid_t pid);
#ifdef CONFIG_VDSO
extern int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
struct vm_area_list *vma_area_list);
#endif
/*
* The PTRACE_SYSCALL will trap task twice -- on
* enter into and on exit from syscall. If we trace

96
include/parasite-vdso.h Normal file
View file

@ -0,0 +1,96 @@
#ifndef __CR_PARASITE_VDSO_H__
#define __CR_PARASITE_VDSO_H__
#include "config.h"
#ifdef CONFIG_VDSO
#include "util-vdso.h"
#include "protobuf/vma.pb-c.h"
struct parasite_ctl;
struct vm_area_list;
/* Check if symbol present in symtable */
static inline bool vdso_symbol_empty(struct vdso_symbol *s)
{
return s->offset == VDSO_BAD_ADDR && s->name[0] == '\0';
}
/*
* Special mark which allows to identify runtime vdso where
* calls from proxy vdso are redirected. This mark usually
* placed at the start of vdso area where Elf header lives.
* Since such runtime vdso is solevey used by proxy and
* nobody else is supposed to access it, it's more-less
* safe to screw the Elf header with @signature and
* @proxy_addr.
*
* The @proxy_addr deserves a few comments. When we redirect
* the calls from proxy to runtime vdso, on next checkpoint
* it won't be possible to find which VMA is proxy, thus
* we save its address in the member.
*/
struct vdso_mark {
u64 signature;
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;
};
#define VDSO_MARK_SIGNATURE (0x6f73647675697263ULL) /* Magic number (criuvdso) */
#define VDSO_MARK_SIGNATURE_V2 (0x4f53447675697263ULL) /* Magic number (criuvDSO) */
#define VDSO_MARK_CUR_VERSION (2)
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_V2;
m->proxy_vdso_addr = proxy_vdso_addr;
m->version = VDSO_MARK_CUR_VERSION;
m->proxy_vvar_addr = proxy_vvar_addr;
}
static inline bool is_vdso_mark(void *addr)
{
struct vdso_mark *m = addr;
if (m->signature == VDSO_MARK_SIGNATURE_V2) {
/*
* New format
*/
return true;
} else if (m->signature == VDSO_MARK_SIGNATURE) {
/*
* Old format -- simply extend the mark up
* to the version we support.
*/
vdso_put_mark(m, m->proxy_vdso_addr, VVAR_BAD_ADDR);
return true;
}
return false;
}
extern int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, unsigned long park_size);
extern int vdso_fill_symtable(char *mem, size_t size, struct vdso_symtable *t);
extern int vdso_proxify(char *who, struct vdso_symtable *sym_rt,
unsigned long vdso_rt_parked_at, size_t index,
VmaEntry *vmas, size_t nr_vmas);
/* only used by aarch64 => to be moved to aarch64/include/asm/vdso.h */
extern void write_intraprocedure_branch(void *to, void *from);
#else /* CONFIG_VDSO */
#define vdso_do_park(sym_rt, park_at, park_size) (0)
#endif /* CONFIG_VDSO */
#endif /* __CR_PARASITE_VDSO_H__ */

View file

@ -19,7 +19,7 @@
#include "timerfd.h"
#include "shmem.h"
#include "sigframe.h"
#include "vdso.h"
#include "parasite-vdso.h"
#include <time.h>

69
include/util-vdso.h Normal file
View file

@ -0,0 +1,69 @@
#ifndef __CR_UTIL_VDSO_H__
#define __CR_UTIL_VDSO_H__
/*
* VDSO management common definitions.
*
* This header file is included by the criu main code and the parasite code.
* It contains definitions shared by these 2 parts.
*
* This file should not be included except in pie/util-vdso.c, include/vdso.h
* and include/parasite-vdso.h
*/
#include <sys/types.h>
/*
* Each architecture must export:
* VDSO_SYMBOL_MAX, the number of vDSO symbols to manage
* ARCH_VDSO_SYMBOLS, a table of string containing the vDSO symbol names
* vdso_redirect_calls, a service called to redirect the vDSO symbols in
* the parasite code.
*/
#include "asm/vdso.h"
struct vdso_symbol {
char name[32];
unsigned long offset;
};
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];
};
#define VDSO_SYMBOL_INIT { .offset = VDSO_BAD_ADDR, }
#define VDSO_SYMTABLE_INIT \
{ \
.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, \
}, \
}
/* Size of VMA associated with vdso */
static inline unsigned long vdso_vma_size(struct vdso_symtable *t)
{
return t->vma_end - t->vma_start;
}
static inline unsigned long vvar_vma_size(struct vdso_symtable *t)
{
return t->vvar_end - t->vvar_start;
}
extern const char *vdso_symbols[VDSO_SYMBOL_MAX];
extern int vdso_fill_symtable(char *mem, size_t size, struct vdso_symtable *t);
#endif /* __CR_UTIL_VDSO_H__ */

View file

@ -8,17 +8,19 @@
#ifdef CONFIG_VDSO
#include "asm/vdso.h"
#include "util-vdso.h"
extern struct vdso_symtable vdso_sym_rt;
extern int vdso_init(void);
extern int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
struct vm_area_list *vma_area_list);
#else /* CONFIG_VDSO */
#define vdso_init() (0)
#define parasite_fixup_vdso(ctl, pid, vma_area_list) (0)
#define vdso_vma_size(t) (0)
#define vdso_do_park(sym_rt, park_at, park_size) (0)
#define vdso_remap(who, from, to, size) (0)
#define vdso_proxify(who, sym_rt, vdso_rt_parked_at, \
index, vmas, nr_vmas) (0)
#endif /* CONFIG_VDSO */