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