0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/fs.h>
0011 #include <linux/mm.h>
0012 #include <linux/mman.h>
0013 #include <linux/sched/mm.h>
0014
0015 #include <asm/cacheflush.h>
0016
0017 #define COLOUR_ALIGN(addr, pgoff) \
0018 ((((addr) + SHMLBA - 1) & ~(SHMLBA - 1)) + \
0019 (((pgoff) << PAGE_SHIFT) & (SHMLBA - 1)))
0020
0021
0022
0023
0024
0025
0026
0027
0028 unsigned long
0029 arch_get_unmapped_area(struct file *filp, unsigned long addr,
0030 unsigned long len, unsigned long pgoff, unsigned long flags)
0031 {
0032 struct mm_struct *mm = current->mm;
0033 struct vm_area_struct *vma;
0034 int do_align = 0;
0035 int aliasing = cache_is_vipt_aliasing();
0036 struct vm_unmapped_area_info info;
0037
0038
0039
0040
0041 if (aliasing)
0042 do_align = filp || (flags & MAP_SHARED);
0043
0044
0045
0046
0047 if (flags & MAP_FIXED) {
0048 if (aliasing && flags & MAP_SHARED &&
0049 (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
0050 return -EINVAL;
0051 return addr;
0052 }
0053
0054 if (len > TASK_SIZE)
0055 return -ENOMEM;
0056
0057 if (addr) {
0058 if (do_align)
0059 addr = COLOUR_ALIGN(addr, pgoff);
0060 else
0061 addr = PAGE_ALIGN(addr);
0062
0063 vma = find_vma(mm, addr);
0064 if (TASK_SIZE - len >= addr &&
0065 (!vma || addr + len <= vm_start_gap(vma)))
0066 return addr;
0067 }
0068
0069 info.flags = 0;
0070 info.length = len;
0071 info.low_limit = mm->mmap_base;
0072 info.high_limit = TASK_SIZE;
0073 info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
0074 info.align_offset = pgoff << PAGE_SHIFT;
0075 return vm_unmapped_area(&info);
0076 }
0077
0078 static const pgprot_t protection_map[16] = {
0079 [VM_NONE] = PAGE_U_NONE,
0080 [VM_READ] = PAGE_U_R,
0081 [VM_WRITE] = PAGE_U_R,
0082 [VM_WRITE | VM_READ] = PAGE_U_R,
0083 [VM_EXEC] = PAGE_U_X_R,
0084 [VM_EXEC | VM_READ] = PAGE_U_X_R,
0085 [VM_EXEC | VM_WRITE] = PAGE_U_X_R,
0086 [VM_EXEC | VM_WRITE | VM_READ] = PAGE_U_X_R,
0087 [VM_SHARED] = PAGE_U_NONE,
0088 [VM_SHARED | VM_READ] = PAGE_U_R,
0089 [VM_SHARED | VM_WRITE] = PAGE_U_W_R,
0090 [VM_SHARED | VM_WRITE | VM_READ] = PAGE_U_W_R,
0091 [VM_SHARED | VM_EXEC] = PAGE_U_X_R,
0092 [VM_SHARED | VM_EXEC | VM_READ] = PAGE_U_X_R,
0093 [VM_SHARED | VM_EXEC | VM_WRITE] = PAGE_U_X_W_R,
0094 [VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = PAGE_U_X_W_R
0095 };
0096 DECLARE_VM_GET_PAGE_PROT