diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 8a265cc019f1..26f50a79dc68 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2008-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2008-2020, The Linux Foundation. All rights reserved. */ #include @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -4519,10 +4520,6 @@ static unsigned long set_svm_area(struct file *file, struct kgsl_process_private *private = dev_priv->process_priv; unsigned long ret; - /* Make sure there isn't a vma conflict in the chosen range */ - if (find_vma_intersection(current->mm, addr, addr + len - 1)) - return -ENOMEM; - /* * Do additoinal constraints checking on the address. Passing MAP_FIXED * ensures that the address we want gets checked @@ -4547,6 +4544,7 @@ static unsigned long get_svm_unmapped_area(struct file *file, unsigned long align = get_align(entry); unsigned long ret, iova; u64 start = 0, end = 0; + struct vm_area_struct *vma; if (flags & MAP_FIXED) { /* Even fixed addresses need to obey alignment */ @@ -4575,9 +4573,14 @@ static unsigned long get_svm_unmapped_area(struct file *file, len, align); while (!IS_ERR_VALUE(iova)) { - ret = set_svm_area(file, entry, iova, len, flags); - if (!IS_ERR_VALUE(ret)) - return ret; + vma = find_vma_intersection(current->mm, iova, iova + len - 1); + if (vma) { + iova = vma->vm_start; + } else { + ret = set_svm_area(file, entry, iova, len, flags); + if (!IS_ERR_VALUE(ret)) + return ret; + } iova = kgsl_mmu_find_svm_region(private->pagetable, start, iova - 1, len, align);