mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
bitkeeper revision 1.1108.53.1 (410f49091nUueqW95skYILdr1AOlpQ)
Fix NMI error code to correctly print a crash dump before hanging.
This commit is contained in:
1 parent
4e5f631ef1
commit
a6ef3afe23
7 files changed
+72
-16
No files matched your search
+4
-3
@@ -20,6 +20,7 @@
|
||||
#include <xen/delay.h>
|
||||
#include <xen/time.h>
|
||||
#include <xen/sched.h>
|
||||
#include <xen/console.h>
|
||||
#include <asm/mc146818rtc.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/msr.h>
|
||||
@@ -271,7 +272,6 @@ void touch_nmi_watchdog (void)
|
||||
|
||||
void nmi_watchdog_tick (struct pt_regs * regs)
|
||||
{
|
||||
extern spinlock_t console_lock;
|
||||
extern void die(const char * str, struct pt_regs * regs, long err);
|
||||
|
||||
int sum, cpu = smp_processor_id();
|
||||
@@ -285,8 +285,9 @@ void nmi_watchdog_tick (struct pt_regs * regs)
|
||||
* before doing the oops ...
|
||||
*/
|
||||
alert_counter[cpu]++;
|
||||
if (alert_counter[cpu] == 5*nmi_hz) {
|
||||
console_lock = SPIN_LOCK_UNLOCKED;
|
||||
if ( alert_counter[cpu] == 5*nmi_hz )
|
||||
{
|
||||
console_force_unlock();
|
||||
die("NMI Watchdog detected LOCKUP on CPU", regs, cpu);
|
||||
}
|
||||
}
|
||||
|
||||
+33
-9
@@ -33,6 +33,7 @@
|
||||
#include <xen/lib.h>
|
||||
#include <xen/errno.h>
|
||||
#include <xen/mm.h>
|
||||
#include <xen/console.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <xen/delay.h>
|
||||
#include <xen/spinlock.h>
|
||||
@@ -140,7 +141,7 @@ void show_registers(struct pt_regs *regs)
|
||||
unsigned long esp;
|
||||
unsigned short ss;
|
||||
|
||||
esp = (unsigned long) (®s->esp);
|
||||
esp = (unsigned long)(®s->esp);
|
||||
ss = __HYPERVISOR_DS;
|
||||
if ( regs->xcs & 3 )
|
||||
{
|
||||
@@ -271,7 +272,6 @@ DO_ERROR_NOCODE( 0, "divide error", divide_error)
|
||||
|
||||
asmlinkage void do_double_fault(void)
|
||||
{
|
||||
extern spinlock_t console_lock;
|
||||
struct tss_struct *tss = &doublefault_tss;
|
||||
unsigned int cpu = ((tss->back_link>>3)-__FIRST_TSS_ENTRY)>>1;
|
||||
|
||||
@@ -295,7 +295,7 @@ asmlinkage void do_double_fault(void)
|
||||
printk("************************************\n");
|
||||
|
||||
/* Lock up the console to prevent spurious output from other CPUs. */
|
||||
spin_lock(&console_lock);
|
||||
console_force_lock();
|
||||
|
||||
/* Wait for manual reset. */
|
||||
for ( ; ; ) ;
|
||||
@@ -472,9 +472,11 @@ asmlinkage void do_general_protection(struct pt_regs *regs, long error_code)
|
||||
die("general protection fault", regs, error_code);
|
||||
}
|
||||
|
||||
asmlinkage void mem_parity_error(unsigned char reason, struct pt_regs * regs)
|
||||
asmlinkage void mem_parity_error(unsigned char reason, struct pt_regs *regs)
|
||||
{
|
||||
printk("NMI received. Dazed and confused, but trying to continue\n");
|
||||
console_force_unlock();
|
||||
|
||||
printk("\n\nNMI received. Dazed and confused, but trying to continue\n");
|
||||
printk("You probably have a hardware problem with your RAM chips\n");
|
||||
|
||||
/* Clear and disable the memory parity error line. */
|
||||
@@ -482,18 +484,40 @@ asmlinkage void mem_parity_error(unsigned char reason, struct pt_regs * regs)
|
||||
outb(reason, 0x61);
|
||||
|
||||
show_registers(regs);
|
||||
panic("PARITY ERROR");
|
||||
|
||||
printk("************************************\n");
|
||||
printk("CPU%d MEMORY ERROR -- system shutdown\n", smp_processor_id());
|
||||
printk("System needs manual reset.\n");
|
||||
printk("************************************\n");
|
||||
|
||||
/* Lock up the console to prevent spurious output from other CPUs. */
|
||||
console_force_lock();
|
||||
|
||||
/* Wait for manual reset. */
|
||||
for ( ; ; ) ;
|
||||
}
|
||||
|
||||
asmlinkage void io_check_error(unsigned char reason, struct pt_regs * regs)
|
||||
asmlinkage void io_check_error(unsigned char reason, struct pt_regs *regs)
|
||||
{
|
||||
printk("NMI: IOCK error (debug interrupt?)\n");
|
||||
console_force_unlock();
|
||||
|
||||
printk("\n\nNMI: IOCK error (debug interrupt?)\n");
|
||||
|
||||
reason = (reason & 0xf) | 8;
|
||||
outb(reason, 0x61);
|
||||
|
||||
show_registers(regs);
|
||||
panic("IOCK ERROR");
|
||||
|
||||
printk("************************************\n");
|
||||
printk("CPU%d I/O ERROR -- system shutdown\n", smp_processor_id());
|
||||
printk("System needs manual reset.\n");
|
||||
printk("************************************\n");
|
||||
|
||||
/* Lock up the console to prevent spurious output from other CPUs. */
|
||||
console_force_lock();
|
||||
|
||||
/* Wait for manual reset. */
|
||||
for ( ; ; ) ;
|
||||
}
|
||||
|
||||
static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
|
||||
|
||||
@@ -602,7 +602,7 @@ ENTRY(nmi)
|
||||
# reload DS and ES when handling them.
|
||||
inb $0x61,%al
|
||||
testb $0x80,%al
|
||||
jne nmi_parity_err
|
||||
je nmi_parity_err
|
||||
testb $0x40,%al
|
||||
jne nmi_io_err
|
||||
movl %eax,%ebx
|
||||
@@ -660,14 +660,22 @@ nmi_parity_err:
|
||||
movl $(__HYPERVISOR_DS),%edx
|
||||
movl %edx,%ds
|
||||
movl %edx,%es
|
||||
jmp SYMBOL_NAME(mem_parity_error)
|
||||
movl %esp,%edx
|
||||
push %edx
|
||||
push %eax
|
||||
call SYMBOL_NAME(mem_parity_error)
|
||||
ud2
|
||||
|
||||
nmi_io_err:
|
||||
movl $(__HYPERVISOR_DS),%edx
|
||||
movl %edx,%ds
|
||||
movl %edx,%es
|
||||
jmp SYMBOL_NAME(io_check_error)
|
||||
|
||||
movl %esp,%edx
|
||||
push %edx
|
||||
push %eax
|
||||
call SYMBOL_NAME(io_check_error)
|
||||
ud2
|
||||
|
||||
.data
|
||||
ENTRY(hypercall_table)
|
||||
.long SYMBOL_NAME(do_set_trap_table) /* 0 */
|
||||
|
||||
@@ -433,6 +433,17 @@ void console_endboot(int disable_vga)
|
||||
switch_serial_input();
|
||||
}
|
||||
|
||||
void console_force_unlock(void)
|
||||
{
|
||||
console_lock = SPIN_LOCK_UNLOCKED;
|
||||
serial_force_unlock(sercon_handle);
|
||||
}
|
||||
|
||||
void console_force_lock(void)
|
||||
{
|
||||
spin_lock(&console_lock);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* **************************************************************
|
||||
|
||||
@@ -459,3 +459,10 @@ unsigned char serial_getc(int handle)
|
||||
spin_unlock_irqrestore(&uart->lock, flags);
|
||||
return c;
|
||||
}
|
||||
|
||||
void serial_force_unlock(int handle)
|
||||
{
|
||||
uart_t *uart = &com[handle & SERHND_IDX];
|
||||
if ( handle != -1 )
|
||||
uart->lock = SPIN_LOCK_UNLOCKED;
|
||||
}
|
||||
@@ -19,4 +19,7 @@ long read_console_ring(unsigned long, unsigned int, unsigned int);
|
||||
void init_console(void);
|
||||
void console_endboot(int disable_vga);
|
||||
|
||||
void console_force_unlock(void);
|
||||
void console_force_lock(void);
|
||||
|
||||
#endif
|
||||
@@ -43,4 +43,6 @@ void serial_puts(int handle, const unsigned char *s);
|
||||
*/
|
||||
unsigned char serial_getc(int handle);
|
||||
|
||||
void serial_force_unlock(int handle);
|
||||
|
||||
#endif /* __XEN_SERIAL_H__ */
|
||||