1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
--- linux-2.6.0-test3orig/drivers/char/ipmi/ipmi_msghandler.c 2003-08-09 00:37:25.000000000 -0400
+++ linux-2.6.0-test3/drivers/char/ipmi/ipmi_msghandler.c 2003-08-14 09:40:49.000000000 -0400
@@ -1813,7 +1813,9 @@
{
}
-static void send_panic_events(void)
+#define EVENT_VALID 0x80
+
+static void send_panic_events(int evt, char *str)
{
struct ipmi_msg msg;
ipmi_smi_t intf;
@@ -1837,12 +1839,17 @@
data[4] = 0x6f; /* Sensor specific, IPMI table 36-1 */
data[5] = 0xa1; /* Runtime stop OEM bytes 2 & 3. */
- /* These used to have the first three bytes of the panic string,
- but not only is that not terribly useful, it's not available
- any more. */
- data[3] = 0;
- data[6] = 0;
- data[7] = 0;
+ /*
+ * Add whatever breadcrumbs we can to indicate the type of panic.
+ * In kernel 2.6.0 an event code and panic string are passed in.
+ */
+ if (evt != 0)
+ data[7] = EVENT_VALID | (evt & 0x7f);
+ if (str != NULL) {
+ data[3] = str[0];
+ data[6] = str[1];
+ if (evt == 0) data[7] = str[2];
+ }
smi_msg.done = dummy_smi_done_handler;
recv_msg.done = dummy_recv_done_handler;
@@ -1891,7 +1898,7 @@
}
#ifdef CONFIG_IPMI_PANIC_EVENT
- send_panic_events();
+ send_panic_events(event,(char *)ptr);
#endif
return NOTIFY_DONE;
--- linux-2.6.0-test3orig/arch/i386/kernel/traps.c 2003-08-09 00:33:15.000000000 -0400
+++ linux-2.6.0-test3/arch/i386/kernel/traps.c 2003-08-13 17:37:50.789828552 -0400
@@ -288,6 +288,8 @@
return address;
}
+extern int last_trapnr;
+
static inline void do_trap(int trapnr, int signr, char *str, int vm86,
struct pt_regs * regs, long error_code, siginfo_t *info)
{
@@ -312,8 +314,10 @@
}
kernel_trap: {
- if (!fixup_exception(regs))
+ if (!fixup_exception(regs)) {
+ last_trapnr = trapnr;
die(str, regs, error_code);
+ }
return;
}
@@ -387,8 +391,10 @@
return;
gp_in_kernel:
- if (!fixup_exception(regs))
+ if (!fixup_exception(regs)) {
+ last_trapnr = 13;
die("general protection fault", regs, error_code);
+ }
}
static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
@@ -721,6 +727,7 @@
error_code);
return;
}
+ last_trapnr = 19;
die_if_kernel("cache flush denied", regs, error_code);
current->thread.trap_no = 19;
current->thread.error_code = error_code;
--- linux-2.6.0-test3orig/kernel/ksyms.c 2003-08-09 00:31:15.000000000 -0400
+++ linux-2.6.0-test3/kernel/ksyms.c 2003-08-13 17:39:00.000000000 -0400
@@ -71,6 +71,7 @@
extern struct timezone sys_tz;
extern int panic_timeout;
+extern int last_trapnr;
/* process memory management */
EXPORT_SYMBOL(do_mmap_pgoff);
@@ -504,6 +505,7 @@
EXPORT_SYMBOL(panic);
EXPORT_SYMBOL(panic_notifier_list);
EXPORT_SYMBOL(panic_timeout);
+EXPORT_SYMBOL(last_trapnr);
EXPORT_SYMBOL(sprintf);
EXPORT_SYMBOL(snprintf);
EXPORT_SYMBOL(sscanf);
--- linux-2.6.0-test3orig/kernel/panic.c 2003-08-09 00:41:41.000000000 -0400
+++ linux-2.6.0-test3/kernel/panic.c 2003-08-13 17:38:49.000000000 -0400
@@ -20,9 +20,15 @@
asmlinkage void sys_sync(void); /* it's really int */
+/* values for panic event */
+#define EVENT_VALID 0x80
+#define PANIC_IN_INTERRUPT 0x40
+#define TRAP_INIT 0x80
+
int panic_timeout;
int panic_on_oops;
int tainted;
+int last_trapnr = TRAP_INIT;
struct notifier_block *panic_notifier_list;
@@ -47,6 +53,7 @@
{
static char buf[1024];
va_list args;
+ int event = 0;
#if defined(CONFIG_ARCH_S390)
unsigned long caller = (unsigned long) __builtin_return_address(0);
#endif
@@ -56,11 +63,16 @@
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
printk(KERN_EMERG "Kernel panic: %s\n",buf);
- if (in_interrupt())
+ if (last_trapnr != TRAP_INIT) {
+ /* should be <= 30 trapnr values, so packing in 0x3f is ok */
+ event = EVENT_VALID + (last_trapnr & 0x3f);
+ }
+ if (in_interrupt()) {
+ event |= PANIC_IN_INTERRUPT; /*0x40*/
printk(KERN_EMERG "In interrupt handler - not syncing\n");
- else if (!current->pid)
+ } else if (!current->pid)
printk(KERN_EMERG "In idle task - not syncing\n");
- else
+ else
sys_sync();
bust_spinlocks(0);
@@ -68,7 +80,7 @@
smp_send_stop();
#endif
- notifier_call_chain(&panic_notifier_list, 0, buf);
+ notifier_call_chain(&panic_notifier_list, event, buf);
if (panic_timeout > 0)
{
|