The patch titled Subject: mm/hmm: unregister mmu_notifier when last HMM client quit v2 has been added to the -mm tree. Its filename is mm-hmm-unregister-mmu_notifier-when-last-hmm-client-quit-v2.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/mm-hmm-unregister-mmu_notifier-when-last-hmm-client-quit-v2.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/mm-hmm-unregister-mmu_notifier-when-last-hmm-client-quit-v2.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Jérôme Glisse <jglisse@xxxxxxxxxx> Subject: mm/hmm: unregister mmu_notifier when last HMM client quit v2 - close race window between a last mirror unregistering and a new mirror registering, which could have lead to use after free() kind of bug Link: http://lkml.kernel.org/r/20180321181614.9968-1-jglisse@xxxxxxxxxx Signed-off-by: Jérôme Glisse <jglisse@xxxxxxxxxx> Cc: Evgeny Baskakov <ebaskakov@xxxxxxxxxx> Cc: Ralph Campbell <rcampbell@xxxxxxxxxx> Cc: Mark Hairgrove <mhairgrove@xxxxxxxxxx> Cc: John Hubbard <jhubbard@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- mm/hmm.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff -puN mm/hmm.c~mm-hmm-unregister-mmu_notifier-when-last-hmm-client-quit-v2 mm/hmm.c --- a/mm/hmm.c~mm-hmm-unregister-mmu_notifier-when-last-hmm-client-quit-v2 +++ a/mm/hmm.c @@ -222,13 +222,24 @@ int hmm_mirror_register(struct hmm_mirro if (!mm || !mirror || !mirror->ops) return -EINVAL; +again: mirror->hmm = hmm_register(mm); if (!mirror->hmm) return -ENOMEM; down_write(&mirror->hmm->mirrors_sem); - list_add(&mirror->list, &mirror->hmm->mirrors); - up_write(&mirror->hmm->mirrors_sem); + if (mirror->hmm->mm == NULL) { + /* + * A racing hmm_mirror_unregister() is about to destroy the hmm + * struct. Try again to allocate a new one. + */ + up_write(&mirror->hmm->mirrors_sem); + mirror->hmm = NULL; + goto again; + } else { + list_add(&mirror->list, &mirror->hmm->mirrors); + up_write(&mirror->hmm->mirrors_sem); + } return 0; } @@ -244,26 +255,27 @@ EXPORT_SYMBOL(hmm_mirror_register); void hmm_mirror_unregister(struct hmm_mirror *mirror) { struct hmm *hmm = mirror->hmm; - struct mm_struct *mm = NULL; - bool unregister = false; + bool should_unregister = false; + struct mm_struct *mm; + + if (list_empty(&mirror->list)) + return; down_write(&hmm->mirrors_sem); list_del_init(&mirror->list); - unregister = list_empty(&hmm->mirrors); + should_unregister = list_empty(&hmm->mirrors); + mm = hmm->mm; + hmm->mm = NULL; up_write(&hmm->mirrors_sem); - if (!unregister) + if (!should_unregister || mm == NULL) return; - spin_lock(&hmm->mm->page_table_lock); - if (hmm->mm->hmm == hmm) { - mm = hmm->mm; + spin_lock(&mm->page_table_lock); + if (mm->hmm == hmm) { mm->hmm = NULL; } - spin_unlock(&hmm->mm->page_table_lock); - - if (mm == NULL) - return; + spin_unlock(&mm->page_table_lock); mmu_notifier_unregister_no_release(&hmm->mmu_notifier, mm); kfree(hmm); _ Patches currently in -mm which might be from jglisse@xxxxxxxxxx are mm-hmm-fix-header-file-if-else-endif-maze-v2.patch mm-hmm-unregister-mmu_notifier-when-last-hmm-client-quit.patch mm-hmm-unregister-mmu_notifier-when-last-hmm-client-quit-v2.patch mm-hmm-hmm_pfns_bad-was-accessing-wrong-struct.patch mm-hmm-use-struct-for-hmm_vma_fault-hmm_vma_get_pfns-parameters-v2.patch mm-hmm-remove-hmm_pfn_read-flag-and-ignore-peculiar-architecture-v2.patch mm-hmm-use-uint64_t-for-hmm-pfn-instead-of-defining-hmm_pfn_t-to-ulong-v2.patch mm-hmm-cleanup-special-vma-handling-vm_special.patch mm-hmm-do-not-differentiate-between-empty-entry-or-missing-directory-v2.patch mm-hmm-rename-hmm_pfn_device_unaddressable-to-hmm_pfn_device_private.patch mm-hmm-move-hmm_pfns_clear-closer-to-where-it-is-use.patch mm-hmm-factor-out-pte-and-pmd-handling-to-simplify-hmm_vma_walk_pmd.patch mm-hmm-change-hmm_vma_fault-to-allow-write-fault-on-page-basis.patch mm-hmm-use-device-driver-encoding-for-hmm-pfn-v2.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html