From e070dab73523bcbf2409ba8b5c342d53bccc0959 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 23 Jul 2015 11:10:38 +0200 Subject: MIPS: Handle page faults of executable but unreadable pages correctly. Without this we end taking execeptions in an endless loop hanging the thread. Signed-off-by: Ralf Baechle --- arch/mips/mm/fault.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/mips/mm/fault.c') diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 36c0f26fac6b..852a41c6da45 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -133,7 +133,8 @@ good_area: #endif goto bad_area; } - if (!(vma->vm_flags & VM_READ)) { + if (!(vma->vm_flags & VM_READ) && + exception_epc(regs) != address) { #if 0 pr_notice("Cpu%d[%s:%d:%0*lx:%ld:%0*lx] RI violation\n", raw_smp_processor_id(), -- cgit v1.2.3 From e3b28831c18c6c95c51b6bb717fa116d2b658ba9 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 28 Jul 2015 20:37:43 +0200 Subject: MIPS: Set trap_no field in thread_struct on exception. This reverts commit 7281cd22973008a782860e48ed8d85d00204168c and adds actual functionality to use the field. --- arch/mips/mm/fault.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/mips/mm/fault.c') diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 852a41c6da45..4b88fa031891 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -57,12 +57,10 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write, #ifdef CONFIG_KPROBES /* - * This is to notify the fault handler of the kprobes. The - * exception code is redundant as it is also carried in REGS, - * but we pass it anyhow. + * This is to notify the fault handler of the kprobes. */ if (notify_die(DIE_PAGE_FAULT, "page fault", regs, -1, - (regs->cp0_cause >> 2) & 0x1f, SIGSEGV) == NOTIFY_STOP) + current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP) return; #endif @@ -224,6 +222,7 @@ bad_area_nosemaphore: print_vma_addr(" ", regs->regs[31]); pr_info("\n"); } + current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f; info.si_signo = SIGSEGV; info.si_errno = 0; /* info.si_code has been set above */ @@ -282,6 +281,7 @@ do_sigbus: field, (unsigned long) regs->cp0_epc, field, (unsigned long) regs->regs[31]); #endif + current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f; tsk->thread.cp0_badvaddr = address; info.si_signo = SIGBUS; info.si_errno = 0; -- cgit v1.2.3