@@ -16,6 +16,7 @@
struct task_struct;
void show_regs(struct pt_regs *regs);
+void show_exception_mesg(struct pt_regs *regs);
void show_stacktrace(struct task_struct *tsk, struct pt_regs *regs);
void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
unsigned long address);
@@ -49,6 +49,9 @@ unhandled_exception(const char *str, struct pt_regs *regs, siginfo_t *info)
tsk->thread.fault_address = (__force unsigned int)info->si_addr;
+ if (unhandled_signal(tsk, info->si_signo))
+ show_exception_mesg(regs);
+
force_sig_info(info->si_signo, info, tsk);
} else {
@@ -101,13 +101,13 @@ static void show_faulting_vma(unsigned long address, char *buf)
if (IS_ERR(nm))
nm = "?";
}
- pr_info(" @off 0x%lx in [%s]\n"
- " VMA: 0x%08lx to 0x%08lx\n",
+
+ pr_cont("[off 0x%lx in %s, VMA: %08lx:%08lx] ",
vma->vm_start < TASK_UNMAPPED_BASE ?
address : address - vma->vm_start,
nm, vma->vm_start, vma->vm_end);
} else
- pr_info(" @No matching VMA found\n");
+ pr_cont("[No matching VMA found] ");
up_read(&active_mm->mmap_sem);
}
@@ -117,7 +117,7 @@ static void show_ecr_verbose(struct pt_regs *regs)
unsigned int vec, cause_code;
unsigned long address;
- pr_info("\n[ECR ]: 0x%08lx => ", regs->event);
+ pr_cont("\n ECR: 0x%08lx => ", regs->event);
/* For Data fault, this is data address not instruction addr */
address = current->thread.fault_address;
@@ -165,10 +165,42 @@ static void show_ecr_verbose(struct pt_regs *regs)
}
}
+static inline void show_exception_mesg_u(struct pt_regs *regs)
+{
+ struct task_struct *tsk = current;
+ char *buf;
+
+ pr_info("Exception: %s[%d]: at %pS ",
+ tsk->comm, task_pid_nr(tsk), (void *)regs->ret);
+
+ buf = (char *)__get_free_page(GFP_NOWAIT);
+ if (buf) {
+ show_faulting_vma(regs->ret, buf);
+ free_page((unsigned long)buf);
+ }
+
+ show_ecr_verbose(regs);
+}
+
+static inline void show_exception_mesg_k(struct pt_regs *regs)
+{
+ pr_info("Exception: at %pS:", (void *)regs->ret);
+
+ show_ecr_verbose(regs);
+}
+
/************************************************************************
* API called by rest of kernel
***********************************************************************/
+void show_exception_mesg(struct pt_regs *regs)
+{
+ if (user_mode(regs))
+ show_exception_mesg_u(regs);
+ else
+ show_exception_mesg_k(regs);
+}
+
void show_regs(struct pt_regs *regs)
{
struct task_struct *tsk = current;
@@ -182,15 +214,10 @@ void show_regs(struct pt_regs *regs)
print_task_path_n_nm(tsk, buf);
show_regs_print_info(KERN_INFO);
- show_ecr_verbose(regs);
-
- pr_info("[EFA ]: 0x%08lx\n[BLINK ]: %pS\n[ERET ]: %pS\n",
- current->thread.fault_address,
+ pr_info("[ECR ]: 0x%08lx\n[EFA ]: 0x%08lx\n[BLINK ]: %pS\n[ERET ]: %pS\n",
+ regs->event, current->thread.fault_address,
(void *)regs->blink, (void *)regs->ret);
- if (user_mode(regs))
- show_faulting_vma(regs->ret, buf); /* faulting code, not data */
-
pr_info("[STAT32]: 0x%08lx", regs->status32);
#define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit" " : ""
@@ -233,6 +260,8 @@ void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
/* Show fault description */
pr_info("\n%s\n", str);
+ show_exception_mesg(regs);
+
/* Caller and Callee regs */
show_regs(regs);
@@ -203,6 +203,10 @@ void do_page_fault(unsigned long address, struct pt_regs *regs)
info.si_errno = 0;
/* info.si_code has been set above */
info.si_addr = (void __user *)address;
+
+ if (unhandled_signal(tsk, info.si_signo))
+ show_exception_mesg(regs);
+
force_sig_info(SIGSEGV, &info, tsk);
return;
}
@@ -242,5 +246,9 @@ void do_page_fault(unsigned long address, struct pt_regs *regs)
info.si_errno = 0;
info.si_code = BUS_ADRERR;
info.si_addr = (void __user *)address;
+
+ if (unhandled_signal(tsk, info.si_signo))
+ show_exception_mesg(regs);
+
force_sig_info(SIGBUS, &info, tsk);
}