arch/i386/kernel/crash.c | 24 +++++++++++++++++------- arch/i386/kernel/nmi.c | 2 +- include/asm-i386/apic.h | 1 + include/linux/crash.h | 2 +- kernel/bootimg.c | 13 ++++++++++++- kernel/bootimg_pic.c | 6 ++++-- 6 files changed, 36 insertions(+), 12 deletions(-) Index: linux-2.4.20-rh/kernel/bootimg.c =================================================================== --- linux-2.4.20-rh.orig/kernel/bootimg.c 2003-10-29 23:56:02.000000000 +0800 +++ linux-2.4.20-rh/kernel/bootimg.c 2003-10-29 23:56:17.000000000 +0800 @@ -238,9 +238,20 @@ int error = -ENOMEM; if (bootimg_checksum(__va(bootimg_dsc.page_dir),bootimg_dsc.pages) - != bootimg_dsc.csum) + != bootimg_dsc.csum) { printk("Checksum of kernel image failed. Rebooting via BIOS\n"); + /* Before calling machine_restart(), make sure it will not + * simply call this function recursively. + */ + bootimg_dsc.page_dir = NULL; + machine_restart(NULL); + + /* We should never get here, but just in case... */ + for (; ; ) + __asm__ __volatile__ ("hlt"); + } + code_page = get_identity_mapped_page(); if (!code_page) goto out3; code = (relocate_and_jump_t) virt_to_phys((void *) code_page); Index: linux-2.4.20-rh/kernel/bootimg_pic.c =================================================================== --- linux-2.4.20-rh.orig/kernel/bootimg_pic.c 2003-10-29 23:56:02.000000000 +0800 +++ linux-2.4.20-rh/kernel/bootimg_pic.c 2003-10-29 23:56:17.000000000 +0800 @@ -69,7 +69,8 @@ for (j = i+1; j < dsc.pages; j++) { table = dsc.page_dir+FROM_TABLE(j); if (((unsigned long) *table) == to) { - copy_and_swap(*table,dsc.scratch); + copy_and_swap((unsigned long) (*table), + dsc.scratch); break; } if ((*table)[PAGE_NR(j)] == to) { @@ -79,7 +80,8 @@ } table = dsc.page_dir+TO_TABLE(j); if (((unsigned long) *table) == to) { - copy_and_swap(*table,dsc.scratch); + copy_and_swap((unsigned long) (*table), + dsc.scratch); break; } } Index: linux-2.4.20-rh/include/asm-i386/apic.h =================================================================== --- linux-2.4.20-rh.orig/include/asm-i386/apic.h 2003-10-29 23:58:49.000000000 +0800 +++ linux-2.4.20-rh/include/asm-i386/apic.h 2003-10-29 23:59:40.000000000 +0800 @@ -86,6 +86,9 @@ extern void apic_pm_unregister(struct pm_dev*); extern int check_nmi_watchdog (void); +extern void disable_apic_nmi_watchdog(void); + + extern unsigned int nmi_watchdog; #define NMI_NONE 0 Index: linux-2.4.20-rh/include/linux/crash.h =================================================================== --- linux-2.4.20-rh.orig/include/linux/crash.h 2003-10-29 23:56:02.000000000 +0800 +++ linux-2.4.20-rh/include/linux/crash.h 2003-10-29 23:56:17.000000000 +0800 @@ -71,7 +71,7 @@ #define CRASH_ZALLOC_PAGES 16*5*2 /* 2 to handle crash in crash */ #define CRASH_LOW_WATER_PAGES 100 -#define CRASH_CPU_TIMEOUT 5000 /* 5 sec wait for other cpus to stop */ +#define CRASH_CPU_TIMEOUT 15000 /* 15 sec wait for other cpus to stop */ #define CRASH_MARK_RESERVED(addr) (set_bit(PG_reserved,&mem_map[MAP_NR(addr)].flags)) #define CRASH_CLEAR_RESERVED(addr) (clear_bit(PG_reserved,&mem_map[MAP_NR(addr)].flags)) Index: linux-2.4.20-rh/arch/i386/kernel/crash.c =================================================================== --- linux-2.4.20-rh.orig/arch/i386/kernel/crash.c 2003-10-29 23:56:02.000000000 +0800 +++ linux-2.4.20-rh/arch/i386/kernel/crash.c 2003-10-29 23:56:17.000000000 +0800 @@ -9,6 +9,8 @@ #include #include #include +#include +#include inline void crash_save_regs(void) { static unsigned long regs[8]; @@ -30,15 +32,23 @@ */ void crash_save_current_state(struct task_struct *tp) { + if (tp != NULL) { + /* + * Here we save ebp instead of esp just in case the compiler + * decides to put an extra push in before we execute this + * instruction (thus invalidating our frame pointer). + */ + asm volatile("movl %%ebp,%0":"=m" (*(u_long *)&tp->thread.esp)); + tp->thread.eip = (u_long)crash_save_current_state; + panic_ksp[smp_processor_id()] = tp->thread.esp; + mb(); + } + /* - * Here we save ebp instead of esp just in case the compiler - * decides to put an extra push in before we execute this - * instruction (thus invalidating our frame pointer). + * Just to be safe, disable the NMI watchdog on the calling CPU so it + * doesn't get in the way while we are trying to save a dump. */ - asm volatile("movl %%ebp,%0":"=m" (*(u_long *)&tp->thread.esp)); - tp->thread.eip = (u_long)crash_save_current_state; - panic_ksp[smp_processor_id()] = tp->thread.esp; - mb(); + disable_apic_nmi_watchdog(); save_core(); Index: linux-2.4.20-rh/arch/i386/kernel/nmi.c =================================================================== --- linux-2.4.20-rh.orig/arch/i386/kernel/nmi.c 2003-10-29 23:56:02.000000000 +0800 +++ linux-2.4.20-rh/arch/i386/kernel/nmi.c 2003-10-29 23:56:17.000000000 +0800 @@ -138,7 +138,7 @@ struct pm_dev *nmi_pmdev; -static void disable_apic_nmi_watchdog(void) +void disable_apic_nmi_watchdog(void) { switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_AMD: