@@ -83,13 +83,13 @@ static inline void mm_fault_error(struct pt_regs *regs, unsigned long addr, vm_f
83
83
BUG ();
84
84
}
85
85
86
- static inline void bad_area (struct pt_regs * regs , struct mm_struct * mm , int code , unsigned long addr )
86
+ static inline void
87
+ bad_area_nosemaphore (struct pt_regs * regs , int code , unsigned long addr )
87
88
{
88
89
/*
89
90
* Something tried to access memory that isn't in our memory map.
90
91
* Fix it, but check if it's kernel or user first.
91
92
*/
92
- mmap_read_unlock (mm );
93
93
/* User mode accesses just cause a SIGSEGV */
94
94
if (user_mode (regs )) {
95
95
do_trap (regs , SIGSEGV , code , addr );
@@ -99,6 +99,15 @@ static inline void bad_area(struct pt_regs *regs, struct mm_struct *mm, int code
99
99
no_context (regs , addr );
100
100
}
101
101
102
+ static inline void
103
+ bad_area (struct pt_regs * regs , struct mm_struct * mm , int code ,
104
+ unsigned long addr )
105
+ {
106
+ mmap_read_unlock (mm );
107
+
108
+ bad_area_nosemaphore (regs , code , addr );
109
+ }
110
+
102
111
static inline void vmalloc_fault (struct pt_regs * regs , int code , unsigned long addr )
103
112
{
104
113
pgd_t * pgd , * pgd_k ;
@@ -281,31 +290,17 @@ asmlinkage void do_page_fault(struct pt_regs *regs)
281
290
else if (cause == EXC_INST_PAGE_FAULT )
282
291
flags |= FAULT_FLAG_INSTRUCTION ;
283
292
retry :
284
- mmap_read_lock (mm );
285
- vma = find_vma (mm , addr );
293
+ vma = lock_mm_and_find_vma (mm , addr , regs );
286
294
if (unlikely (!vma )) {
287
295
tsk -> thread .bad_cause = cause ;
288
- bad_area (regs , mm , code , addr );
289
- return ;
290
- }
291
- if (likely (vma -> vm_start <= addr ))
292
- goto good_area ;
293
- if (unlikely (!(vma -> vm_flags & VM_GROWSDOWN ))) {
294
- tsk -> thread .bad_cause = cause ;
295
- bad_area (regs , mm , code , addr );
296
- return ;
297
- }
298
- if (unlikely (expand_stack (vma , addr ))) {
299
- tsk -> thread .bad_cause = cause ;
300
- bad_area (regs , mm , code , addr );
296
+ bad_area_nosemaphore (regs , code , addr );
301
297
return ;
302
298
}
303
299
304
300
/*
305
301
* Ok, we have a good vm_area for this memory access, so
306
302
* we can handle it.
307
303
*/
308
- good_area :
309
304
code = SEGV_ACCERR ;
310
305
311
306
if (unlikely (access_error (cause , vma ))) {
0 commit comments