Introduce s390 arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT. This is a preparatory patch, no functional change is introduced. Signed-off-by: Kalesh Singh <kaleshsingh@xxxxxxxxxx> --- Changes in v2: - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a special case of the hint addr being "enforced", per Yang Shi. - Consolidate error handling in arch_mmap_hint(). arch/s390/include/asm/pgtable.h | 1 + arch/s390/mm/mmap.c | 51 +++++++++++++++------------------ 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 48268095b0a3..eaecb558ab9b 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -1997,6 +1997,7 @@ extern void s390_reset_cmma(struct mm_struct *mm); /* s390 has a private copy of get unmapped area to deal with cache synonyms */ #define HAVE_ARCH_UNMAPPED_AREA #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN +#define HAVE_ARCH_MMAP_HINT #define pmd_pgtable(pmd) \ ((pgtable_t)__va(pmd_val(pmd) & -sizeof(pte_t)*PTRS_PER_PTE)) diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 33f3504be90b..8afb046605c9 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c @@ -83,28 +83,33 @@ static int get_align_mask(struct file *filp, unsigned long flags) return 0; } +unsigned long arch_mmap_hint(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, + unsigned long flags) +{ + /* requested length too big for entire address space */ + if (len > TASK_SIZE - mmap_min_addr) + return -ENOMEM; + + if (flags & MAP_FIXED) + return addr; + + return generic_mmap_hint(filp, addr, len, pgoff, flags); +} + unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags) { struct mm_struct *mm = current->mm; - struct vm_area_struct *vma; struct vm_unmapped_area_info info = {}; - if (len > TASK_SIZE - mmap_min_addr) - return -ENOMEM; - - if (flags & MAP_FIXED) + addr = arch_mmap_hint(filp, addr, len, pgoff, flags); + if (IS_ERR_VALUE(addr)) + return addr; + if (addr) goto check_asce_limit; - if (addr) { - addr = PAGE_ALIGN(addr); - vma = find_vma(mm, addr); - if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && - (!vma || addr + len <= vm_start_gap(vma))) - goto check_asce_limit; - } - info.length = len; info.low_limit = mm->mmap_base; info.high_limit = TASK_SIZE; @@ -123,25 +128,15 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long ad unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags) { - struct vm_area_struct *vma; struct mm_struct *mm = current->mm; struct vm_unmapped_area_info info = {}; - /* requested length too big for entire address space */ - if (len > TASK_SIZE - mmap_min_addr) - return -ENOMEM; - - if (flags & MAP_FIXED) - goto check_asce_limit; - /* requesting a specific address */ - if (addr) { - addr = PAGE_ALIGN(addr); - vma = find_vma(mm, addr); - if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && - (!vma || addr + len <= vm_start_gap(vma))) - goto check_asce_limit; - } + addr = arch_mmap_hint(filp, addr, len, pgoff, flags); + if (IS_ERR_VALUE(addr)) + return addr; + if (addr) + goto check_asce_limit; info.flags = VM_UNMAPPED_AREA_TOPDOWN; info.length = len; -- 2.47.0.338.g60cca15819-goog