Commit 06f846b7 authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Andrei Vagin

vdso: Save vdso/vvar pair order inside vdso_symtable

I plan to keep boot-persistent vdso_symtable inside kdat,
moving {vvar,vdso}_start addresses out into new structure.
As order of vdso/vvar is preserved across one booting store
it inside of vdso_symtable.
Reviewed-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarDmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent ba963921
......@@ -33,6 +33,7 @@ struct vdso_symtable {
unsigned long vvar_start;
unsigned long vvar_size;
struct vdso_symbol symbols[VDSO_SYMBOL_MAX];
bool vdso_before_vvar; /* order of vdso/vvar pair */
};
#define VDSO_SYMBOL_INIT { .offset = VDSO_BAD_ADDR, }
......@@ -47,6 +48,7 @@ struct vdso_symtable {
[0 ... VDSO_SYMBOL_MAX - 1] = \
(struct vdso_symbol)VDSO_SYMBOL_INIT, \
}, \
.vdso_before_vvar = false, \
}
#ifdef CONFIG_VDSO_32
......
......@@ -48,8 +48,8 @@ int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, unsigned l
BUG_ON((sym_rt->vdso_size + sym_rt->vvar_size) < park_size);
if (sym_rt->vvar_start != VDSO_BAD_ADDR) {
if (sym_rt->vdso_start < sym_rt->vvar_start) {
if (sym_rt->vvar_start != VVAR_BAD_ADDR) {
if (sym_rt->vdso_before_vvar) {
ret = vdso_remap("rt-vdso", sym_rt->vdso_start,
park_at, sym_rt->vdso_size);
park_at += sym_rt->vdso_size;
......@@ -127,13 +127,12 @@ static bool blobs_matches(VmaEntry *vdso_img, VmaEntry *vvar_img,
}
if (vvar_img && sym_rt->vvar_start != VVAR_BAD_ADDR) {
long delta_rt = sym_rt->vvar_start - sym_rt->vdso_start;
long delta_img = vvar_img->start - vdso_img->start;
bool vdso_firstly = (vvar_img->start > vdso_img->start);
if (sym_rt->vvar_size != vma_entry_len(vvar_img))
return false;
return delta_rt == delta_img;
return (vdso_firstly == sym_rt->vdso_before_vvar);
}
return true;
......@@ -238,8 +237,7 @@ int vdso_proxify(struct vdso_symtable *sym_rt, unsigned long vdso_rt_parked_at,
/*
* Don't forget to shift if vvar is before vdso.
*/
if (sym_rt->vvar_start != VDSO_BAD_ADDR &&
sym_rt->vvar_start < sym_rt->vdso_start)
if (sym_rt->vvar_start != VDSO_BAD_ADDR && !sym_rt->vdso_before_vvar)
vdso_rt_parked_at += sym_rt->vvar_size;
if (vdso_redirect_calls(vdso_rt_parked_at,
......
......@@ -283,6 +283,9 @@ static int vdso_parse_maps(pid_t pid, struct vdso_symtable *s)
}
}
if (s->vdso_start != VDSO_BAD_ADDR && s->vvar_start != VVAR_BAD_ADDR)
s->vdso_before_vvar = (s->vdso_start < s->vvar_start);
exit_code = 0;
err:
bclose(&f);
......
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