mas_empty_area() maple tree interface does not work properly and returns -EBUSY if there is no gap in the range. This commit explicitly scans the VMAs for the input range and checks if they are continuous or not.
Note: reserv_vmi_range_mapped() can switch to the old method of using mas_empty_area() if this issue is resolved in core maple tree library.
Fixes: ("mm/cap_addr_mgmt: Add capability reservation interfaces in VMA") Fixes: ("mm/mmap: Add reservation constraints in mmap/munmap parameters") Signed-off-by: Amit Daniel Kachhap amitdaniel.kachhap@arm.com --- mm/cap_addr_mgmt.c | 25 ++++++++++++++++--------- mm/mmap.c | 2 +- 2 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/mm/cap_addr_mgmt.c b/mm/cap_addr_mgmt.c index 845e4a99556e..d58caed45edd 100644 --- a/mm/cap_addr_mgmt.c +++ b/mm/cap_addr_mgmt.c @@ -64,9 +64,10 @@ user_uintptr_t reserv_range_set_reserv(ptraddr_t start, size_t len, user_ptr_per int reserv_vmi_range_mapped(struct vma_iterator *vmi, ptraddr_t start, size_t len, bool locked) { - struct vm_area_struct *vma; + struct vm_area_struct *vma, *last_vma = NULL; struct mm_struct *mm = current->mm; int ret = -ENOMEM; + ptraddr_t end = start + len - 1;
if (!reserv_is_supported(mm)) return 0; @@ -78,14 +79,20 @@ int reserv_vmi_range_mapped(struct vma_iterator *vmi, ptraddr_t start, len = round_up(len, PAGE_SIZE); vma_iter_set(vmi, start); /* Try walking the given range */ - vma = mas_find(&vmi->mas, start + len - 1); - if (!vma) - goto out; - - /* If the range is fully mapped then no gap exists */ - if (mas_empty_area(&vmi->mas, start, start + len - 1, 1)) - goto out; - ret = 0; + do { + vma = mas_find(&vmi->mas, end); + if (vma) { + /* The new and old vma should be continuous */ + if (last_vma && last_vma->vm_end != vma->vm_start) + goto out; + /* End range is within the vma so return success */ + if (end < vma->vm_end) { + ret = 0; + goto out; + } + last_vma = vma; + } + } while (vma); out: if (!locked) mmap_read_unlock(mm); diff --git a/mm/mmap.c b/mm/mmap.c index aef8a08d9a0d..776fc37e07ed 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1411,7 +1411,7 @@ int check_pcuabi_params(user_uintptr_t user_ptr, unsigned long len, return -ERESERVATION; if (!map_fixed) return ret; - if (!reserv_vmi_range_mapped(&vmi, addr, len, reserv_lock)) + if (reserv_vmi_range_mapped(&vmi, addr, len, reserv_lock)) return -ENOMEM;
return 0;
linux-morello@op-lists.linaro.org