Commit 6446fd2c authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

vdso: Move parking into a separate routine

Since we might have a several vDSO zones lets hide
handling in arch-specific routines.
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 6906e1a8
......@@ -146,7 +146,7 @@ extern struct vdso_symtable vdso_sym_rt;
extern u64 vdso_pfn;
extern int vdso_init(void);
extern int vdso_remap(char *who, unsigned long from, unsigned long to, size_t size);
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,
VmaEntry *vdso_vma, VmaEntry *vvar_vma,
......
......@@ -19,6 +19,7 @@
#include "vdso.h"
#include "vma.h"
#include "log.h"
#include "bug.h"
#ifdef LOG_PREFIX
# undef LOG_PREFIX
......@@ -246,7 +247,7 @@ err_oob:
return -EFAULT;
}
int vdso_remap(char *who, unsigned long from, unsigned long to, size_t size)
static int vdso_remap(char *who, unsigned long from, unsigned long to, size_t size)
{
unsigned long addr;
......@@ -262,6 +263,33 @@ int vdso_remap(char *who, unsigned long from, unsigned long to, size_t size)
return 0;
}
/* Park runtime vDSO in some safe place where it can be accessible from restorer */
int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, unsigned long park_size)
{
int ret;
BUG_ON((vdso_vma_size(sym_rt) + vvar_vma_size(sym_rt)) < park_size);
if (sym_rt->vvar_start != VDSO_BAD_ADDR) {
if (sym_rt->vma_start < sym_rt->vvar_start) {
ret = vdso_remap("rt-vdso", sym_rt->vma_start,
park_at, vdso_vma_size(sym_rt));
park_at += vdso_vma_size(sym_rt);
ret |= vdso_remap("rt-vvar", sym_rt->vvar_start,
park_at, vvar_vma_size(sym_rt));
} else {
ret = vdso_remap("rt-vvar", sym_rt->vvar_start,
park_at, vvar_vma_size(sym_rt));
park_at += vvar_vma_size(sym_rt);
ret |= vdso_remap("rt-vdso", sym_rt->vma_start,
park_at, vdso_vma_size(sym_rt));
}
} else
ret = vdso_remap("rt-vdso", sym_rt->vma_start,
park_at, vdso_vma_size(sym_rt));
return ret;
}
int vdso_proxify(char *who, struct vdso_symtable *sym_rt,
VmaEntry *vdso_vma, VmaEntry *vvar_vma,
unsigned long vdso_rt_parked_at)
......
......@@ -15,6 +15,7 @@
#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_vma, \
vvar_vma, vdso_rt_parked_at) (0)
......
......@@ -701,16 +701,8 @@ long __export_restore_task(struct task_restore_args *args)
pr_info("Switched to the restorer %d\n", my_pid);
#ifdef CONFIG_VDSO
if (vdso_remap("rt-vdso", args->vdso_sym_rt.vma_start,
args->vdso_rt_parked_at,
vdso_vma_size(&args->vdso_sym_rt)))
if (vdso_do_park(&args->vdso_sym_rt, args->vdso_rt_parked_at, vdso_rt_size))
goto core_restore_end;
if (args->vdso_sym_rt.vvar_start != VVAR_BAD_ADDR) {
if (vdso_remap("rt-vvar", args->vdso_sym_rt.vvar_start,
args->vdso_rt_parked_at + vdso_vma_size(&args->vdso_sym_rt),
vvar_vma_size(&args->vdso_sym_rt)))
goto core_restore_end;
}
#endif
if (unmap_old_vmas((void *)args->premmapped_addr, args->premmapped_len,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment