mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-01-23 02:14:37 +00:00
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:
parent
6eaa4e92bf
commit
7f01d691c7
18 changed files with 684 additions and 1688 deletions
12
include/asm-generic/vdso.h
Normal file
12
include/asm-generic/vdso.h
Normal 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__ */
|
||||
|
|
@ -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
96
include/parasite-vdso.h
Normal 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__ */
|
||||
|
|
@ -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
69
include/util-vdso.h
Normal 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__ */
|
||||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue