#include <asm/proto.h>
#include <asm/nmi.h>
+extern struct gate_struct idt_table[256];
+
asmlinkage void divide_error(void);
asmlinkage void debug(void);
asmlinkage void nmi(void);
asmlinkage void machine_check(void);
asmlinkage void spurious_interrupt_bug(void);
-ATOMIC_NOTIFIER_HEAD(die_chain);
-
-extern char last_sysfs_file[];
+struct notifier_block *die_chain;
+static DEFINE_SPINLOCK(die_notifier_lock);
int register_die_notifier(struct notifier_block *nb)
{
- vmalloc_sync_all();
- return atomic_notifier_chain_register(&die_chain, nb);
-}
-EXPORT_SYMBOL(register_die_notifier);
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&die_chain, nb);
+ int err = 0;
+ unsigned long flags;
+ spin_lock_irqsave(&die_notifier_lock, flags);
+ err = notifier_chain_register(&die_chain, nb);
+ spin_unlock_irqrestore(&die_notifier_lock, flags);
+ return err;
}
-EXPORT_SYMBOL(unregister_die_notifier);
static inline void conditional_sti(struct pt_regs *regs)
{
{
if (regs->eflags & X86_EFLAGS_IF)
local_irq_disable();
- /* Make sure to not schedule here because we could be running
- on an exception stack. */
preempt_enable_no_resched();
}
if (!modname)
modname = delim = "";
return printk("<%016lx>{%s%s%s%s%+ld}",
- address, delim, modname, delim, symname, offset);
+ address,delim,modname,delim,symname,offset);
}
#else
int printk_address(unsigned long address)
show_stack(NULL, (unsigned long*)rsp);
printk("\nCode: ");
- if (regs->rip < PAGE_OFFSET)
+ if(regs->rip < PAGE_OFFSET)
goto bad;
- for (i=0; i<20; i++) {
+ for(i=0;i<20;i++)
+ {
unsigned char c;
- if (__get_user(c, &((unsigned char*)regs->rip)[i])) {
+ if(__get_user(c, &((unsigned char*)regs->rip)[i])) {
bad:
printk(" Bad RIP value.");
break;
static DEFINE_SPINLOCK(die_lock);
static int die_owner = -1;
-static unsigned int die_nest_count;
unsigned __kprobes long oops_begin(void)
{
else
spin_lock(&die_lock);
}
- die_nest_count++;
die_owner = cpu;
console_verbose();
bust_spinlocks(1);
{
die_owner = -1;
bust_spinlocks(0);
- die_nest_count--;
- if (die_nest_count)
- /* We still own the lock */
- local_irq_restore(flags);
- else
- /* Nest count reaches zero, release the lock. */
- spin_unlock_irqrestore(&die_lock, flags);
+ spin_unlock_irqrestore(&die_lock, flags);
if (panic_on_oops)
panic("Oops");
}
printk("DEBUG_PAGEALLOC");
#endif
printk("\n");
-#ifdef CONFIG_SYSFS
- printk(KERN_ALERT "last sysfs file: %s\n", last_sysfs_file);
-#endif
notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV);
show_registers(regs);
/* Executive summary in case the oops scrolled away */
panic("nmi watchdog");
printk("console shuts up ...\n");
oops_end(flags);
- nmi_exit();
- local_irq_enable();
do_exit(SIGSEGV);
}
{
struct task_struct *tsk = current;
+ conditional_sti(regs);
+
tsk->thread.error_code = error_code;
tsk->thread.trap_no = trapnr;
printk(KERN_INFO
"%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n",
tsk->comm, tsk->pid, str,
- regs->rip, regs->rsp, error_code);
+ regs->rip,regs->rsp,error_code);
if (info)
force_sig_info(signr, info, tsk);
{
const struct exception_table_entry *fixup;
fixup = search_exception_tables(regs->rip);
- if (fixup)
+ if (fixup) {
regs->rip = fixup->fixup;
- else
+ } else
die(str, regs, error_code);
return;
}
if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
== NOTIFY_STOP) \
return; \
- conditional_sti(regs); \
do_trap(trapnr, signr, str, regs, error_code, NULL); \
}
if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
== NOTIFY_STOP) \
return; \
- conditional_sti(regs); \
do_trap(trapnr, signr, str, regs, error_code, &info); \
}
DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
DO_ERROR(18, SIGSEGV, "reserved", reserved)
-
-/* Runs on IST stack */
-asmlinkage void do_stack_segment(struct pt_regs *regs, long error_code)
-{
- if (notify_die(DIE_TRAP, "stack segment", regs, error_code,
- 12, SIGBUS) == NOTIFY_STOP)
- return;
- preempt_conditional_sti(regs);
- do_trap(12, SIGBUS, "stack segment", regs, error_code, NULL);
- preempt_conditional_cli(regs);
-}
+DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
asmlinkage void do_double_fault(struct pt_regs * regs, long error_code)
{
printk(KERN_INFO
"%s[%d] general protection rip:%lx rsp:%lx error:%lx\n",
tsk->comm, tsk->pid,
- regs->rip, regs->rsp, error_code);
+ regs->rip,regs->rsp,error_code);
force_sig(SIGSEGV, tsk);
return;
if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) {
return;
}
- preempt_conditional_sti(regs);
do_trap(3, SIGTRAP, "int3", regs, error_code, NULL);
- preempt_conditional_cli(regs);
+ return;
}
/* Help handler running on IST stack to switch back to user stack
static int __init oops_dummy(char *s)
{
panic_on_oops = 1;
- return 1;
+ return -1;
}
__setup("oops=", oops_dummy);
static int __init kstack_setup(char *s)
{
kstack_depth_to_print = simple_strtoul(s,NULL,0);
- return 1;
+ return 0;
}
__setup("kstack=", kstack_setup);