1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
6 #include <linux/mman.h>
8 #include <linux/sched.h>
9 #include <linux/random.h>
12 unsigned long shm_align_mask
= (0x4000 >> 1) - 1; /* Sane caches */
14 #define COLOUR_ALIGN(addr, pgoff) \
15 ((((addr) + shm_align_mask) & ~shm_align_mask) + \
16 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
18 unsigned long arch_get_unmapped_area(struct file
*filp
, unsigned long addr
,
19 unsigned long len
, unsigned long pgoff
, unsigned long flags
)
21 struct vm_area_struct
*vmm
;
24 if (flags
& MAP_FIXED
) {
26 * We do not accept a shared mapping if it would violate
27 * cache aliasing constraints.
29 if ((flags
& MAP_SHARED
) &&
30 ((addr
- (pgoff
<< PAGE_SHIFT
)) & shm_align_mask
))
38 if (filp
|| (flags
& MAP_SHARED
))
42 addr
= COLOUR_ALIGN(addr
, pgoff
);
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
))
50 addr
= TASK_UNMAPPED_BASE
;
52 addr
= COLOUR_ALIGN(addr
, pgoff
);
54 addr
= PAGE_ALIGN(addr
);
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
)
60 if (!vmm
|| addr
+ len
<= vmm
->vm_start
)
64 addr
= COLOUR_ALIGN(addr
, pgoff
);