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.h>
17 #include <asm/cacheflush.h>
19 #define COLOUR_ALIGN(addr, pgoff) \
20 ((((addr) + SHMLBA - 1) & ~(SHMLBA - 1)) + \
21 (((pgoff) << PAGE_SHIFT) & (SHMLBA - 1)))
24 * Ensure that shared mappings are correctly aligned to
25 * avoid aliasing issues with VIPT caches.
26 * We need to ensure that
27 * a specific page of an object is always mapped at a multiple of
31 arch_get_unmapped_area(struct file
*filp
, unsigned long addr
,
32 unsigned long len
, unsigned long pgoff
, unsigned long flags
)
34 struct mm_struct
*mm
= current
->mm
;
35 struct vm_area_struct
*vma
;
37 int aliasing
= cache_is_vipt_aliasing();
38 struct vm_unmapped_area_info info
;
41 * We only need to do colour alignment if D cache aliases.
44 do_align
= filp
|| (flags
& MAP_SHARED
);
47 * We enforce the MAP_FIXED case.
49 if (flags
& MAP_FIXED
) {
50 if (aliasing
&& flags
& MAP_SHARED
&&
51 (addr
- (pgoff
<< PAGE_SHIFT
)) & (SHMLBA
- 1))
61 addr
= COLOUR_ALIGN(addr
, pgoff
);
63 addr
= PAGE_ALIGN(addr
);
65 vma
= find_vma(mm
, addr
);
66 if (TASK_SIZE
- len
>= addr
&&
67 (!vma
|| addr
+ len
<= vma
->vm_start
))
73 info
.low_limit
= mm
->mmap_base
;
74 info
.high_limit
= TASK_SIZE
;
75 info
.align_mask
= do_align
? (PAGE_MASK
& (SHMLBA
- 1)) : 0;
76 info
.align_offset
= pgoff
<< PAGE_SHIFT
;
77 return vm_unmapped_area(&info
);