diff options
-rw-r--r-- | mm/hmm.c | 14 |
1 files changed, 8 insertions, 6 deletions
@@ -925,19 +925,21 @@ void hmm_range_unregister(struct hmm_range *range) | |||
925 | { | 925 | { |
926 | struct hmm *hmm = range->hmm; | 926 | struct hmm *hmm = range->hmm; |
927 | 927 | ||
928 | /* Sanity check this really should not happen. */ | ||
929 | if (hmm == NULL || range->end <= range->start) | ||
930 | return; | ||
931 | |||
932 | mutex_lock(&hmm->lock); | 928 | mutex_lock(&hmm->lock); |
933 | list_del_init(&range->list); | 929 | list_del_init(&range->list); |
934 | mutex_unlock(&hmm->lock); | 930 | mutex_unlock(&hmm->lock); |
935 | 931 | ||
936 | /* Drop reference taken by hmm_range_register() */ | 932 | /* Drop reference taken by hmm_range_register() */ |
937 | range->valid = false; | ||
938 | mmput(hmm->mm); | 933 | mmput(hmm->mm); |
939 | hmm_put(hmm); | 934 | hmm_put(hmm); |
940 | range->hmm = NULL; | 935 | |
936 | /* | ||
937 | * The range is now invalid and the ref on the hmm is dropped, so | ||
938 | * poison the pointer. Leave other fields in place, for the caller's | ||
939 | * use. | ||
940 | */ | ||
941 | range->valid = false; | ||
942 | memset(&range->hmm, POISON_INUSE, sizeof(range->hmm)); | ||
941 | } | 943 | } |
942 | EXPORT_SYMBOL(hmm_range_unregister); | 944 | EXPORT_SYMBOL(hmm_range_unregister); |
943 | 945 | ||