aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel/trap_kern.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/kernel/trap_kern.c')
-rw-r--r--arch/um/kernel/trap_kern.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
index 87cc6fd76ced..d297429ac360 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap_kern.c
@@ -18,6 +18,7 @@
18#include "asm/a.out.h" 18#include "asm/a.out.h"
19#include "asm/current.h" 19#include "asm/current.h"
20#include "asm/irq.h" 20#include "asm/irq.h"
21#include "sysdep/sigcontext.h"
21#include "user_util.h" 22#include "user_util.h"
22#include "kern_util.h" 23#include "kern_util.h"
23#include "kern.h" 24#include "kern.h"
@@ -39,6 +40,12 @@ int handle_page_fault(unsigned long address, unsigned long ip,
39 int err = -EFAULT; 40 int err = -EFAULT;
40 41
41 *code_out = SEGV_MAPERR; 42 *code_out = SEGV_MAPERR;
43
44 /* If the fault was during atomic operation, don't take the fault, just
45 * fail. */
46 if (in_atomic())
47 goto out_nosemaphore;
48
42 down_read(&mm->mmap_sem); 49 down_read(&mm->mmap_sem);
43 vma = find_vma(mm, address); 50 vma = find_vma(mm, address);
44 if(!vma) 51 if(!vma)
@@ -89,6 +96,7 @@ survive:
89 flush_tlb_page(vma, address); 96 flush_tlb_page(vma, address);
90out: 97out:
91 up_read(&mm->mmap_sem); 98 up_read(&mm->mmap_sem);
99out_nosemaphore:
92 return(err); 100 return(err);
93 101
94/* 102/*
@@ -125,7 +133,15 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
125 } 133 }
126 else if(current->mm == NULL) 134 else if(current->mm == NULL)
127 panic("Segfault with no mm"); 135 panic("Segfault with no mm");
128 err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); 136
137 if (SEGV_IS_FIXABLE(&fi))
138 err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
139 else {
140 err = -EFAULT;
141 /* A thread accessed NULL, we get a fault, but CR2 is invalid.
142 * This code is used in __do_copy_from_user() of TT mode. */
143 address = 0;
144 }
129 145
130 catcher = current->thread.fault_catcher; 146 catcher = current->thread.fault_catcher;
131 if(!err) 147 if(!err)