[PATCH 2/4] powerpc/mm: Handle VDSO unmapping via close() rather than arch_unmap()
Liam R. Howlett
Liam.Howlett at oracle.com
Thu Aug 8 01:56:01 AEST 2024
* Jeff Xu <jeffxu at google.com> [240807 11:44]:
> On Wed, Aug 7, 2024 at 5:41 AM Michael Ellerman <mpe at ellerman.id.au> 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 at linux-foundation.org>
> > Signed-off-by: Michael Ellerman <mpe at ellerman.id.au>
> > ---
> > 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.
Thanks,
Liam
More information about the Linuxppc-dev
mailing list