This source file includes following definitions.
- arch_get_unmapped_area_common
- arch_get_unmapped_area
- arch_get_unmapped_area_topdown
- __virt_addr_valid
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 #include <linux/compiler.h>
  10 #include <linux/elf-randomize.h>
  11 #include <linux/errno.h>
  12 #include <linux/mm.h>
  13 #include <linux/mman.h>
  14 #include <linux/export.h>
  15 #include <linux/personality.h>
  16 #include <linux/random.h>
  17 #include <linux/sched/signal.h>
  18 #include <linux/sched/mm.h>
  19 
  20 unsigned long shm_align_mask = PAGE_SIZE - 1;   
  21 EXPORT_SYMBOL(shm_align_mask);
  22 
  23 #define COLOUR_ALIGN(addr, pgoff)                               \
  24         ((((addr) + shm_align_mask) & ~shm_align_mask) +        \
  25          (((pgoff) << PAGE_SHIFT) & shm_align_mask))
  26 
  27 enum mmap_allocation_direction {UP, DOWN};
  28 
  29 static unsigned long arch_get_unmapped_area_common(struct file *filp,
  30         unsigned long addr0, unsigned long len, unsigned long pgoff,
  31         unsigned long flags, enum mmap_allocation_direction dir)
  32 {
  33         struct mm_struct *mm = current->mm;
  34         struct vm_area_struct *vma;
  35         unsigned long addr = addr0;
  36         int do_color_align;
  37         struct vm_unmapped_area_info info;
  38 
  39         if (unlikely(len > TASK_SIZE))
  40                 return -ENOMEM;
  41 
  42         if (flags & MAP_FIXED) {
  43                 
  44                 if (TASK_SIZE - len < addr)
  45                         return -EINVAL;
  46 
  47                 
  48 
  49 
  50 
  51                 if ((flags & MAP_SHARED) &&
  52                     ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
  53                         return -EINVAL;
  54                 return addr;
  55         }
  56 
  57         do_color_align = 0;
  58         if (filp || (flags & MAP_SHARED))
  59                 do_color_align = 1;
  60 
  61         
  62         if (addr) {
  63                 if (do_color_align)
  64                         addr = COLOUR_ALIGN(addr, pgoff);
  65                 else
  66                         addr = PAGE_ALIGN(addr);
  67 
  68                 vma = find_vma(mm, addr);
  69                 if (TASK_SIZE - len >= addr &&
  70                     (!vma || addr + len <= vm_start_gap(vma)))
  71                         return addr;
  72         }
  73 
  74         info.length = len;
  75         info.align_mask = do_color_align ? (PAGE_MASK & shm_align_mask) : 0;
  76         info.align_offset = pgoff << PAGE_SHIFT;
  77 
  78         if (dir == DOWN) {
  79                 info.flags = VM_UNMAPPED_AREA_TOPDOWN;
  80                 info.low_limit = PAGE_SIZE;
  81                 info.high_limit = mm->mmap_base;
  82                 addr = vm_unmapped_area(&info);
  83 
  84                 if (!(addr & ~PAGE_MASK))
  85                         return addr;
  86 
  87                 
  88 
  89 
  90 
  91 
  92 
  93         }
  94 
  95         info.flags = 0;
  96         info.low_limit = mm->mmap_base;
  97         info.high_limit = TASK_SIZE;
  98         return vm_unmapped_area(&info);
  99 }
 100 
 101 unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0,
 102         unsigned long len, unsigned long pgoff, unsigned long flags)
 103 {
 104         return arch_get_unmapped_area_common(filp,
 105                         addr0, len, pgoff, flags, UP);
 106 }
 107 
 108 
 109 
 110 
 111 
 112 unsigned long arch_get_unmapped_area_topdown(struct file *filp,
 113         unsigned long addr0, unsigned long len, unsigned long pgoff,
 114         unsigned long flags)
 115 {
 116         return arch_get_unmapped_area_common(filp,
 117                         addr0, len, pgoff, flags, DOWN);
 118 }
 119 
 120 bool __virt_addr_valid(const volatile void *kaddr)
 121 {
 122         unsigned long vaddr = (unsigned long)kaddr;
 123 
 124         if ((vaddr < PAGE_OFFSET) || (vaddr >= MAP_BASE))
 125                 return false;
 126 
 127         return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
 128 }
 129 EXPORT_SYMBOL_GPL(__virt_addr_valid);