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 { ...@@ -33,6 +33,7 @@ struct vdso_symtable {
unsigned long vvar_start; unsigned long vvar_start;
unsigned long vvar_size; unsigned long vvar_size;
struct vdso_symbol symbols[VDSO_SYMBOL_MAX]; struct vdso_symbol symbols[VDSO_SYMBOL_MAX];
bool vdso_before_vvar; /* order of vdso/vvar pair */
}; };
#define VDSO_SYMBOL_INIT { .offset = VDSO_BAD_ADDR, } #define VDSO_SYMBOL_INIT { .offset = VDSO_BAD_ADDR, }
...@@ -47,6 +48,7 @@ struct vdso_symtable { ...@@ -47,6 +48,7 @@ struct vdso_symtable {
[0 ... VDSO_SYMBOL_MAX - 1] = \ [0 ... VDSO_SYMBOL_MAX - 1] = \
(struct vdso_symbol)VDSO_SYMBOL_INIT, \ (struct vdso_symbol)VDSO_SYMBOL_INIT, \
}, \ }, \
.vdso_before_vvar = false, \
} }
#ifdef CONFIG_VDSO_32 #ifdef CONFIG_VDSO_32
......
...@@ -48,8 +48,8 @@ int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, unsigned l ...@@ -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); BUG_ON((sym_rt->vdso_size + sym_rt->vvar_size) < park_size);
if (sym_rt->vvar_start != VDSO_BAD_ADDR) { if (sym_rt->vvar_start != VVAR_BAD_ADDR) {
if (sym_rt->vdso_start < sym_rt->vvar_start) { if (sym_rt->vdso_before_vvar) {
ret = vdso_remap("rt-vdso", sym_rt->vdso_start, ret = vdso_remap("rt-vdso", sym_rt->vdso_start,
park_at, sym_rt->vdso_size); park_at, sym_rt->vdso_size);
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, ...@@ -127,13 +127,12 @@ static bool blobs_matches(VmaEntry *vdso_img, VmaEntry *vvar_img,
} }
if (vvar_img && sym_rt->vvar_start != VVAR_BAD_ADDR) { if (vvar_img && sym_rt->vvar_start != VVAR_BAD_ADDR) {
long delta_rt = sym_rt->vvar_start - sym_rt->vdso_start; bool vdso_firstly = (vvar_img->start > vdso_img->start);
long delta_img = vvar_img->start - vdso_img->start;
if (sym_rt->vvar_size != vma_entry_len(vvar_img)) if (sym_rt->vvar_size != vma_entry_len(vvar_img))
return false; return false;
return delta_rt == delta_img; return (vdso_firstly == sym_rt->vdso_before_vvar);
} }
return true; return true;
...@@ -238,8 +237,7 @@ int vdso_proxify(struct vdso_symtable *sym_rt, unsigned long vdso_rt_parked_at, ...@@ -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. * Don't forget to shift if vvar is before vdso.
*/ */
if (sym_rt->vvar_start != VDSO_BAD_ADDR && if (sym_rt->vvar_start != VDSO_BAD_ADDR && !sym_rt->vdso_before_vvar)
sym_rt->vvar_start < sym_rt->vdso_start)
vdso_rt_parked_at += sym_rt->vvar_size; vdso_rt_parked_at += sym_rt->vvar_size;
if (vdso_redirect_calls(vdso_rt_parked_at, if (vdso_redirect_calls(vdso_rt_parked_at,
......
...@@ -283,6 +283,9 @@ static int vdso_parse_maps(pid_t pid, struct vdso_symtable *s) ...@@ -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; exit_code = 0;
err: err:
bclose(&f); 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