Skip to content

Commit b20c821

Browse files
hcahcaVasily Gorbik
authored andcommitted
s390/mm,fault: move VM_FAULT_ERROR handling to do_exception()
Get rid of do_fault_error() and move its contents to do_exception(), which makes do_exception(). With removing do_fault_error() it is also possible to get rid of the handle_fault_error_nolock() wrapper. Instead rename do_no_context() to handle_fault_error_nolock(). In result the whole fault handling looks much more like on other architectures. Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
1 parent 7c194d8 commit b20c821

1 file changed

Lines changed: 34 additions & 47 deletions

File tree

arch/s390/mm/fault.c

Lines changed: 34 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
261256
static 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

455442
void 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

Comments
 (0)