4 * (started from arm version - for VIPT alias handling)
6 * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com)
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
15 #include <linux/mman.h>
16 #include <linux/sched/mm.h>
18 #include <asm/cacheflush.h>
20 #define COLOUR_ALIGN(addr, pgoff) \
21 ((((addr) + SHMLBA - 1) & ~(SHMLBA - 1)) + \
22 (((pgoff) << PAGE_SHIFT) & (SHMLBA - 1)))
25 * Ensure that shared mappings are correctly aligned to
26 * avoid aliasing issues with VIPT caches.
27 * We need to ensure that
28 * a specific page of an object is always mapped at a multiple of
32 arch_get_unmapped_area(struct file
*filp
, unsigned long addr
,
33 unsigned long len
, unsigned long pgoff
, unsigned long flags
)
35 struct mm_struct
*mm
= current
->mm
;
36 struct vm_area_struct
*vma
;
38 int aliasing
= cache_is_vipt_aliasing();
39 struct vm_unmapped_area_info info
;
42 * We only need to do colour alignment if D cache aliases.
45 do_align
= filp
|| (flags
& MAP_SHARED
);
48 * We enforce the MAP_FIXED case.
50 if (flags
& MAP_FIXED
) {
51 if (aliasing
&& flags
& MAP_SHARED
&&
52 (addr
- (pgoff
<< PAGE_SHIFT
)) & (SHMLBA
- 1))
62 addr
= COLOUR_ALIGN(addr
, pgoff
);
64 addr
= PAGE_ALIGN(addr
);
66 vma
= find_vma(mm
, addr
);
67 if (TASK_SIZE
- len
>= addr
&&
68 (!vma
|| addr
+ len
<= vm_start_gap(vma
)))
74 info
.low_limit
= mm
->mmap_base
;
75 info
.high_limit
= TASK_SIZE
;
76 info
.align_mask
= do_align
? (PAGE_MASK
& (SHMLBA
- 1)) : 0;
77 info
.align_offset
= pgoff
<< PAGE_SHIFT
;
78 return vm_unmapped_area(&info
);