Re: [PATCH 2/4] powerpc/mm: Handle VDSO unmapping via close() rather than arch_unmap()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Aug 7, 2024 at 8:56 AM Liam R. Howlett <Liam.Howlett@xxxxxxxxxx> wrote:
>
> * Jeff Xu <jeffxu@xxxxxxxxxx> [240807 11:44]:
> > On Wed, Aug 7, 2024 at 5:41 AM Michael Ellerman <mpe@xxxxxxxxxxxxxx> wrote:
> > >
> > > Add a close() callback to the VDSO special mapping to handle unmapping
> > > of the VDSO. That will make it possible to remove the arch_unmap() hook
> > > entirely in a subsequent patch.
> > >
> > > Suggested-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
> > > Signed-off-by: Michael Ellerman <mpe@xxxxxxxxxxxxxx>
> > > ---
> > >  arch/powerpc/include/asm/mmu_context.h |  4 ----
> > >  arch/powerpc/kernel/vdso.c             | 17 +++++++++++++++++
> > >  2 files changed, 17 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
> > > index 37bffa0f7918..9b8c1555744e 100644
> > > --- a/arch/powerpc/include/asm/mmu_context.h
> > > +++ b/arch/powerpc/include/asm/mmu_context.h
> > > @@ -263,10 +263,6 @@ extern void arch_exit_mmap(struct mm_struct *mm);
> > >  static inline void arch_unmap(struct mm_struct *mm,
> > >                               unsigned long start, unsigned long end)
> > >  {
> > > -       unsigned long vdso_base = (unsigned long)mm->context.vdso;
> > > -
> > > -       if (start <= vdso_base && vdso_base < end)
> > > -               mm->context.vdso = NULL;
> > >  }
> > >
> > >  #ifdef CONFIG_PPC_MEM_KEYS
> > > diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
> > > index 7a2ff9010f17..220a76cae7c1 100644
> > > --- a/arch/powerpc/kernel/vdso.c
> > > +++ b/arch/powerpc/kernel/vdso.c
> > > @@ -81,6 +81,21 @@ static int vdso64_mremap(const struct vm_special_mapping *sm, struct vm_area_str
> > >         return vdso_mremap(sm, new_vma, &vdso64_end - &vdso64_start);
> > >  }
> > >
> > > +static void vdso_close(const struct vm_special_mapping *sm, struct vm_area_struct *vma)
> > > +{
> > > +       struct mm_struct *mm = vma->vm_mm;
> > > +
> > > +       /*
> > > +        * close() is called for munmap() but also for mremap(). In the mremap()
> > > +        * case the vdso pointer has already been updated by the mremap() hook
> > > +        * above, so it must not be set to NULL here.
> > > +        */
> > > +       if (vma->vm_start != (unsigned long)mm->context.vdso)
> > > +               return;
> > > +
> > > +       mm->context.vdso = NULL;
> > > +}
> > > +
> > >  static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
> > >                              struct vm_area_struct *vma, struct vm_fault *vmf);
> > >
> > > @@ -92,11 +107,13 @@ static struct vm_special_mapping vvar_spec __ro_after_init = {
> > >  static struct vm_special_mapping vdso32_spec __ro_after_init = {
> > >         .name = "[vdso]",
> > >         .mremap = vdso32_mremap,
> > > +       .close = vdso_close,
> > IIUC, only CHECKPOINT_RESTORE requires this, and
> > CHECKPOINT_RESTORE is in init/Kconfig, with default N
> >
> > Can we add #ifdef CONFIG_CHECKPOINT_RESTORE here ?
> >
>
> No, these can be unmapped and it needs to be cleaned up.  Valgrind is
> one application that is known to unmap the vdso and runs into issues on
> platforms that do not handle the removal correctly.
>
Maybe Valgrind needs that exactly for checkpoint restore ? [1]

"CRIU fails to restore applications that have unmapped the vDSO
segment. One such
application is Valgrind."

Usually when the kernel accepts new functionality, the patch needs to
state the user case.
The only user case I found for .mremap and .close so far is the CRIU case.

[1] https://github.com/checkpoint-restore/criu/issues/488

Thanks
-Jeff

> Thanks,
> Liam





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux