@@ -225,7 +225,7 @@ static void do_sigsegv(struct pt_regs *regs, int si_code)
225225 force_sig_fault (SIGSEGV , si_code , (void __user * )get_fault_address (regs ));
226226}
227227
228- static void do_no_context (struct pt_regs * regs , int si_code )
228+ static void handle_fault_error_nolock (struct pt_regs * regs , int si_code )
229229{
230230 enum fault_type fault_type ;
231231 unsigned long address ;
@@ -253,11 +253,6 @@ static void do_no_context(struct pt_regs *regs, int si_code)
253253 die (regs , "Oops" );
254254}
255255
256- static inline void handle_fault_error_nolock (struct pt_regs * regs , int si_code )
257- {
258- do_no_context (regs , si_code );
259- }
260-
261256static void handle_fault_error (struct pt_regs * regs , int si_code )
262257{
263258 struct mm_struct * mm = current -> mm ;
@@ -271,31 +266,6 @@ static void do_sigbus(struct pt_regs *regs)
271266 force_sig_fault (SIGBUS , BUS_ADRERR , (void __user * )get_fault_address (regs ));
272267}
273268
274- static void do_fault_error (struct pt_regs * regs , vm_fault_t fault )
275- {
276- /* fault & VM_FAULT_ERROR */
277- if (fault & VM_FAULT_OOM ) {
278- if (!user_mode (regs ))
279- do_no_context (regs , 0 );
280- else
281- pagefault_out_of_memory ();
282- } else if (fault & VM_FAULT_SIGSEGV ) {
283- /* Kernel mode? Handle exceptions or die */
284- if (!user_mode (regs ))
285- do_no_context (regs , 0 );
286- else
287- do_sigsegv (regs , SEGV_MAPERR );
288- } else if (fault & VM_FAULT_SIGBUS ) {
289- /* Kernel mode? Handle exceptions or die */
290- if (!user_mode (regs ))
291- do_no_context (regs , 0 );
292- else
293- do_sigbus (regs );
294- } else {
295- BUG ();
296- }
297- }
298-
299269/*
300270 * This routine handles page faults. It determines the address,
301271 * and the problem, and then passes it off to one of the appropriate
@@ -362,9 +332,9 @@ static void do_exception(struct pt_regs *regs, int access)
362332 vma_end_read (vma );
363333 if (!(fault & VM_FAULT_RETRY )) {
364334 count_vm_vma_lock_event (VMA_LOCK_SUCCESS );
365- if (likely (!( fault & VM_FAULT_ERROR ) ))
366- fault = 0 ;
367- goto out ;
335+ if (unlikely ( fault & VM_FAULT_ERROR ))
336+ goto error ;
337+ return ;
368338 }
369339 count_vm_vma_lock_event (VMA_LOCK_RETRY );
370340 /* Quick path to respond to signals */
@@ -412,13 +382,14 @@ static void do_exception(struct pt_regs *regs, int access)
412382 if (fault & VM_FAULT_COMPLETED ) {
413383 if (gmap ) {
414384 mmap_read_lock (mm );
415- goto out_gmap ;
385+ goto gmap ;
416386 }
417- fault = 0 ;
418- goto out ;
387+ return ;
388+ }
389+ if (unlikely (fault & VM_FAULT_ERROR )) {
390+ mmap_read_unlock (mm );
391+ goto error ;
419392 }
420- if (unlikely (fault & VM_FAULT_ERROR ))
421- goto out_up ;
422393 if (fault & VM_FAULT_RETRY ) {
423394 if (IS_ENABLED (CONFIG_PGSTE ) && gmap && (flags & FAULT_FLAG_RETRY_NOWAIT )) {
424395 /*
@@ -433,23 +404,39 @@ static void do_exception(struct pt_regs *regs, int access)
433404 mmap_read_lock (mm );
434405 goto retry ;
435406 }
436- out_gmap :
407+ gmap :
437408 if (IS_ENABLED (CONFIG_PGSTE ) && gmap ) {
438409 address = __gmap_link (gmap , current -> thread .gmap_addr ,
439410 address );
440411 if (address == - EFAULT )
441412 return handle_fault_error (regs , SEGV_MAPERR );
442413 if (address == - ENOMEM ) {
443414 fault = VM_FAULT_OOM ;
444- goto out_up ;
415+ mmap_read_unlock (mm );
416+ goto error ;
445417 }
446418 }
447- fault = 0 ;
448- out_up :
449419 mmap_read_unlock (mm );
450- out :
451- if (unlikely (fault ))
452- do_fault_error (regs , fault );
420+ return ;
421+ error :
422+ if (fault & VM_FAULT_OOM ) {
423+ if (!user_mode (regs ))
424+ handle_fault_error_nolock (regs , 0 );
425+ else
426+ pagefault_out_of_memory ();
427+ } else if (fault & VM_FAULT_SIGSEGV ) {
428+ if (!user_mode (regs ))
429+ handle_fault_error_nolock (regs , 0 );
430+ else
431+ do_sigsegv (regs , SEGV_MAPERR );
432+ } else if (fault & VM_FAULT_SIGBUS ) {
433+ if (!user_mode (regs ))
434+ handle_fault_error_nolock (regs , 0 );
435+ else
436+ do_sigbus (regs );
437+ } else {
438+ BUG ();
439+ }
453440}
454441
455442void do_protection_exception (struct pt_regs * regs )
@@ -477,7 +464,7 @@ void do_protection_exception(struct pt_regs *regs)
477464 * Low-address protection in kernel mode means
478465 * NULL pointer write access in kernel mode.
479466 */
480- return do_no_context (regs , 0 );
467+ return handle_fault_error_nolock (regs , 0 );
481468 }
482469 if (unlikely (MACHINE_HAS_NX && teid .b56 )) {
483470 regs -> int_parm_long = (teid .addr * PAGE_SIZE ) | (regs -> psw .addr & PAGE_MASK );
0 commit comments