xref: /kernel/linux/linux-5.10/arch/sh/mm/mmap.c (revision 8c2ecf20)
1/*
2 * arch/sh/mm/mmap.c
3 *
4 * Copyright (C) 2008 - 2009  Paul Mundt
5 *
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
8 * for more details.
9 */
10#include <linux/io.h>
11#include <linux/mm.h>
12#include <linux/sched/mm.h>
13#include <linux/mman.h>
14#include <linux/module.h>
15#include <asm/page.h>
16#include <asm/processor.h>
17
18unsigned long shm_align_mask = PAGE_SIZE - 1;	/* Sane caches */
19EXPORT_SYMBOL(shm_align_mask);
20
21#ifdef CONFIG_MMU
22/*
23 * To avoid cache aliases, we map the shared page with same color.
24 */
25static inline unsigned long COLOUR_ALIGN(unsigned long addr,
26					 unsigned long pgoff)
27{
28	unsigned long base = (addr + shm_align_mask) & ~shm_align_mask;
29	unsigned long off = (pgoff << PAGE_SHIFT) & shm_align_mask;
30
31	return base + off;
32}
33
34unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
35	unsigned long len, unsigned long pgoff, unsigned long flags)
36{
37	struct mm_struct *mm = current->mm;
38	struct vm_area_struct *vma;
39	int do_colour_align;
40	struct vm_unmapped_area_info info;
41
42	if (flags & MAP_FIXED) {
43		/* We do not accept a shared mapping if it would violate
44		 * cache aliasing constraints.
45		 */
46		if ((flags & MAP_SHARED) &&
47		    ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
48			return -EINVAL;
49		return addr;
50	}
51
52	if (unlikely(len > TASK_SIZE))
53		return -ENOMEM;
54
55	do_colour_align = 0;
56	if (filp || (flags & MAP_SHARED))
57		do_colour_align = 1;
58
59	if (addr) {
60		if (do_colour_align)
61			addr = COLOUR_ALIGN(addr, pgoff);
62		else
63			addr = PAGE_ALIGN(addr);
64
65		vma = find_vma(mm, addr);
66		if (TASK_SIZE - len >= addr &&
67		    (!vma || addr + len <= vm_start_gap(vma)))
68			return addr;
69	}
70
71	info.flags = 0;
72	info.length = len;
73	info.low_limit = TASK_UNMAPPED_BASE;
74	info.high_limit = TASK_SIZE;
75	info.align_mask = do_colour_align ? (PAGE_MASK & shm_align_mask) : 0;
76	info.align_offset = pgoff << PAGE_SHIFT;
77	return vm_unmapped_area(&info);
78}
79
80unsigned long
81arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
82			  const unsigned long len, const unsigned long pgoff,
83			  const unsigned long flags)
84{
85	struct vm_area_struct *vma;
86	struct mm_struct *mm = current->mm;
87	unsigned long addr = addr0;
88	int do_colour_align;
89	struct vm_unmapped_area_info info;
90
91	if (flags & MAP_FIXED) {
92		/* We do not accept a shared mapping if it would violate
93		 * cache aliasing constraints.
94		 */
95		if ((flags & MAP_SHARED) &&
96		    ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
97			return -EINVAL;
98		return addr;
99	}
100
101	if (unlikely(len > TASK_SIZE))
102		return -ENOMEM;
103
104	do_colour_align = 0;
105	if (filp || (flags & MAP_SHARED))
106		do_colour_align = 1;
107
108	/* requesting a specific address */
109	if (addr) {
110		if (do_colour_align)
111			addr = COLOUR_ALIGN(addr, pgoff);
112		else
113			addr = PAGE_ALIGN(addr);
114
115		vma = find_vma(mm, addr);
116		if (TASK_SIZE - len >= addr &&
117		    (!vma || addr + len <= vm_start_gap(vma)))
118			return addr;
119	}
120
121	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
122	info.length = len;
123	info.low_limit = PAGE_SIZE;
124	info.high_limit = mm->mmap_base;
125	info.align_mask = do_colour_align ? (PAGE_MASK & shm_align_mask) : 0;
126	info.align_offset = pgoff << PAGE_SHIFT;
127	addr = vm_unmapped_area(&info);
128
129	/*
130	 * A failed mmap() very likely causes application failure,
131	 * so fall back to the bottom-up function here. This scenario
132	 * can happen with large stack limits and large mmap()
133	 * allocations.
134	 */
135	if (addr & ~PAGE_MASK) {
136		VM_BUG_ON(addr != -ENOMEM);
137		info.flags = 0;
138		info.low_limit = TASK_UNMAPPED_BASE;
139		info.high_limit = TASK_SIZE;
140		addr = vm_unmapped_area(&info);
141	}
142
143	return addr;
144}
145#endif /* CONFIG_MMU */
146
147/*
148 * You really shouldn't be using read() or write() on /dev/mem.  This
149 * might go away in the future.
150 */
151int valid_phys_addr_range(phys_addr_t addr, size_t count)
152{
153	if (addr < __MEMORY_START)
154		return 0;
155	if (addr + count > __pa(high_memory))
156		return 0;
157
158	return 1;
159}
160
161int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
162{
163	return 1;
164}
165