Index: 2.6.x-xfs/arch/i386/Kconfig
===================================================================
--- 2.6.x-xfs.orig/arch/i386/Kconfig Tue May 11 14:54:13 2004
+++ 2.6.x-xfs/arch/i386/Kconfig Tue May 11 16:10:50 2004
@@ -1284,6 +1284,85 @@
on the VM subsystem for higher order allocations. This option
will also use IRQ stacks to compensate for the reduced stackspace.
+config KDB
+ bool "Built-in Kernel Debugger support"
+ depends on DEBUG_KERNEL
+ help
+ This option provides a built-in kernel debugger. The built-in
+ kernel debugger contains commands which allow memory to be examined,
+ instructions to be disassembled and breakpoints to be set. For details,
+ see Documentation/kdb/kdb.mm and the manual pages kdb_bt, kdb_ss, etc.
+ Kdb can also be used via the serial port. Set up the system to
+ have a serial console (see Documentation/serial-console.txt).
+ The Control-A key sequence on the serial port will cause the
+ kernel debugger to be entered with input from the serial port and
+ output to the serial console. If unsure, say N.
+
+config KDB_MODULES
+ tristate "KDB modules"
+ depends on KDB
+ help
+ KDB can be extended by adding your own modules, in directory
+ kdb/modules. This option selects the way that these modules should
+ be compiled, as free standing modules (select M) or built into the
+ kernel (select Y). If unsure say M.
+
+config KDB_OFF
+ bool "KDB off by default"
+ depends on KDB
+ help
+ Normally kdb is activated by default, as long as CONFIG_KDB is set.
+ If you want to ship a kernel with kdb support but only have kdb
+ turned on when the user requests it then select this option. When
+ compiled with CONFIG_KDB_OFF, kdb ignores all events unless you boot
+ with kdb=on or you echo "1" > /proc/sys/kernel/kdb. This option also
+ works in reverse, if kdb is normally activated, you can boot with
+ kdb=off or echo "0" > /proc/sys/kernel/kdb to deactivate kdb. If
+ unsure, say N.
+
+config KDB_CONTINUE_CATASTROPHIC
+ int "KDB continues after catastrophic errors"
+ depends on KDB
+ default "0"
+ help
+ This integer controls the behaviour of kdb when the kernel gets a
+ catastrophic error, i.e. for a panic, oops, NMI or other watchdog
+ tripping. CONFIG_KDB_CONTINUE_CATASTROPHIC interacts with
+ /proc/sys/kernel/kdb and CONFIG_DUMP (if your kernel has the LKCD
+ patch).
+ When KDB is active (/proc/sys/kernel/kdb == 1) and a catastrophic
+ error occurs, nothing extra happens until you type 'go'.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 0 (default). The first time
+ you type 'go', kdb warns you. The second time you type 'go', KDB
+ tries to continue - no guarantees that the kernel is still usable.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 1. KDB tries to continue - no
+ guarantees that the kernel is still usable.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 2. If your kernel has the LKCD
+ patch and LKCD is configured to take a dump then KDB forces a dump.
+ Whether or not a dump is taken, KDB forces a reboot.
+ When KDB is not active (/proc/sys/kernel/kdb == 0) and a catastrophic
+ error occurs, the following steps are automatic, no human
+ intervention is required.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 0 (default) or 1. KDB attempts
+ to continue - no guarantees that the kernel is still usable.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 2. If your kernel has the LKCD
+ patch and LKCD is configured to take a dump then KDB automatically
+ forces a dump. Whether or not a dump is taken, KDB forces a
+ reboot.
+ If you are not sure, say 0. Read Documentation/kdb/dump.txt before
+ setting to 2.
+
+# KDB_USB does not work, the usb code needs to be
+# converted from 2.4.19 to 2.5.40 APIs. Omit it until somebody
+# fixes CONFIG_KDB_USB.
+#config KDB_USB
+# bool "Support for USB Keyboard in KDB"
+# depends on KDB && USB
+# help
+# If you want to use kdb from a USB keyboard then say Y here. If you
+# say N then kdb can only be used from a PC (AT) keyboard or a serial
+# console.
+
config X86_FIND_SMP_CONFIG
bool
depends on X86_LOCAL_APIC || X86_VOYAGER
Index: 2.6.x-xfs/arch/i386/Makefile
===================================================================
--- 2.6.x-xfs.orig/arch/i386/Makefile Tue May 11 14:54:13 2004
+++ 2.6.x-xfs/arch/i386/Makefile Tue May 11 16:10:50 2004
@@ -47,6 +47,7 @@
cflags-$(CONFIG_MWINCHIP3D) += $(call check_gcc,-march=winchip2,-march=i586)
cflags-$(CONFIG_MCYRIXIII) += $(call check_gcc,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
cflags-$(CONFIG_MVIAC3_2) += $(call check_gcc,-march=c3-2,-march=i686)
+cflags-$(CONFIG_KDB) += $(call check_gcc,-fno-optimize-sibling-calls,)
# AMD Elan support
cflags-$(CONFIG_X86_ELAN) += -march=i486
@@ -108,6 +109,7 @@
# must be linked after kernel/
drivers-$(CONFIG_OPROFILE) += arch/i386/oprofile/
drivers-$(CONFIG_PM) += arch/i386/power/
+drivers-$(CONFIG_KDB) += arch/i386/kdb/
CFLAGS += $(mflags-y)
AFLAGS += $(mflags-y)
Index: 2.6.x-xfs/arch/i386/kernel/entry.S
===================================================================
--- 2.6.x-xfs.orig/arch/i386/kernel/entry.S Tue May 11 14:54:13 2004
+++ 2.6.x-xfs/arch/i386/kernel/entry.S Tue May 11 16:10:50 2004
@@ -187,6 +187,18 @@
popl %eax
jmp syscall_exit
+#if defined(CONFIG_KDB)
+ENTRY(kdb_call)
+ pushl %eax # save orig EAX
+ SAVE_ALL
+ pushl %esp # struct pt_regs
+ pushl $0 # error_code
+ pushl $7 # KDB_REASON_ENTRY
+ call kdb
+ addl $12,%esp # remove args
+ RESTORE_ALL
+#endif
+
/*
* Return to user mode is not as complex as all this looks,
* but we want the default path for a system call return to
@@ -590,6 +602,22 @@
pushl $do_alignment_check
jmp error_code
+#if defined(CONFIG_KDB)
+ENTRY(page_fault_mca)
+ pushl %ecx
+ pushl %edx
+ pushl %eax
+ movl $473,%ecx
+ rdmsr
+ andl $0xfffffffe,%eax /* Disable last branch recording */
+ wrmsr
+ popl %eax
+ popl %edx
+ popl %ecx
+ pushl $do_page_fault
+ jmp error_code
+#endif
+
ENTRY(page_fault)
pushl $do_page_fault
jmp error_code
Index: 2.6.x-xfs/arch/i386/kernel/i8259.c
===================================================================
--- 2.6.x-xfs.orig/arch/i386/kernel/i8259.c Tue May 11 14:54:13 2004
+++ 2.6.x-xfs/arch/i386/kernel/i8259.c Tue May 11 16:10:50 2004
@@ -423,6 +423,10 @@
int vector = FIRST_EXTERNAL_VECTOR + i;
if (i >= NR_IRQS)
break;
+#ifdef CONFIG_KDB
+ if (vector == KDBENTER_VECTOR)
+ continue;
+#endif
if (vector != SYSCALL_VECTOR)
set_intr_gate(vector, interrupt[i]);
}
Index: 2.6.x-xfs/arch/i386/kernel/io_apic.c
===================================================================
--- 2.6.x-xfs.orig/arch/i386/kernel/io_apic.c Tue May 11 14:54:13 2004
+++ 2.6.x-xfs/arch/i386/kernel/io_apic.c Tue May 11 16:10:50 2004
@@ -27,6 +27,9 @@
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/config.h>
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#endif /* CONFIG_KDB */
#include <linux/smp_lock.h>
#include <linux/mc146818rtc.h>
#include <linux/compiler.h>
@@ -1164,6 +1167,10 @@
current_vector += 8;
if (current_vector == SYSCALL_VECTOR)
goto next;
+#ifdef CONFIG_KDB
+ if (current_vector == KDBENTER_VECTOR)
+ goto next;
+#endif /* CONFIG_KDB */
if (current_vector >= FIRST_SYSTEM_VECTOR) {
offset++;
Index: 2.6.x-xfs/arch/i386/kernel/nmi.c
===================================================================
--- 2.6.x-xfs.orig/arch/i386/kernel/nmi.c Tue May 11 14:54:13 2004
+++ 2.6.x-xfs/arch/i386/kernel/nmi.c Tue May 11 16:10:50 2004
@@ -25,6 +25,9 @@
#include <linux/module.h>
#include <linux/nmi.h>
#include <linux/sysdev.h>
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#endif /* CONFIG_KDB */
#include <asm/smp.h>
#include <asm/mtrr.h>
@@ -480,6 +483,9 @@
printk("NMI Watchdog detected LOCKUP on CPU%d, eip %08lx, registers:\n", cpu, regs->eip);
show_registers(regs);
printk("console shuts up ...\n");
+#ifdef CONFIG_KDB
+ kdb(KDB_REASON_NMI, 0, regs);
+#endif /* CONFIG_KDB */
console_silent();
spin_unlock(&nmi_print_lock);
bust_spinlocks(0);
Index: 2.6.x-xfs/arch/i386/kernel/reboot.c
===================================================================
--- 2.6.x-xfs.orig/arch/i386/kernel/reboot.c Tue May 11 14:47:19 2004
+++ 2.6.x-xfs/arch/i386/kernel/reboot.c Tue May 11 16:10:50 2004
@@ -3,6 +3,10 @@
*/
#include <linux/mm.h>
+#include <linux/config.h>
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#endif /* CONFIG_KDB */
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/init.h>
@@ -252,6 +256,14 @@
* Stop all CPUs and turn off local APICs and the IO-APIC, so
* other OSs see a clean IRQ state.
*/
+#ifdef CONFIG_KDB
+ /*
+ * If this restart is occuring while kdb is running (e.g. reboot
+ * command), the other CPU's are already stopped. Don't try to
+ * stop them yet again.
+ */
+ if (!KDB_IS_RUNNING())
+#endif /* CONFIG_KDB */
smp_send_stop();
#elif defined(CONFIG_X86_LOCAL_APIC)
if (cpu_has_apic) {
Index: 2.6.x-xfs/arch/i386/kernel/smp.c
===================================================================
--- 2.6.x-xfs.orig/arch/i386/kernel/smp.c Tue May 11 14:47:19 2004
+++ 2.6.x-xfs/arch/i386/kernel/smp.c Tue May 11 16:10:50 2004
@@ -26,6 +26,11 @@
#include <mach_ipi.h>
#include <mach_apic.h>
+#include <linux/config.h>
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#endif /* CONFIG_KDB */
+
/*
* Some notes on x86 processor bugs affecting SMP operation:
*
@@ -144,6 +149,15 @@
*/
cfg = __prepare_ICR(shortcut, vector);
+#ifdef CONFIG_KDB
+ if (vector == KDB_VECTOR) {
+ /*
+ * Setup KDB IPI to be delivered as an NMI
+ */
+ cfg = (cfg&~APIC_VECTOR_MASK)|APIC_DM_NMI;
+ }
+#endif /* CONFIG_KDB */
+
/*
* Send the IPI. The write to APIC_ICR fires this off.
*/
@@ -221,6 +235,15 @@
* program the ICR
*/
cfg = __prepare_ICR(0, vector);
+
+#ifdef CONFIG_KDB
+ if (vector == KDB_VECTOR) {
+ /*
+ * Setup KDB IPI to be delivered as an NMI
+ */
+ cfg = (cfg&~APIC_VECTOR_MASK)|APIC_DM_NMI;
+ }
+#endif /* CONFIG_KDB */
/*
* Send the IPI. The write to APIC_ICR fires this off.
@@ -467,6 +490,15 @@
on_each_cpu(do_flush_tlb_all, 0, 1, 1);
}
+#ifdef CONFIG_KDB
+void
+smp_kdb_stop(void)
+{
+ if (!KDB_FLAG(NOIPI))
+ send_IPI_allbutself(KDB_VECTOR);
+}
+#endif /* CONFIG_KDB */
+
/*
* this function sends a 'reschedule' IPI to another CPU.
* it goes straight through and wastes no time serializing
Index: 2.6.x-xfs/arch/i386/kernel/smpboot.c
===================================================================
--- 2.6.x-xfs.orig/arch/i386/kernel/smpboot.c Tue May 11 14:54:13 2004
+++ 2.6.x-xfs/arch/i386/kernel/smpboot.c Tue May 11 16:10:50 2004
@@ -43,6 +43,9 @@
#include <linux/smp_lock.h>
#include <linux/irq.h>
#include <linux/bootmem.h>
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#endif /* CONFIG_KDB */
#include <linux/delay.h>
#include <linux/mc146818rtc.h>
@@ -420,6 +423,11 @@
*/
cpu_set(cpuid, cpu_callin_map);
+#ifdef CONFIG_KDB
+ /* Activate any preset global breakpoints on this cpu */
+ kdb(KDB_REASON_SILENT, 0, 0);
+#endif /* CONFIG_KDB */
+
/*
* Synchronize the TSC with the BP
*/
Index: 2.6.x-xfs/arch/i386/kernel/traps.c
===================================================================
--- 2.6.x-xfs.orig/arch/i386/kernel/traps.c Tue May 11 14:54:13 2004
+++ 2.6.x-xfs/arch/i386/kernel/traps.c Tue May 11 16:10:50 2004
@@ -36,6 +36,10 @@
#include <linux/mca.h>
#endif
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#endif /* CONFIG_KDB */
+
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -56,6 +60,9 @@
#include "mach_traps.h"
asmlinkage int system_call(void);
+#ifdef CONFIG_KDB
+asmlinkage int kdb_call(void);
+#endif /* CONFIG_KDB */
asmlinkage void lcall7(void);
asmlinkage void lcall27(void);
@@ -86,6 +93,9 @@
asmlinkage void stack_segment(void);
asmlinkage void general_protection(void);
asmlinkage void page_fault(void);
+#ifdef CONFIG_KDB
+asmlinkage void page_fault_mca(void);
+#endif /* CONFIG_KDB */
asmlinkage void coprocessor_error(void);
asmlinkage void simd_coprocessor_error(void);
asmlinkage void alignment_check(void);
@@ -279,6 +289,10 @@
show_registers(regs);
bust_spinlocks(0);
spin_unlock_irq(&die_lock);
+#ifdef CONFIG_KDB
+ kdb_diemsg = str;
+ kdb(KDB_REASON_OOPS, err, regs);
+#endif /* CONFIG_KDB */
if (in_interrupt())
panic("Fatal exception in interrupt");
@@ -377,7 +391,9 @@
}
DO_VM86_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->eip)
+#ifndef CONFIG_KDB
DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
+#endif /* !CONFIG_KDB */
DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds)
DO_ERROR_INFO( 6, SIGILL, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
@@ -448,16 +464,37 @@
return;
}
#endif
+#ifdef CONFIG_KDB
+ (void)kdb(KDB_REASON_NMI, reason, regs);
+#endif /* CONFIG_KDB */
printk("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n",
reason, smp_processor_id());
printk("Dazed and confused, but trying to continue\n");
printk("Do you have a strange power saving mode enabled?\n");
}
+#if defined(CONFIG_SMP) && defined(CONFIG_KDB)
+static void
+do_ack_apic_irq(void)
+{
+ ack_APIC_irq();
+}
+#endif /* defined(CONFIG_SMP) && defined(CONFIG_KDB) */
+
static void default_do_nmi(struct pt_regs * regs)
{
unsigned char reason = get_nmi_reason();
+#if defined(CONFIG_SMP) && defined(CONFIG_KDB)
+ /*
+ * Call the kernel debugger to see if this NMI is due
+ * to an KDB requested IPI. If so, kdb will handle it.
+ */
+ if (kdb_ipi(regs, do_ack_apic_irq)) {
+ return;
+ }
+#endif /* defined(CONFIG_SMP) && defined(CONFIG_KDB) */
+
if (!(reason & 0xc0)) {
#ifdef CONFIG_X86_LOCAL_APIC
/*
@@ -545,6 +582,11 @@
__asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
+#ifdef CONFIG_KDB
+ if (kdb(KDB_REASON_DEBUG, error_code, regs))
+ return;
+#endif /* CONFIG_KDB */
+
/* It's safe to allow irq's after DR6 has been saved */
if (regs->eflags & X86_EFLAGS_IF)
local_irq_enable();
@@ -612,6 +654,16 @@
return;
}
+#ifdef CONFIG_KDB
+asmlinkage void do_int3(struct pt_regs * regs, long error_code)
+{
+ if (kdb(KDB_REASON_BREAK, error_code, regs))
+ return;
+ do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL);
+}
+#endif /* CONFIG_KDB */
+
+
/*
* Note that we play around with the 'TS' bit in an attempt to get
* the correct behaviour even in the presence of the asynchronous
@@ -880,7 +932,17 @@
set_trap_gate(11,&segment_not_present);
set_trap_gate(12,&stack_segment);
set_trap_gate(13,&general_protection);
+#ifdef CONFIG_KDB
+ if (test_bit(X86_FEATURE_MCE, boot_cpu_data.x86_capability) &&
+ test_bit(X86_FEATURE_MCA, boot_cpu_data.x86_capability)) {
+ set_intr_gate(14,&page_fault_mca);
+ }
+ else {
+ set_intr_gate(14,&page_fault);
+ }
+#else /* !CONFIG_KDB */
set_intr_gate(14,&page_fault);
+#endif /* CONFIG_KDB */
set_trap_gate(15,&spurious_interrupt_bug);
set_trap_gate(16,&coprocessor_error);
set_trap_gate(17,&alignment_check);
@@ -890,6 +952,14 @@
set_trap_gate(19,&simd_coprocessor_error);
set_system_gate(SYSCALL_VECTOR,&system_call);
+#ifdef CONFIG_KDB
+ kdb_enablehwfault();
+ /*
+ * A trap gate, used by the kernel to enter the
+ * debugger, preserving all registers.
+ */
+ set_trap_gate(KDBENTER_VECTOR, &kdb_call);
+#endif /* CONFIG_KDB */
/*
* default LDT is a single-entry callgate to lcall7 for iBCS
Index: 2.6.x-xfs/arch/i386/kernel/vmlinux.lds.S
===================================================================
--- 2.6.x-xfs.orig/arch/i386/kernel/vmlinux.lds.S Tue May 11 14:54:13 2004
+++ 2.6.x-xfs/arch/i386/kernel/vmlinux.lds.S Tue May 11 16:10:50 2004
@@ -83,6 +83,9 @@
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ __kdb_initcall_start = .;
+ .kdb_initcall.init : { *(.kdb_initcall.init) }
+ __kdb_initcall_end = .;
SECURITY_INIT
. = ALIGN(4);
__alt_instructions = .;
Index: 2.6.x-xfs/include/asm-i386/kmap_types.h
===================================================================
--- 2.6.x-xfs.orig/include/asm-i386/kmap_types.h Tue May 11 14:47:19 2004
+++ 2.6.x-xfs/include/asm-i386/kmap_types.h Tue May 11 16:10:50 2004
@@ -24,7 +24,8 @@
D(11) KM_IRQ1,
D(12) KM_SOFTIRQ0,
D(13) KM_SOFTIRQ1,
-D(14) KM_TYPE_NR
+D(14) KM_KDB,
+D(15) KM_TYPE_NR
};
#undef D
Index: 2.6.x-xfs/include/asm-i386/mach-default/irq_vectors.h
===================================================================
--- 2.6.x-xfs.orig/include/asm-i386/mach-default/irq_vectors.h Tue May 11 14:54:16 2004
+++ 2.6.x-xfs/include/asm-i386/mach-default/irq_vectors.h Tue May 11 16:10:50 2004
@@ -29,6 +29,7 @@
#define FIRST_EXTERNAL_VECTOR 0x20
#define SYSCALL_VECTOR 0x80
+#define KDBENTER_VECTOR 0x81
/*
* Vectors 0x20-0x2f are used for ISA interrupts.
@@ -48,6 +49,7 @@
#define INVALIDATE_TLB_VECTOR 0xfd
#define RESCHEDULE_VECTOR 0xfc
#define CALL_FUNCTION_VECTOR 0xfb
+#define KDB_VECTOR 0xf9
#define THERMAL_APIC_VECTOR 0xf0
/*
Index: 2.6.x-xfs/include/asm-i386/ptrace.h
===================================================================
--- 2.6.x-xfs.orig/include/asm-i386/ptrace.h Tue May 11 14:47:19 2004
+++ 2.6.x-xfs/include/asm-i386/ptrace.h Tue May 11 16:10:50 2004
@@ -54,6 +54,29 @@
#define PTRACE_GET_THREAD_AREA 25
#define PTRACE_SET_THREAD_AREA 26
+enum EFLAGS {
+ EF_CF = 0x00000001,
+ EF_PF = 0x00000004,
+ EF_AF = 0x00000010,
+ EF_ZF = 0x00000040,
+ EF_SF = 0x00000080,
+ EF_TF = 0x00000100,
+ EF_IE = 0x00000200,
+ EF_DF = 0x00000400,
+ EF_OF = 0x00000800,
+ EF_IOPL = 0x00003000,
+ EF_IOPL_RING0 = 0x00000000,
+ EF_IOPL_RING1 = 0x00001000,
+ EF_IOPL_RING2 = 0x00002000,
+ EF_NT = 0x00004000, /* nested task */
+ EF_RF = 0x00010000, /* resume */
+ EF_VM = 0x00020000, /* virtual mode */
+ EF_AC = 0x00040000, /* alignment */
+ EF_VIF = 0x00080000, /* virtual interrupt */
+ EF_VIP = 0x00100000, /* virtual interrupt pending */
+ EF_ID = 0x00200000, /* id */
+};
+
#ifdef __KERNEL__
#define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs))
#define instruction_pointer(regs) ((regs)->eip)