Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/microblaze/mm/fault.c
10817 views
1
/*
2
* arch/microblaze/mm/fault.c
3
*
4
* Copyright (C) 2007 Xilinx, Inc. All rights reserved.
5
*
6
* Derived from "arch/ppc/mm/fault.c"
7
* Copyright (C) 1995-1996 Gary Thomas ([email protected])
8
*
9
* Derived from "arch/i386/mm/fault.c"
10
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
11
*
12
* Modified by Cort Dougan and Paul Mackerras.
13
*
14
* This file is subject to the terms and conditions of the GNU General
15
* Public License. See the file COPYING in the main directory of this
16
* archive for more details.
17
*
18
*/
19
20
#include <linux/module.h>
21
#include <linux/signal.h>
22
#include <linux/sched.h>
23
#include <linux/kernel.h>
24
#include <linux/errno.h>
25
#include <linux/string.h>
26
#include <linux/types.h>
27
#include <linux/ptrace.h>
28
#include <linux/mman.h>
29
#include <linux/mm.h>
30
#include <linux/interrupt.h>
31
32
#include <asm/page.h>
33
#include <asm/pgtable.h>
34
#include <asm/mmu.h>
35
#include <asm/mmu_context.h>
36
#include <asm/system.h>
37
#include <linux/uaccess.h>
38
#include <asm/exceptions.h>
39
40
static unsigned long pte_misses; /* updated by do_page_fault() */
41
static unsigned long pte_errors; /* updated by do_page_fault() */
42
43
/*
44
* Check whether the instruction at regs->pc is a store using
45
* an update addressing form which will update r1.
46
*/
47
static int store_updates_sp(struct pt_regs *regs)
48
{
49
unsigned int inst;
50
51
if (get_user(inst, (unsigned int __user *)regs->pc))
52
return 0;
53
/* check for 1 in the rD field */
54
if (((inst >> 21) & 0x1f) != 1)
55
return 0;
56
/* check for store opcodes */
57
if ((inst & 0xd0000000) == 0xd0000000)
58
return 1;
59
return 0;
60
}
61
62
63
/*
64
* bad_page_fault is called when we have a bad access from the kernel.
65
* It is called from do_page_fault above and from some of the procedures
66
* in traps.c.
67
*/
68
void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
69
{
70
const struct exception_table_entry *fixup;
71
/* MS: no context */
72
/* Are we prepared to handle this fault? */
73
fixup = search_exception_tables(regs->pc);
74
if (fixup) {
75
regs->pc = fixup->fixup;
76
return;
77
}
78
79
/* kernel has accessed a bad area */
80
die("kernel access of bad area", regs, sig);
81
}
82
83
/*
84
* The error_code parameter is ESR for a data fault,
85
* 0 for an instruction fault.
86
*/
87
void do_page_fault(struct pt_regs *regs, unsigned long address,
88
unsigned long error_code)
89
{
90
struct vm_area_struct *vma;
91
struct mm_struct *mm = current->mm;
92
siginfo_t info;
93
int code = SEGV_MAPERR;
94
int is_write = error_code & ESR_S;
95
int fault;
96
97
regs->ear = address;
98
regs->esr = error_code;
99
100
/* On a kernel SLB miss we can only check for a valid exception entry */
101
if (unlikely(kernel_mode(regs) && (address >= TASK_SIZE))) {
102
printk(KERN_WARNING "kernel task_size exceed");
103
_exception(SIGSEGV, regs, code, address);
104
}
105
106
/* for instr TLB miss and instr storage exception ESR_S is undefined */
107
if ((error_code & 0x13) == 0x13 || (error_code & 0x11) == 0x11)
108
is_write = 0;
109
110
if (unlikely(in_atomic() || !mm)) {
111
if (kernel_mode(regs))
112
goto bad_area_nosemaphore;
113
114
/* in_atomic() in user mode is really bad,
115
as is current->mm == NULL. */
116
printk(KERN_EMERG "Page fault in user mode with "
117
"in_atomic(), mm = %p\n", mm);
118
printk(KERN_EMERG "r15 = %lx MSR = %lx\n",
119
regs->r15, regs->msr);
120
die("Weird page fault", regs, SIGSEGV);
121
}
122
123
/* When running in the kernel we expect faults to occur only to
124
* addresses in user space. All other faults represent errors in the
125
* kernel and should generate an OOPS. Unfortunately, in the case of an
126
* erroneous fault occurring in a code path which already holds mmap_sem
127
* we will deadlock attempting to validate the fault against the
128
* address space. Luckily the kernel only validly references user
129
* space from well defined areas of code, which are listed in the
130
* exceptions table.
131
*
132
* As the vast majority of faults will be valid we will only perform
133
* the source reference check when there is a possibility of a deadlock.
134
* Attempt to lock the address space, if we cannot we then validate the
135
* source. If this is invalid we can skip the address space check,
136
* thus avoiding the deadlock.
137
*/
138
if (unlikely(!down_read_trylock(&mm->mmap_sem))) {
139
if (kernel_mode(regs) && !search_exception_tables(regs->pc))
140
goto bad_area_nosemaphore;
141
142
down_read(&mm->mmap_sem);
143
}
144
145
vma = find_vma(mm, address);
146
if (unlikely(!vma))
147
goto bad_area;
148
149
if (vma->vm_start <= address)
150
goto good_area;
151
152
if (unlikely(!(vma->vm_flags & VM_GROWSDOWN)))
153
goto bad_area;
154
155
if (unlikely(!is_write))
156
goto bad_area;
157
158
/*
159
* N.B. The ABI allows programs to access up to
160
* a few hundred bytes below the stack pointer (TBD).
161
* The kernel signal delivery code writes up to about 1.5kB
162
* below the stack pointer (r1) before decrementing it.
163
* The exec code can write slightly over 640kB to the stack
164
* before setting the user r1. Thus we allow the stack to
165
* expand to 1MB without further checks.
166
*/
167
if (unlikely(address + 0x100000 < vma->vm_end)) {
168
169
/* get user regs even if this fault is in kernel mode */
170
struct pt_regs *uregs = current->thread.regs;
171
if (uregs == NULL)
172
goto bad_area;
173
174
/*
175
* A user-mode access to an address a long way below
176
* the stack pointer is only valid if the instruction
177
* is one which would update the stack pointer to the
178
* address accessed if the instruction completed,
179
* i.e. either stwu rs,n(r1) or stwux rs,r1,rb
180
* (or the byte, halfword, float or double forms).
181
*
182
* If we don't check this then any write to the area
183
* between the last mapped region and the stack will
184
* expand the stack rather than segfaulting.
185
*/
186
if (address + 2048 < uregs->r1
187
&& (kernel_mode(regs) || !store_updates_sp(regs)))
188
goto bad_area;
189
}
190
if (expand_stack(vma, address))
191
goto bad_area;
192
193
good_area:
194
code = SEGV_ACCERR;
195
196
/* a write */
197
if (unlikely(is_write)) {
198
if (unlikely(!(vma->vm_flags & VM_WRITE)))
199
goto bad_area;
200
/* a read */
201
} else {
202
/* protection fault */
203
if (unlikely(error_code & 0x08000000))
204
goto bad_area;
205
if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC))))
206
goto bad_area;
207
}
208
209
/*
210
* If for any reason at all we couldn't handle the fault,
211
* make sure we exit gracefully rather than endlessly redo
212
* the fault.
213
*/
214
fault = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0);
215
if (unlikely(fault & VM_FAULT_ERROR)) {
216
if (fault & VM_FAULT_OOM)
217
goto out_of_memory;
218
else if (fault & VM_FAULT_SIGBUS)
219
goto do_sigbus;
220
BUG();
221
}
222
if (unlikely(fault & VM_FAULT_MAJOR))
223
current->maj_flt++;
224
else
225
current->min_flt++;
226
up_read(&mm->mmap_sem);
227
/*
228
* keep track of tlb+htab misses that are good addrs but
229
* just need pte's created via handle_mm_fault()
230
* -- Cort
231
*/
232
pte_misses++;
233
return;
234
235
bad_area:
236
up_read(&mm->mmap_sem);
237
238
bad_area_nosemaphore:
239
pte_errors++;
240
241
/* User mode accesses cause a SIGSEGV */
242
if (user_mode(regs)) {
243
_exception(SIGSEGV, regs, code, address);
244
/* info.si_signo = SIGSEGV;
245
info.si_errno = 0;
246
info.si_code = code;
247
info.si_addr = (void *) address;
248
force_sig_info(SIGSEGV, &info, current);*/
249
return;
250
}
251
252
bad_page_fault(regs, address, SIGSEGV);
253
return;
254
255
/*
256
* We ran out of memory, or some other thing happened to us that made
257
* us unable to handle the page fault gracefully.
258
*/
259
out_of_memory:
260
up_read(&mm->mmap_sem);
261
if (!user_mode(regs))
262
bad_page_fault(regs, address, SIGKILL);
263
else
264
pagefault_out_of_memory();
265
return;
266
267
do_sigbus:
268
up_read(&mm->mmap_sem);
269
if (user_mode(regs)) {
270
info.si_signo = SIGBUS;
271
info.si_errno = 0;
272
info.si_code = BUS_ADRERR;
273
info.si_addr = (void __user *)address;
274
force_sig_info(SIGBUS, &info, current);
275
return;
276
}
277
bad_page_fault(regs, address, SIGBUS);
278
}
279
280