diff options
Diffstat (limited to 'arch/s390/mm/fault.c')
-rw-r--r-- | arch/s390/mm/fault.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index c220399ae196..0ba174f779da 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -83,9 +83,8 @@ static inline int notify_page_fault(struct pt_regs *regs) /* * Find out which address space caused the exception. - * Access register mode is impossible, ignore space == 3. */ -static inline enum fault_type get_fault_type(struct pt_regs *regs) +static enum fault_type get_fault_type(struct pt_regs *regs) { unsigned long trans_exc_code; @@ -108,6 +107,10 @@ static inline enum fault_type get_fault_type(struct pt_regs *regs) } return VDSO_FAULT; } + if (trans_exc_code == 1) { + /* access register mode, not used in the kernel */ + return USER_FAULT; + } /* home space exception -> access via kernel ASCE */ return KERNEL_FAULT; } @@ -211,6 +214,8 @@ static void dump_fault_info(struct pt_regs *regs) asce = S390_lowcore.kernel_asce; pr_cont("kernel "); break; + default: + unreachable(); } pr_cont("ASCE.\n"); dump_pagetable(asce, regs->int_parm_long & __FAIL_ADDR_MASK); @@ -243,8 +248,7 @@ static noinline void do_sigsegv(struct pt_regs *regs, int si_code) { report_user_fault(regs, SIGSEGV, 1); force_sig_fault(SIGSEGV, si_code, - (void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK), - current); + (void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK)); } const struct exception_table_entry *s390_search_extables(unsigned long addr) @@ -305,8 +309,7 @@ static noinline void do_sigbus(struct pt_regs *regs) * or user mode. */ force_sig_fault(SIGBUS, BUS_ADRERR, - (void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK), - current); + (void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK)); } static noinline int signal_return(struct pt_regs *regs) |