On Fri, Aug 26, 2016 at 10:13 AM, Dmitry Safonov <dsafo...@virtuozzo.com> wrote: > Add API to change vdso blob type with arch_prctl. > As this is usefull only by needs of CRIU, expose > this interface under CONFIG_CHECKPOINT_RESTORE. > > Cc: Andy Lutomirski <l...@kernel.org> > Cc: Oleg Nesterov <o...@redhat.com> > Cc: Thomas Gleixner <t...@linutronix.de> > Cc: "H. Peter Anvin" <h...@zytor.com> > Cc: Ingo Molnar <mi...@redhat.com> > Cc: linux...@kvack.org > Cc: x...@kernel.org > Cc: Cyrill Gorcunov <gorcu...@openvz.org> > Cc: Pavel Emelyanov <xe...@virtuozzo.com> > Signed-off-by: Dmitry Safonov <dsafo...@virtuozzo.com> > --- > arch/x86/entry/vdso/vma.c | 45 > ++++++++++++++++++++++++++++++--------- > arch/x86/include/asm/vdso.h | 2 ++ > arch/x86/include/uapi/asm/prctl.h | 6 ++++++ > arch/x86/kernel/process_64.c | 25 ++++++++++++++++++++++ > 4 files changed, 68 insertions(+), 10 deletions(-) > > diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c > index 5bcb25a9e573..dad2b2d8ff03 100644 > --- a/arch/x86/entry/vdso/vma.c > +++ b/arch/x86/entry/vdso/vma.c > @@ -176,6 +176,16 @@ static int vvar_fault(const struct vm_special_mapping > *sm, > return VM_FAULT_SIGBUS; > } > > +static const struct vm_special_mapping vdso_mapping = { > + .name = "[vdso]", > + .fault = vdso_fault, > + .mremap = vdso_mremap, > +}; > +static const struct vm_special_mapping vvar_mapping = { > + .name = "[vvar]", > + .fault = vvar_fault, > +}; > + > /* > * Add vdso and vvar mappings to current process. > * @image - blob to map > @@ -188,16 +198,6 @@ static int map_vdso(const struct vdso_image *image, > unsigned long addr) > unsigned long text_start; > int ret = 0; > > - static const struct vm_special_mapping vdso_mapping = { > - .name = "[vdso]", > - .fault = vdso_fault, > - .mremap = vdso_mremap, > - }; > - static const struct vm_special_mapping vvar_mapping = { > - .name = "[vvar]", > - .fault = vvar_fault, > - }; > - > if (down_write_killable(&mm->mmap_sem)) > return -EINTR; > > @@ -256,6 +256,31 @@ static int map_vdso_randomized(const struct vdso_image > *image) > return map_vdso(image, addr); > } > > +int map_vdso_once(const struct vdso_image *image, unsigned long addr) > +{ > + struct mm_struct *mm = current->mm; > + struct vm_area_struct *vma; > + > + down_write(&mm->mmap_sem); > + /* > + * Check if we have already mapped vdso blob - fail to prevent > + * abusing from userspace install_speciall_mapping, which may > + * not do accounting and rlimit right. > + * We could search vma near context.vdso, but it's a slowpath, > + * so let's explicitely check all VMAs to be completely sure. > + */ > + for (vma = mm->mmap; vma; vma = vma->vm_next) { > + if (vma->vm_private_data == &vdso_mapping || > + vma->vm_private_data == &vvar_mapping) {
Should probably also check that vm_ops == &special_mapping_vmops, which means that maybe there should be a: static inline bool vma_is_special_mapping(const struct vm_area_struct *vma, const struct vm_special_mapping &sm); --Andy