1 // SPDX-License-Identifier: GPL-2.0-only
5 * (started from arm version - for VIPT alias handling)
7 * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com)
12 #include <linux/mman.h>
13 #include <linux/sched/mm.h>
15 #include <asm/cacheflush.h>
17 #define COLOUR_ALIGN(addr, pgoff) \
18 ((((addr) + SHMLBA - 1) & ~(SHMLBA - 1)) + \
19 (((pgoff) << PAGE_SHIFT) & (SHMLBA - 1)))
22 * Ensure that shared mappings are correctly aligned to
23 * avoid aliasing issues with VIPT caches.
24 * We need to ensure that
25 * a specific page of an object is always mapped at a multiple of
29 arch_get_unmapped_area(struct file
*filp
, unsigned long addr
,
30 unsigned long len
, unsigned long pgoff
, unsigned long flags
)
32 struct mm_struct
*mm
= current
->mm
;
33 struct vm_area_struct
*vma
;
35 int aliasing
= cache_is_vipt_aliasing();
36 struct vm_unmapped_area_info info
;
39 * We only need to do colour alignment if D cache aliases.
42 do_align
= filp
|| (flags
& MAP_SHARED
);
45 * We enforce the MAP_FIXED case.
47 if (flags
& MAP_FIXED
) {
48 if (aliasing
&& flags
& MAP_SHARED
&&
49 (addr
- (pgoff
<< PAGE_SHIFT
)) & (SHMLBA
- 1))
59 addr
= COLOUR_ALIGN(addr
, pgoff
);
61 addr
= PAGE_ALIGN(addr
);
63 vma
= find_vma(mm
, addr
);
64 if (TASK_SIZE
- len
>= addr
&&
65 (!vma
|| addr
+ len
<= vm_start_gap(vma
)))
71 info
.low_limit
= mm
->mmap_base
;
72 info
.high_limit
= TASK_SIZE
;
73 info
.align_mask
= do_align
? (PAGE_MASK
& (SHMLBA
- 1)) : 0;
74 info
.align_offset
= pgoff
<< PAGE_SHIFT
;
75 return vm_unmapped_area(&info
);