Merge tag 'asoc-fix-v5.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/brooni...
[linux-2.6-block.git] / arch / csky / abiv1 / mmap.c
CommitLineData
013de2d6
GR
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3
4#include <linux/fs.h>
5#include <linux/mm.h>
6#include <linux/mman.h>
7#include <linux/shm.h>
8#include <linux/sched.h>
9#include <linux/random.h>
10#include <linux/io.h>
11
12unsigned long shm_align_mask = (0x4000 >> 1) - 1; /* Sane caches */
13
14#define COLOUR_ALIGN(addr, pgoff) \
15 ((((addr) + shm_align_mask) & ~shm_align_mask) + \
16 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
17
18unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
19 unsigned long len, unsigned long pgoff, unsigned long flags)
20{
21 struct vm_area_struct *vmm;
22 int do_color_align;
23
24 if (flags & MAP_FIXED) {
25 /*
26 * We do not accept a shared mapping if it would violate
27 * cache aliasing constraints.
28 */
29 if ((flags & MAP_SHARED) &&
30 ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
31 return -EINVAL;
32 return addr;
33 }
34
35 if (len > TASK_SIZE)
36 return -ENOMEM;
37 do_color_align = 0;
38 if (filp || (flags & MAP_SHARED))
39 do_color_align = 1;
40 if (addr) {
41 if (do_color_align)
42 addr = COLOUR_ALIGN(addr, pgoff);
43 else
44 addr = PAGE_ALIGN(addr);
45 vmm = find_vma(current->mm, addr);
46 if (TASK_SIZE - len >= addr &&
47 (!vmm || addr + len <= vmm->vm_start))
48 return addr;
49 }
50 addr = TASK_UNMAPPED_BASE;
51 if (do_color_align)
52 addr = COLOUR_ALIGN(addr, pgoff);
53 else
54 addr = PAGE_ALIGN(addr);
55
56 for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
57 /* At this point: (!vmm || addr < vmm->vm_end). */
58 if (TASK_SIZE - len < addr)
59 return -ENOMEM;
60 if (!vmm || addr + len <= vmm->vm_start)
61 return addr;
62 addr = vmm->vm_end;
63 if (do_color_align)
64 addr = COLOUR_ALIGN(addr, pgoff);
65 }
66}