7 #include <linux/sched.h>
9 #include <linux/module.h>
10 #include <asm/current.h>
11 #include <asm/pgtable.h>
12 #include <asm/tlbflush.h>
24 int is_write,
int is_user,
int *code_out)
33 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
34 (is_write ? FAULT_FLAG_WRITE : 0);
52 else if (!(vma->
vm_flags & VM_GROWSDOWN))
61 if (is_write && !(vma->
vm_flags & VM_WRITE))
65 if (!is_write && !(vma->
vm_flags & (VM_READ | VM_EXEC)))
73 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(
current))
76 if (
unlikely(fault & VM_FAULT_ERROR)) {
77 if (fault & VM_FAULT_OOM) {
79 }
else if (fault & VM_FAULT_SIGBUS) {
85 if (flags & FAULT_FLAG_ALLOW_RETRY) {
86 if (fault & VM_FAULT_MAJOR)
90 if (fault & VM_FAULT_RETRY) {
91 flags &= ~FAULT_FLAG_ALLOW_RETRY;
92 flags |= FAULT_FLAG_TRIED;
140 if (!printk_ratelimit())
143 printk(
"%s%s[%d]: segfault at %lx ip %p sp %p error %x",
153 static void bad_segv(
struct faultinfo fi,
unsigned long ip)
160 current->thread.arch.faultinfo = fi;
181 show_segv_info(regs);
182 bad_segv(*fi,
UPT_IP(regs));
209 panic(
"Segfault with no mm");
225 catcher =
current->thread.fault_catcher;
228 else if (catcher !=
NULL) {
229 current->thread.fault_addr = (
void *) address;
233 panic(
"fault_addr set but no fault catcher");
239 panic(
"Kernel mode fault at addr 0x%lx, ip 0x%lx",
243 show_segv_info(regs);
249 si.si_addr = (
void __user *)address;
250 current->thread.arch.faultinfo = fi;
255 si.si_addr = (
void __user *) address;
256 current->thread.arch.faultinfo = fi;
270 "mount likely just ran out of space\n");
271 panic(
"Kernel mode signal %d", sig);
276 memset(&clean_si, 0,
sizeof(clean_si));
288 current->thread.arch.faultinfo = *fi;
289 #ifdef __ARCH_SI_TRAPNO
290 clean_si.si_trapno = si->si_trapno;
294 printk(
KERN_ERR "Attempted to relay unknown signal %d (si_code = %d)\n",