mm/hmm: Poison hmm_range during unregister
Trying to misuse a range outside its lifetime is a kernel bug. Use poison bytes to help detect this condition. Double unregister will reliably crash. Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> Reviewed-by: Jérôme Glisse <jglisse@redhat.com> Reviewed-by: John Hubbard <jhubbard@nvidia.com> Acked-by: Souptick Joarder <jrdr.linux@gmail.com> Reviewed-by: Ralph Campbell <rcampbell@nvidia.com> Reviewed-by: Ira Weiny <ira.weiny@intel.com> Tested-by: Philip Yang <Philip.Yang@amd.com>
This commit is contained in:
parent
187229c2dd
commit
2dcc3eb8ab
14
mm/hmm.c
14
mm/hmm.c
@ -925,19 +925,21 @@ void hmm_range_unregister(struct hmm_range *range)
|
|||||||
{
|
{
|
||||||
struct hmm *hmm = range->hmm;
|
struct hmm *hmm = range->hmm;
|
||||||
|
|
||||||
/* Sanity check this really should not happen. */
|
|
||||||
if (hmm == NULL || range->end <= range->start)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mutex_lock(&hmm->lock);
|
mutex_lock(&hmm->lock);
|
||||||
list_del_init(&range->list);
|
list_del_init(&range->list);
|
||||||
mutex_unlock(&hmm->lock);
|
mutex_unlock(&hmm->lock);
|
||||||
|
|
||||||
/* Drop reference taken by hmm_range_register() */
|
/* Drop reference taken by hmm_range_register() */
|
||||||
range->valid = false;
|
|
||||||
mmput(hmm->mm);
|
mmput(hmm->mm);
|
||||||
hmm_put(hmm);
|
hmm_put(hmm);
|
||||||
range->hmm = NULL;
|
|
||||||
|
/*
|
||||||
|
* The range is now invalid and the ref on the hmm is dropped, so
|
||||||
|
* poison the pointer. Leave other fields in place, for the caller's
|
||||||
|
* use.
|
||||||
|
*/
|
||||||
|
range->valid = false;
|
||||||
|
memset(&range->hmm, POISON_INUSE, sizeof(range->hmm));
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(hmm_range_unregister);
|
EXPORT_SYMBOL(hmm_range_unregister);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user