4 * Copyright (C) 2008 Paul Mundt
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
12 #include <linux/mman.h>
13 #include <linux/module.h>
15 #include <asm/processor.h>
18 unsigned long shm_align_mask
= PAGE_SIZE
- 1; /* Sane caches */
19 EXPORT_SYMBOL(shm_align_mask
);
22 * To avoid cache aliases, we map the shared page with same color.
24 #define COLOUR_ALIGN(addr, pgoff) \
25 ((((addr) + shm_align_mask) & ~shm_align_mask) + \
26 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
28 unsigned long arch_get_unmapped_area(struct file
*filp
, unsigned long addr
,
29 unsigned long len
, unsigned long pgoff
, unsigned long flags
)
31 struct mm_struct
*mm
= current
->mm
;
32 struct vm_area_struct
*vma
;
33 unsigned long start_addr
;
36 if (flags
& MAP_FIXED
) {
37 /* We do not accept a shared mapping if it would violate
38 * cache aliasing constraints.
40 if ((flags
& MAP_SHARED
) && (addr
& shm_align_mask
))
45 if (unlikely(len
> TASK_SIZE
))
49 if (filp
|| (flags
& MAP_SHARED
))
54 addr
= COLOUR_ALIGN(addr
, pgoff
);
56 addr
= PAGE_ALIGN(addr
);
58 vma
= find_vma(mm
, addr
);
59 if (TASK_SIZE
- len
>= addr
&&
60 (!vma
|| addr
+ len
<= vma
->vm_start
))
64 if (len
> mm
->cached_hole_size
) {
65 start_addr
= addr
= mm
->free_area_cache
;
67 mm
->cached_hole_size
= 0;
68 start_addr
= addr
= TASK_UNMAPPED_BASE
;
73 addr
= COLOUR_ALIGN(addr
, pgoff
);
75 addr
= PAGE_ALIGN(mm
->free_area_cache
);
77 for (vma
= find_vma(mm
, addr
); ; vma
= vma
->vm_next
) {
78 /* At this point: (!vma || addr < vma->vm_end). */
79 if (unlikely(TASK_SIZE
- len
< addr
)) {
81 * Start a new search - just in case we missed
84 if (start_addr
!= TASK_UNMAPPED_BASE
) {
85 start_addr
= addr
= TASK_UNMAPPED_BASE
;
86 mm
->cached_hole_size
= 0;
91 if (likely(!vma
|| addr
+ len
<= vma
->vm_start
)) {
93 * Remember the place where we stopped the search:
95 mm
->free_area_cache
= addr
+ len
;
98 if (addr
+ mm
->cached_hole_size
< vma
->vm_start
)
99 mm
->cached_hole_size
= vma
->vm_start
- addr
;
103 addr
= COLOUR_ALIGN(addr
, pgoff
);
106 #endif /* CONFIG_MMU */
109 * You really shouldn't be using read() or write() on /dev/mem. This
110 * might go away in the future.
112 int valid_phys_addr_range(unsigned long addr
, size_t count
)
114 if (addr
< __MEMORY_START
)
116 if (addr
+ count
> __pa(high_memory
))
122 int valid_mmap_phys_addr_range(unsigned long pfn
, size_t size
)