Commit c3a85f1f authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: Oops cleanup

From: Anton Blanchard <anton@samba.org>

Oops cleanup:

- Move prototypes into system.h
- Move the debugger hooks into die, all the calls sites were calling them.
- Handle bad values passed to prregs
parent fbe3e9b6
......@@ -37,9 +37,6 @@
#include <asm/processor.h>
#include <asm/ppcdebug.h>
extern int fix_alignment(struct pt_regs *);
extern void bad_page_fault(struct pt_regs *, unsigned long, int);
#ifdef CONFIG_PPC_PSERIES
/* This is true if we are using the firmware NMI handler (typically LPAR) */
extern int fwnmi_active;
......@@ -67,11 +64,17 @@ EXPORT_SYMBOL(__debugger_fault_handler);
static spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
void die(const char *str, struct pt_regs *regs, long err)
int die(const char *str, struct pt_regs *regs, long err)
{
static int die_counter;
int nl = 0;
if (debugger_fault_handler(regs))
return 1;
if (debugger(regs))
return 1;
console_verbose();
spin_lock_irq(&die_lock);
bust_spinlocks(1);
......@@ -126,15 +129,16 @@ void die(const char *str, struct pt_regs *regs, long err)
panic("Fatal exception");
}
do_exit(SIGSEGV);
return 0;
}
static void
_exception(int signr, siginfo_t *info, struct pt_regs *regs)
{
if (!user_mode(regs)) {
if (debugger(regs))
if (die("Exception in kernel mode", regs, signr))
return;
die("Exception in kernel mode", regs, signr);
}
force_sig_info(signr, info, current);
......@@ -188,7 +192,6 @@ SystemResetException(struct pt_regs *regs)
}
#endif
if (!debugger(regs))
die("System Reset", regs, 0);
/* Must die if the interrupt is not recoverable */
......@@ -246,9 +249,6 @@ static int recover_mce(struct pt_regs *regs, struct rtas_error_log err)
*
* On hardware prior to Power 4 these exceptions were asynchronous which
* means we can't tell exactly where it occurred and so we can't recover.
*
* Note that the debugger should test RI=0 and warn the user that system
* state has been corrupted.
*/
void
MachineCheckException(struct pt_regs *regs)
......@@ -266,12 +266,11 @@ MachineCheckException(struct pt_regs *regs)
}
#endif
if (debugger_fault_handler(regs))
return;
if (debugger(regs))
return;
die("Machine check", regs, 0);
die("Machine check in kernel mode", regs, 0);
/* Must die if the interrupt is not recoverable */
if (!(regs->msr & MSR_RI))
panic("Unrecoverable Machine check");
}
void
......@@ -397,9 +396,6 @@ ProgramCheckException(struct pt_regs *regs)
{
siginfo_t info;
if (debugger_fault_handler(regs))
return;
if (regs->msr & 0x100000) {
/* IEEE FP exception */
......@@ -438,16 +434,18 @@ ProgramCheckException(struct pt_regs *regs)
}
}
void
KernelFPUnavailableException(struct pt_regs *regs)
void KernelFPUnavailableException(struct pt_regs *regs)
{
die("Unrecoverable FP Unavailable Exception in Kernel", regs, 0);
printk(KERN_EMERG "Unrecoverable FP Unavailable Exception "
"%lx at %lx\n", regs->trap, regs->nip);
die("Unrecoverable FP Unavailable Exception", regs, SIGABRT);
}
void
KernelAltivecUnavailableException(struct pt_regs *regs)
void KernelAltivecUnavailableException(struct pt_regs *regs)
{
die("Unrecoverable VMX/Altivec Unavailable Exception in Kernel", regs, 0);
printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception "
"%lx at %lx\n", regs->trap, regs->nip);
die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
}
void
......@@ -539,7 +537,6 @@ void unrecoverable_exception(struct pt_regs *regs)
{
printk(KERN_EMERG "Unrecoverable exception %lx at %lx\n",
regs->trap, regs->nip);
debugger(regs);
die("Unrecoverable exception", regs, SIGABRT);
}
......@@ -551,7 +548,6 @@ void kernel_bad_stack(struct pt_regs *regs)
{
printk(KERN_EMERG "Bad kernel stack pointer %lx at %lx\n",
regs->gpr[1], regs->nip);
debugger(regs);
die("Bad kernel stack pointer", regs, SIGABRT);
}
......
......@@ -37,8 +37,6 @@
#include <asm/system.h>
#include <asm/uaccess.h>
void bad_page_fault(struct pt_regs *, unsigned long, int);
/*
* The error_code parameter is
* - DSISR for a non-SLB data access fault,
......@@ -177,10 +175,8 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
* It is called from do_page_fault above and from some of the procedures
* in traps.c.
*/
void
bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
{
extern void die(const char *, struct pt_regs *, long);
const struct exception_table_entry *entry;
/* Are we prepared to handle this fault? */
......@@ -190,7 +186,5 @@ bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
}
/* kernel has accessed a bad area */
if (debugger(regs))
return;
die("Kernel access of bad area", regs, sig);
}
......@@ -542,7 +542,6 @@ cmds(struct pt_regs *excp)
symbol_lookup();
break;
case 'r':
if (excp != NULL)
prregs(excp); /* print regs */
break;
case 'e':
......@@ -966,8 +965,7 @@ static void backtrace(struct pt_regs *excp)
spinlock_t exception_print_lock = SPIN_LOCK_UNLOCKED;
void
excprint(struct pt_regs *fp)
void excprint(struct pt_regs *fp)
{
unsigned long flags;
......@@ -1002,21 +1000,31 @@ excprint(struct pt_regs *fp)
spin_unlock_irqrestore(&exception_print_lock, flags);
}
void
prregs(struct pt_regs *fp)
void prregs(struct pt_regs *fp)
{
int n;
unsigned long base;
if (scanhex((void *)&base))
fp = (struct pt_regs *) base;
if (setjmp(bus_error_jmp) == 0) {
__debugger_fault_handler = handle_fault;
sync();
for (n = 0; n < 16; ++n)
printf("R%.2ld = %.16lx R%.2ld = %.16lx\n", n, fp->gpr[n],
n+16, fp->gpr[n+16]);
printf("pc = %.16lx msr = %.16lx\nlr = %.16lx cr = %.16lx\n",
fp->nip, fp->msr, fp->link, fp->ccr);
printf("R%.2ld = %.16lx R%.2ld = %.16lx\n", n,
fp->gpr[n], n+16, fp->gpr[n+16]);
printf("pc = %.16lx msr = %.16lx\nlr = %.16lx "
"cr = %.16lx\n", fp->nip, fp->msr, fp->link, fp->ccr);
printf("ctr = %.16lx xer = %.16lx trap = %8lx\n",
fp->ctr, fp->xer, fp->trap);
sync();
/* wait a little while to see if we get a machine check */
__delay(200);
} else {
printf("*** Error reading regs\n");
}
}
void
......
......@@ -94,7 +94,12 @@ static inline int debugger_dabr_match(struct pt_regs *regs) { return 0; }
static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
#endif
extern int fix_alignment(struct pt_regs *regs);
extern void bad_page_fault(struct pt_regs *regs, unsigned long address,
int sig);
extern void show_regs(struct pt_regs * regs);
extern int die(const char *str, struct pt_regs *regs, long err);
extern void flush_instruction_cache(void);
extern int _get_PVR(void);
extern void giveup_fpu(struct task_struct *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment