@@ -84,13 +84,13 @@ static inline void mm_fault_error(struct pt_regs *regs, unsigned long addr, vm_f
8484 BUG ();
8585}
8686
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 )
8889{
8990 /*
9091 * Something tried to access memory that isn't in our memory map.
9192 * Fix it, but check if it's kernel or user first.
9293 */
93- mmap_read_unlock (mm );
9494 /* User mode accesses just cause a SIGSEGV */
9595 if (user_mode (regs )) {
9696 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
100100 no_context (regs , addr );
101101}
102102
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+
103112static inline void vmalloc_fault (struct pt_regs * regs , int code , unsigned long addr )
104113{
105114 pgd_t * pgd , * pgd_k ;
@@ -287,31 +296,17 @@ void handle_page_fault(struct pt_regs *regs)
287296 else if (cause == EXC_INST_PAGE_FAULT )
288297 flags |= FAULT_FLAG_INSTRUCTION ;
289298retry :
290- mmap_read_lock (mm );
291- vma = find_vma (mm , addr );
299+ vma = lock_mm_and_find_vma (mm , addr , regs );
292300 if (unlikely (!vma )) {
293301 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 );
307303 return ;
308304 }
309305
310306 /*
311307 * Ok, we have a good vm_area for this memory access, so
312308 * we can handle it.
313309 */
314- good_area :
315310 code = SEGV_ACCERR ;
316311
317312 if (unlikely (access_error (cause , vma ))) {
0 commit comments