Skip to contentSkip to conversation

A different KGDB stub for -mm

PATCH In review Tom Rini 2 participants 12 messages Oct 29, 2004 – Oct 30, 2004

Subsystems (6)
lore
Share & tools
lore

Tom Rini

author
#0 lore raw

PATCH 1/8 A different KGDB stub for -mm

Cc: <[email protected]>, <[email protected]>
The following series of patches adds (or in some cases, replaces) KGDB support for i386, ppc32, ia64, x86_64 and mips (both 32 and 64bit tested). This version of KGDB can be used either via serial or ethernet.

Some useful features, such as a descriptive 'info threads' are supported by a series of GDB patches which Amit is working on getting merged upstream. These can be found in CVS on kgdb.sourceforge.net in the gdb module and currently only work on i386. I've sent these patches to Andrew, who will put them up on kernel.org for easier access.

It is my hope that these patches can be merged into the -mm tree at this point.

This version of KGDB has a common back-end with hooks for architectures to what they need to and can't be generalized. Similarly, there are hooks for I/O so that it can be done by 8250 uart, ethernet via netpoll, or board-specific UART (e.g. the one found on MIPS SiByte 1250-swarm boards).

kgdb can be told to wait for the system via kgdbwait, or you can just connect to a running system. Or if you have SysRq, 'g' will drop into KGDB. 8250 can be configured at compile time or boot time. kgdboe must be configured at boot-time.

A whole lot of people have helped to get this working, and to avoid an Oscars moment, I'd like to thank everyone and leave it at that. :)

---

 linux-2.6.10-rc1-trini/Documentation/DocBook/Makefile  |    2 
 linux-2.6.10-rc1-trini/Documentation/DocBook/kgdb.tmpl |  175 ++
 linux-2.6.10-rc1-trini/Makefile                        |    2 
 linux-2.6.10-rc1-trini/include/linux/debugger.h        |   59 
 linux-2.6.10-rc1-trini/include/linux/kgdb.h            |  212 ++
 linux-2.6.10-rc1-trini/kernel/Makefile                 |    1 
 linux-2.6.10-rc1-trini/kernel/kgdb.c                   | 1390 +++++++++++++++++
 linux-2.6.10-rc1-trini/kernel/pid.c                    |   11 
 linux-2.6.10-rc1-trini/kernel/sched.c                  |    7 
 linux-2.6.10-rc1-trini/lib/Kconfig.debug               |   14 
 10 files changed, 1871 insertions(+), 2 deletions(-)
Documentation/DocBook/Makefile renamed from Documentation/DocBook/Makefile~core-lite +1 -1
diff -puN Documentation/DocBook/Makefile~core-lite Documentation/DocBook/Makefile
@@ -11,7 +11,7 @@ DOCBOOKS := wanbook.sgml z8530book.sgml 
 	    mousedrivers.sgml deviceiobook.sgml procfs-guide.sgml \
 	    tulip-user.sgml writing_usb_driver.sgml scsidrivers.sgml \
 	    sis900.sgml kernel-api.sgml journal-api.sgml lsm.sgml usb.sgml \
-	    gadget.sgml libata.sgml mtdnand.sgml librs.sgml
+	    gadget.sgml libata.sgml mtdnand.sgml librs.sgml kgdb.sgml
 
 ###
 # The build process is as follows (targets):
Documentation/DocBook/kgdb.tmpl new file +175 -0

175 lines not on this page · raw message

Makefile renamed from Makefile~core-lite +2 -0
diff -puN Makefile~core-lite Makefile
@@ -488,6 +488,8 @@ endif
 
 ifndef CONFIG_FRAME_POINTER
 CFLAGS		+= -fomit-frame-pointer
+else
+CFLAGS		+= -fno-omit-frame-pointer
 endif
 
 ifdef CONFIG_DEBUG_INFO
include/linux/debugger.h new file +59 -0

59 lines not on this page · raw message

include/linux/kgdb.h new file +212 -0

212 lines not on this page · raw message

kernel/Makefile renamed from kernel/Makefile~core-lite +1 -0
diff -puN kernel/Makefile~core-lite kernel/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_STOP_MACHINE) += stop_machi
 obj-$(CONFIG_AUDIT) += audit.o
 obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
 obj-$(CONFIG_KPROBES) += kprobes.o
+obj-$(CONFIG_KGDB) += kgdb.o
 obj-$(CONFIG_SYSFS) += ksysfs.o
 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
 
kernel/kgdb.c new file +1390 -0

1,390 lines not on this page · raw message

kernel/pid.c renamed from kernel/pid.c~core-lite +10 -1
diff -puN kernel/pid.c~core-lite kernel/pid.c
@@ -250,8 +250,13 @@ void switch_exec_pids(task_t *leader, ta
 /*
  * The pid hash table is scaled according to the amount of memory in the
  * machine.  From a minimum of 16 slots up to 4096 slots at one gigabyte or
- * more.
+ * more.  KGDB needs to know if this function has been called already,
+ * since we might have entered KGDB very early.
  */
+#ifdef CONFIG_KGDB
+int pidhash_init_done;
+#endif
+
 void __init pidhash_init(void)
 {
 	int i, j, pidhash_size;
@@ -273,6 +278,10 @@ void __init pidhash_init(void)
 		for (j = 0; j < pidhash_size; j++)
 			INIT_HLIST_HEAD(&pid_hash[i][j]);
 	}
+
+#ifdef CONFIG_KGDB
+	pidhash_init_done = 1;
+#endif
 }
 
 void __init pidmap_init(void)
kernel/sched.c renamed from kernel/sched.c~core-lite +7 -0
diff -puN kernel/sched.c~core-lite kernel/sched.c
@@ -44,6 +44,7 @@
 #include <linux/seq_file.h>
 #include <linux/syscalls.h>
 #include <linux/times.h>
+#include <linux/debugger.h>
 #include <asm/tlb.h>
 
 #include <asm/unistd.h>
@@ -4567,6 +4568,12 @@ void __might_sleep(char *file, int line)
 #if defined(in_atomic)
 	static unsigned long prev_jiffy;	/* ratelimiting */
 
+	if (atomic_read(&debugger_active))
+		return;
+
+	if (atomic_read(&debugger_active))
+		return;
+
 	if ((in_atomic() || irqs_disabled()) &&
 	    system_state == SYSTEM_RUNNING) {
 		if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
lib/Kconfig.debug renamed from lib/Kconfig.debug~core-lite +14 -0
diff -puN lib/Kconfig.debug~core-lite lib/Kconfig.debug
@@ -82,6 +82,7 @@ config DEBUG_BUGVERBOSE
 config DEBUG_INFO
 	bool "Compile the kernel with debug info"
 	depends on DEBUG_KERNEL && (ALPHA || CRIS || X86 || IA64 || M68K || MIPS || PARISC || PPC32 || PPC64 || ARCH_S390 || (SUPERH && !SUPERH64) || SPARC64 || V850 || X86_64)
+	default y if KGDB
 	help
           If you say Y here the resulting kernel image will include
 	  debugging info resulting in a larger kernel image.
@@ -104,9 +105,22 @@ if !X86_64
 config FRAME_POINTER
 	bool "Compile the kernel with frame pointers"
 	depends on X86 || CRIS || M68KNOMMU || PARISC
+	default y if KGDB
 	help
 	  If you say Y here the resulting kernel image will be slightly larger
 	  and slower, but it will give very useful debugging information.
 	  If you don't debug the kernel, you can say N, but we may not be able
 	  to solve problems without frame pointers.
 endif
+
+config KGDB
+	bool "KGDB: kernel debugging with remote gdb"
+	depends on DEBUG_KERNEL
+	help
+	  If you say Y here, it will be possible to remotely debug the
+	  kernel using gdb. This enlarges your kernel image disk size by
+	  several megabytes and requires a machine with more than 128 MB
+	  RAM to avoid excessive linking time.
+	  Documentation of kernel debugger available at
+	  http://kgdb.sourceforge.net
+	  This is only useful for kernel hackers. If unsure, say N.

_

author
#1 lore raw

PATCH 2/8 KGDB support for i386

This adds support for KGDB on the i386 architecture. The only slightly related change is to make i386 parse early_params now as KGDB registers as one. We also add an early_trap_init() call which does the parts of trap_init() which need to be done for KGDB to be entered, and can be done safely this early.

As an aside, I believe the hunk to arch/i386/kernel/signal.c can be dropped in a post 2.6.10-rc1 tree as something similar using unlikey() has been put in.

---

 linux-2.6.10-rc1-trini/arch/i386/kernel/Makefile |    1 
 linux-2.6.10-rc1-trini/arch/i386/kernel/irq.c    |    3 
 linux-2.6.10-rc1-trini/arch/i386/kernel/kgdb.c   |  300 +++++++++++++++++++++++
 linux-2.6.10-rc1-trini/arch/i386/kernel/nmi.c    |   11 
 linux-2.6.10-rc1-trini/arch/i386/kernel/setup.c  |    3 
 linux-2.6.10-rc1-trini/arch/i386/kernel/signal.c |    3 
 linux-2.6.10-rc1-trini/arch/i386/kernel/traps.c  |   31 +-
 linux-2.6.10-rc1-trini/arch/i386/mm/fault.c      |   10 
 linux-2.6.10-rc1-trini/include/asm-i386/kgdb.h   |   48 +++
 linux-2.6.10-rc1-trini/include/asm-i386/system.h |   10 
 linux-2.6.10-rc1-trini/lib/Kconfig.debug         |    2 
 11 files changed, 405 insertions(+), 17 deletions(-)
arch/i386/kernel/Makefile renamed from arch/i386/kernel/Makefile~i386-lite +1 -0
diff -puN arch/i386/kernel/Makefile~i386-lite arch/i386/kernel/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_ACPI_SRAT) 	+= srat.o
 obj-$(CONFIG_HPET_TIMER) 	+= time_hpet.o
 obj-$(CONFIG_EFI) 		+= efi.o efi_stub.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
+obj-$(CONFIG_KGDB)		+= kgdb.o
 
 EXTRA_AFLAGS   := -traditional
 
arch/i386/kernel/irq.c renamed from arch/i386/kernel/irq.c~i386-lite +3 -0
diff -puN arch/i386/kernel/irq.c~i386-lite arch/i386/kernel/irq.c
@@ -15,6 +15,7 @@
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
+#include <linux/kgdb.h>
 
 #ifndef CONFIG_X86_LOCAL_APIC
 /*
@@ -103,6 +104,8 @@ asmlinkage unsigned int do_IRQ(struct pt
 
 	irq_exit();
 
+	kgdb_process_breakpoint();
+
 	return 1;
 }
 
arch/i386/kernel/kgdb.c new file +300 -0

300 lines not on this page · raw message

arch/i386/kernel/nmi.c renamed from arch/i386/kernel/nmi.c~i386-lite +10 -1
diff -puN arch/i386/kernel/nmi.c~i386-lite arch/i386/kernel/nmi.c
@@ -26,6 +26,7 @@
 #include <linux/nmi.h>
 #include <linux/sysdev.h>
 #include <linux/sysctl.h>
+#include <linux/debugger.h>
 
 #include <asm/smp.h>
 #include <asm/mtrr.h>
@@ -481,7 +482,15 @@ void nmi_watchdog_tick (struct pt_regs *
 
 	sum = irq_stat[cpu].apic_timer_irqs;
 
-	if (last_irq_sums[cpu] == sum) {
+	if (atomic_read(&debugger_active)) {
+		/*
+		 * The machine is in debugger, hold this cpu if already
+		 * not held.
+		 */
+		debugger_nmihook(cpu, regs);
+		alert_counter[cpu] = 0;
+
+	} else if (last_irq_sums[cpu] == sum) {
 		/*
 		 * Ayiee, looks like this CPU is stuck ...
 		 * wait a few IRQs (5 seconds) before doing the oops ...
arch/i386/kernel/setup.c renamed from arch/i386/kernel/setup.c~i386-lite +3 -0
diff -puN arch/i386/kernel/setup.c~i386-lite arch/i386/kernel/setup.c
@@ -117,6 +117,7 @@ struct e820map e820;
 unsigned char aux_device_present;
 
 extern void early_cpu_init(void);
+extern void early_trap_init(void);
 extern void dmi_scan_machine(void);
 extern void generic_apic_probe(char *);
 extern int root_mountflags;
@@ -1302,6 +1303,7 @@ void __init setup_arch(char **cmdline_p)
 	memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
 	pre_setup_arch_hook();
 	early_cpu_init();
+	early_trap_init();
 
 	/*
 	 * FIXME: This isn't an official loader_type right
@@ -1358,6 +1360,7 @@ void __init setup_arch(char **cmdline_p)
 	data_resource.end = virt_to_phys(_edata)-1;
 
 	parse_cmdline_early(cmdline_p);
+	parse_early_param();
 
 	max_low_pfn = setup_memory();
 
arch/i386/kernel/signal.c renamed from arch/i386/kernel/signal.c~i386-lite +2 -1
diff -puN arch/i386/kernel/signal.c~i386-lite arch/i386/kernel/signal.c
@@ -600,7 +600,8 @@ int fastcall do_signal(struct pt_regs *r
 		 * have been cleared if the watchpoint triggered
 		 * inside the kernel.
 		 */
-		__asm__("movl %0,%%db7"	: : "r" (current->thread.debugreg[7]));
+		if (current->thread.debugreg[7])
+			__asm__("movl %0,%%db7"	: : "r" (current->thread.debugreg[7]));
 
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal(signr, &info, &ka, oldset, regs);
arch/i386/kernel/traps.c renamed from arch/i386/kernel/traps.c~i386-lite +19 -12
diff -puN arch/i386/kernel/traps.c~i386-lite arch/i386/kernel/traps.c
@@ -53,6 +53,7 @@
 
 #include <linux/irq.h>
 #include <linux/module.h>
+#include <linux/debugger.h>
 
 #include "mach_traps.h"
 
@@ -332,7 +333,7 @@ void die(const char * str, struct pt_reg
 #endif
 		if (nl)
 			printk("\n");
-	notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
+		notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
 		show_registers(regs);
   	} else
 		printk(KERN_ERR "Recursive die() failure, output suppressed\n");
@@ -711,7 +712,7 @@ asmlinkage void do_debug(struct pt_regs 
 	tsk->thread.debugreg[6] = condition;
 
 	/* Mask out spurious TF errors due to lazy TF clearing */
-	if (condition & DR_STEP) {
+	if (condition & DR_STEP && !debugger_step) {
 		/*
 		 * The TF error should be masked out only if the current
 		 * process is not traced and if the TRAP flag has been set
@@ -733,12 +734,14 @@ asmlinkage void do_debug(struct pt_regs 
 	info.si_signo = SIGTRAP;
 	info.si_errno = 0;
 	info.si_code = TRAP_BRKPT;
-	
-	/* If this is a kernel mode trap, save the user PC on entry to 
-	 * the kernel, that's what the debugger can make sense of.
-	 */
-	info.si_addr = ((regs->xcs & 3) == 0) ? (void __user *)tsk->thread.eip
-	                                      : (void __user *)regs->eip;
+
+	/* If this is a kernel mode trap, we need to reset db7 to allow us
+	 * to continue sanely */
+	if ((regs->xcs & 3) == 0)
+		goto clear_dr7;
+
+	info.si_addr = (void *)regs->eip;
+
 	force_sig_info(SIGTRAP, &info, tsk);
 
 	/* Disable additional traps. They'll be re-enabled when
@@ -748,6 +751,7 @@ clear_dr7:
 	__asm__("movl %0,%%db7"
 		: /* no output */
 		: "r" (0));
+	notify_die(DIE_DEBUG, "debug", regs, condition, error_code, SIGTRAP);
 	return;
 
 debug_vm86:
@@ -1005,6 +1009,12 @@ static void __init set_task_gate(unsigne
 	_set_gate(idt_table+n,5,0,0,(gdt_entry<<3));
 }
 
+/* Some traps need to be set early. */
+void __init early_trap_init(void) {
+	set_intr_gate(1,&debug);
+	set_system_intr_gate(3, &int3); /* int3 can be called from all */
+	set_intr_gate(14,&page_fault);
+}
 
 void __init trap_init(void)
 {
@@ -1019,10 +1029,8 @@ void __init trap_init(void)
 #endif
 
 	set_trap_gate(0,&divide_error);
-	set_intr_gate(1,&debug);
 	set_intr_gate(2,&nmi);
-	set_system_intr_gate(3, &int3); /* int3-5 can be called from all */
-	set_system_gate(4,&overflow);
+	set_system_gate(4,&overflow); /* int4/5 can be called from all */
 	set_system_gate(5,&bounds);
 	set_trap_gate(6,&invalid_op);
 	set_trap_gate(7,&device_not_available);
@@ -1032,7 +1040,6 @@ void __init trap_init(void)
 	set_trap_gate(11,&segment_not_present);
 	set_trap_gate(12,&stack_segment);
 	set_trap_gate(13,&general_protection);
-	set_intr_gate(14,&page_fault);
 	set_trap_gate(15,&spurious_interrupt_bug);
 	set_trap_gate(16,&coprocessor_error);
 	set_trap_gate(17,&alignment_check);
arch/i386/mm/fault.c renamed from arch/i386/mm/fault.c~i386-lite +10 -0
diff -puN arch/i386/mm/fault.c~i386-lite arch/i386/mm/fault.c
@@ -2,6 +2,11 @@
  *  linux/arch/i386/mm/fault.c
  *
  *  Copyright (C) 1995  Linus Torvalds
+ *
+ *  Change History
+ *
+ *	Tigran Aivazian <[email protected]>	Remote debugging support.
+ *
  */
 
 #include <linux/signal.h>
@@ -21,6 +26,7 @@
 #include <linux/vt_kern.h>		/* For unblank_screen() */
 #include <linux/highmem.h>
 #include <linux/module.h>
+#include <linux/debugger.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -426,6 +432,10 @@ no_context:
  	if (is_prefetch(regs, address, error_code))
  		return;
 
+	if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
+				SIGSEGV) == NOTIFY_BAD)
+		return;
+
 /*
  * Oops. The kernel tried to access some bad page. We'll have to
  * terminate things with extreme prejudice.
include/asm-i386/kgdb.h new file +48 -0

48 lines not on this page · raw message

include/asm-i386/system.h renamed from include/asm-i386/system.h~i386-lite +8 -2
diff -puN include/asm-i386/system.h~i386-lite include/asm-i386/system.h
@@ -12,9 +12,13 @@
 struct task_struct;	/* one of the stranger aspects of C forward declarations.. */
 extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
 
+/* sleeping_thread_to_gdb_regs depends on this code. Correct it if you change
+ * any of the following */
 #define switch_to(prev,next,last) do {					\
 	unsigned long esi,edi;						\
-	asm volatile("pushfl\n\t"					\
+	asm volatile(".globl __switch_to_begin\n"			\
+		     "__switch_to_begin:"				\
+		     "pushfl\n\t"					\
 		     "pushl %%ebp\n\t"					\
 		     "movl %%esp,%0\n\t"	/* save ESP */		\
 		     "movl %5,%%esp\n\t"	/* restore ESP */	\
@@ -23,7 +27,9 @@ extern struct task_struct * FASTCALL(__s
 		     "jmp __switch_to\n"				\
 		     "1:\t"						\
 		     "popl %%ebp\n\t"					\
-		     "popfl"						\
+		     "popfl\n"						\
+		     ".globl __switch_to_end\n"				\
+		     "__switch_to_end:\n"				\
 		     :"=m" (prev->thread.esp),"=m" (prev->thread.eip),	\
 		      "=a" (last),"=S" (esi),"=D" (edi)			\
 		     :"m" (next->thread.esp),"m" (next->thread.eip),	\
lib/Kconfig.debug renamed from lib/Kconfig.debug~i386-lite +1 -1
diff -puN lib/Kconfig.debug~i386-lite lib/Kconfig.debug
@@ -115,7 +115,7 @@ endif
 
 config KGDB
 	bool "KGDB: kernel debugging with remote gdb"
-	depends on DEBUG_KERNEL
+	depends on DEBUG_KERNEL && (X86)
 	help
 	  If you say Y here, it will be possible to remotely debug the
 	  kernel using gdb. This enlarges your kernel image disk size by

_

author
#2 lore raw

PATCH 3/8 KGDB support for ppc32

Cc: Matt Porter <[email protected]>
This adds KGDB support for ppc32 and was done by myself. Note that this currently doesn't work on 40x || BOOKE, but that problem is more generic (the current ppc stub doesn't work either) and Matt Porter is close to having a tested solution now.

---

 linux-2.6.10-rc1-trini/arch/ppc/Kconfig.debug          |   36 
 linux-2.6.10-rc1-trini/arch/ppc/kernel/Makefile        |    2 
 linux-2.6.10-rc1-trini/arch/ppc/kernel/irq.c           |    5 
 linux-2.6.10-rc1-trini/arch/ppc/kernel/kgdb.c          |  276 +++++
 linux-2.6.10-rc1-trini/arch/ppc/kernel/setup.c         |   16 
 linux-2.6.10-rc1-trini/arch/ppc/platforms/sandpoint.c  |   11 
 linux-2.6.10-rc1-trini/arch/ppc/syslib/Makefile        |    2 
 linux-2.6.10-rc1-trini/arch/ppc/syslib/ppc4xx_serial.c |    5 
 linux-2.6.10-rc1-trini/include/asm-ppc/kgdb.h          |   20 
 linux-2.6.10-rc1-trini/lib/Kconfig.debug               |    2 
 linux-2.6.10-rc1/arch/ppc/kernel/ppc-stub.c            |  879 -----------------
 linux-2.6.10-rc1/arch/ppc/syslib/gen550_kgdb.c         |   86 -
 linux-2.6.10-rc1/arch/ppc/syslib/ppc4xx_kgdb.c         |  124 --
 13 files changed, 295 insertions(+), 1169 deletions(-)
arch/ppc/Kconfig.debug renamed from arch/ppc/Kconfig.debug~ppc-lite +0 -36
diff -puN arch/ppc/Kconfig.debug~ppc-lite arch/ppc/Kconfig.debug
@@ -2,42 +2,6 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
-config KGDB
-	bool "Include kgdb kernel debugger"
-	depends on DEBUG_KERNEL && (BROKEN || PPC_GEN550 || 4xx)
-	select DEBUG_INFO
-	help
-	  Include in-kernel hooks for kgdb, the Linux kernel source level
-	  debugger.  See <http://kgdb.sourceforge.net/> for more information.
-	  Unless you are intending to debug the kernel, say N here.
-
-choice
-	prompt "Serial Port"
-	depends on KGDB
-	default KGDB_TTYS1
-
-config KGDB_TTYS0
-	bool "ttyS0"
-
-config KGDB_TTYS1
-	bool "ttyS1"
-
-config KGDB_TTYS2
-	bool "ttyS2"
-
-config KGDB_TTYS3
-	bool "ttyS3"
-
-endchoice
-
-config KGDB_CONSOLE
-	bool "Enable serial console thru kgdb port"
-	depends on KGDB && 8xx || CPM2
-	help
-	  If you enable this, all serial console messages will be sent
-	  over the gdb stub.
-	  If unsure, say N.
-
 config XMON
 	bool "Include xmon kernel debugger"
 	depends on DEBUG_KERNEL
arch/ppc/kernel/Makefile renamed from arch/ppc/kernel/Makefile~ppc-lite +1 -1
diff -puN arch/ppc/kernel/Makefile~ppc-lite arch/ppc/kernel/Makefile
@@ -20,7 +20,7 @@ obj-$(CONFIG_POWER4)		+= cpu_setup_power
 obj-$(CONFIG_MODULES)		+= module.o ppc_ksyms.o
 obj-$(CONFIG_NOT_COHERENT_CACHE)	+= dma-mapping.o
 obj-$(CONFIG_PCI)		+= pci.o
-obj-$(CONFIG_KGDB)		+= ppc-stub.o
+obj-$(CONFIG_KGDB)		+= kgdb.o
 obj-$(CONFIG_SMP)		+= smp.o smp-tbsync.o
 obj-$(CONFIG_TAU)		+= temp.o
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
arch/ppc/kernel/irq.c renamed from arch/ppc/kernel/irq.c~ppc-lite +4 -1
diff -puN arch/ppc/kernel/irq.c~ppc-lite arch/ppc/kernel/irq.c
@@ -48,6 +48,7 @@
 #include <linux/cpumask.h>
 #include <linux/profile.h>
 #include <linux/bitops.h>
+#include <linux/kgdb.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -155,7 +156,9 @@ void do_IRQ(struct pt_regs *regs)
 	if (irq != -2 && first)
 		/* That's not SMP safe ... but who cares ? */
 		ppc_spurious_interrupts++;
-        irq_exit();
+	irq_exit();
+
+	kgdb_process_breakpoint();
 }
 
 void __init init_IRQ(void)
arch/ppc/kernel/kgdb.c new file +276 -0

276 lines not on this page · raw message

arch/ppc/kernel/ppc-stub.c deleted +0 -879

879 lines not on this page · raw message

arch/ppc/kernel/setup.c renamed from arch/ppc/kernel/setup.c~ppc-lite +0 -16
diff -puN arch/ppc/kernel/setup.c~ppc-lite arch/ppc/kernel/setup.c
@@ -40,10 +40,6 @@
 #include <asm/xmon.h>
 #include <asm/ocp.h>
 
-#if defined CONFIG_KGDB
-#include <asm/kgdb.h>
-#endif
-
 extern void platform_init(unsigned long r3, unsigned long r4,
 		unsigned long r5, unsigned long r6, unsigned long r7);
 extern void bootx_init(unsigned long r4, unsigned long phys);
@@ -699,18 +695,6 @@ void __init setup_arch(char **cmdline_p)
 #endif /* CONFIG_XMON */
 	if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab);
 
-#if defined(CONFIG_KGDB)
-	if (ppc_md.kgdb_map_scc)
-		ppc_md.kgdb_map_scc();
-	set_debug_traps();
-	if (strstr(cmd_line, "gdb")) {
-		if (ppc_md.progress)
-			ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000);
-		printk("kgdb breakpoint activated\n");
-		breakpoint();
-	}
-#endif
-
 	/*
 	 * Set cache line size based on type of cpu as a default.
 	 * Systems with OF can look in the properties on the cpu node(s)
arch/ppc/platforms/sandpoint.c renamed from arch/ppc/platforms/sandpoint.c~ppc-lite +2 -9
diff -puN arch/ppc/platforms/sandpoint.c~ppc-lite arch/ppc/platforms/sandpoint.c
@@ -252,8 +252,7 @@ sandpoint_find_bridges(void)
 	return;
 }
 
-#if defined(CONFIG_SERIAL_8250) && \
-	(defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG))
+#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
 static void __init
 sandpoint_early_serial_map(void)
 {
@@ -689,16 +688,10 @@ platform_init(unsigned long r3, unsigned
 	ppc_md.nvram_read_val = todc_mc146818_read_val;
 	ppc_md.nvram_write_val = todc_mc146818_write_val;
 
-#if defined(CONFIG_SERIAL_8250) && \
-	(defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG))
+#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
 	sandpoint_early_serial_map();
-#ifdef CONFIG_KGDB
-	ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
-#endif
-#ifdef CONFIG_SERIAL_TEXT_DEBUG
 	ppc_md.progress = gen550_progress;
 #endif
-#endif
 
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
 	ppc_ide_md.default_irq = sandpoint_ide_default_irq;
arch/ppc/syslib/Makefile renamed from arch/ppc/syslib/Makefile~ppc-lite +0 -2
diff -puN arch/ppc/syslib/Makefile~ppc-lite arch/ppc/syslib/Makefile
@@ -25,7 +25,6 @@ obj-$(CONFIG_GEN_RTC)		+= todc_time.o
 obj-$(CONFIG_PPC4xx_DMA)	+= ppc4xx_dma.o
 obj-$(CONFIG_PPC4xx_EDMA)	+= ppc4xx_sgdma.o
 ifeq ($(CONFIG_40x),y)
-obj-$(CONFIG_KGDB)		+= ppc4xx_kgdb.o
 obj-$(CONFIG_PCI)		+= indirect_pci.o pci_auto.o ppc405_pci.o
 endif
 endif
@@ -72,7 +71,6 @@ obj-$(CONFIG_PCI_8260)		+= m8260_pci.o i
 obj-$(CONFIG_8260_PCI9)		+= m8260_pci_erratum9.o
 obj-$(CONFIG_CPM2)		+= cpm2_common.o cpm2_pic.o
 ifeq ($(CONFIG_PPC_GEN550),y)
-obj-$(CONFIG_KGDB)		+= gen550_kgdb.o gen550_dbg.o
 obj-$(CONFIG_SERIAL_TEXT_DEBUG)	+= gen550_dbg.o
 endif
 obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
arch/ppc/syslib/gen550_kgdb.c deleted +0 -86

86 lines not on this page · raw message

arch/ppc/syslib/ppc4xx_kgdb.c deleted +0 -124

124 lines not on this page · raw message

arch/ppc/syslib/ppc4xx_serial.c renamed from arch/ppc/syslib/ppc4xx_serial.c~ppc-lite +0 -5
diff -puN arch/ppc/syslib/ppc4xx_serial.c~ppc-lite arch/ppc/syslib/ppc4xx_serial.c
@@ -20,11 +20,6 @@
 
 #if defined(CONFIG_IBM405GP) || defined(CONFIG_IBM405CR)
 
-#ifdef CONFIG_KGDB
-#include <asm/kgdb.h>
-#include <linux/init.h>
-#endif
-
 #ifdef CONFIG_DEBUG_BRINGUP
 
 #include <linux/console.h>
include/asm-ppc/kgdb.h renamed from include/asm-ppc/kgdb.h~ppc-lite +11 -9
diff -puN include/asm-ppc/kgdb.h~ppc-lite include/asm-ppc/kgdb.h
@@ -2,6 +2,8 @@
  * kgdb.h: Defines and declarations for serial line source level
  *         remote debugging of the Linux kernel using gdb.
  *
+ * PPC Mods (C) 2004 Tom Rini ([email protected])
+ * PPC Mods (C) 2003 John Whitney ([email protected])
  * PPC Mods (C) 1998 Michael Tesch ([email protected])
  *
  * Copyright (C) 1995 David S. Miller ([email protected])
@@ -12,6 +14,15 @@
 
 #ifndef __ASSEMBLY__
 
+#define BREAK_INSTR_SIZE	4
+#define MAXREG			(PT_FPSCR+1)
+#define NUMREGBYTES		(MAXREG * sizeof(int))
+#define BUFMAX			((NUMREGBYTES * 2) + 512)
+#define OUTBUFMAX		((NUMREGBYTES * 2) + 512)
+#define BREAKPOINT()		asm(".long 0x7d821008"); /* twge r2, r2 */
+
+#define CHECK_EXCEPTION_STACK() 	1
+
 /* Things specific to the gen550 backend. */
 struct uart_port;
 
@@ -19,15 +30,6 @@ extern void gen550_progress(char *, unsi
 extern void gen550_kgdb_map_scc(void);
 extern void gen550_init(int, struct uart_port *);
 
-/* Things specific to the pmac backend. */
-extern void zs_kgdb_hook(int tty_num);
-
-/* To init the kgdb engine. (called by serial hook)*/
-extern void set_debug_traps(void);
-
-/* To enter the debugger explicitly. */
-extern void breakpoint(void);
-
 /* For taking exceptions
  * these are defined in traps.c
  */
lib/Kconfig.debug renamed from lib/Kconfig.debug~ppc-lite +1 -1
diff -puN lib/Kconfig.debug~ppc-lite lib/Kconfig.debug
@@ -115,7 +115,7 @@ endif
 
 config KGDB
 	bool "KGDB: kernel debugging with remote gdb"
-	depends on DEBUG_KERNEL && (X86)
+	depends on DEBUG_KERNEL && (X86 || ((!SMP || BROKEN) && (PPC32)))
 	help
 	  If you say Y here, it will be possible to remotely debug the
 	  kernel using gdb. This enlarges your kernel image disk size by

_

author
#3 lore raw

PATCH 4/8 8250 uart driver for KGDB

Cc: Russell King <[email protected]>
This adds an 8250 uart driver for KGDB and adds a hook into 8250.c to unregister a port based on the IRQ, serial8250_release_irq(). We use serial8250_unregister_port() to do the real work here, however. Note that we can't use unregister_port in kgdb_8250.c since we don't know what the 'port' is, in 8250 terms, only the IRQ. The other change is that we have SERIAL_8250_NR_UARTS always be defined if KGDB_8250.

---

 linux-2.6.10-rc1-trini/drivers/serial/8250.c        |   39 +
 linux-2.6.10-rc1-trini/drivers/serial/Kconfig       |    4 
 linux-2.6.10-rc1-trini/drivers/serial/Makefile      |    1 
 linux-2.6.10-rc1-trini/drivers/serial/kgdb_8250.c   |  477 ++++++++++++++++++++
 linux-2.6.10-rc1-trini/drivers/serial/serial_core.c |    6 
 linux-2.6.10-rc1-trini/lib/Kconfig.debug            |  101 ++++
 6 files changed, 625 insertions(+), 3 deletions(-)
drivers/serial/8250.c renamed from drivers/serial/8250.c~8250 +39 -0
diff -puN drivers/serial/8250.c~8250 drivers/serial/8250.c
@@ -1348,12 +1348,17 @@ static void serial8250_break_ctl(struct 
 	spin_unlock_irqrestore(&up->port.lock, flags);
 }
 
+static int released_irq = -1;
+
 static int serial8250_startup(struct uart_port *port)
 {
 	struct uart_8250_port *up = (struct uart_8250_port *)port;
 	unsigned long flags;
 	int retval;
 
+	if (up->port.irq == released_irq)
+		return -EBUSY;
+
 	up->capabilities = uart_config[up->port.type].flags;
 	up->mcr = 0;
 
@@ -1990,6 +1995,9 @@ serial8250_register_ports(struct uart_dr
 	for (i = 0; i < UART_NR; i++) {
 		struct uart_8250_port *up = &serial8250_ports[i];
 
+		if (up->port.irq == released_irq)
+			continue;
+
 		up->port.line = i;
 		up->port.ops = &serial8250_pops;
 		up->port.dev = dev;
@@ -2327,6 +2335,9 @@ int serial8250_register_port(struct uart
 	struct uart_8250_port *uart;
 	int ret = -ENOSPC;
 
+	if (port->line == released_irq)
+		return -EBUSY;
+
 	down(&serial_sem);
 
 	uart = serial8250_find_match_or_unused(port);
@@ -2376,6 +2387,34 @@ void serial8250_unregister_port(int line
 }
 EXPORT_SYMBOL(serial8250_unregister_port);
 
+/**
+ *	serial8250_release_irq - remove a 16x50 serial port at runtime based
+ *	on IRQ
+ *	@irq: IRQ number
+ *
+ *	Remove one serial port.  This may not be called from interrupt
+ *	context.  This is called when the caller know the IRQ of the
+ *	port they want, but not where it is in our table.  This allows
+ *	for one port, based on IRQ, to be permanently released from us.
+ */
+
+int serial8250_release_irq(int irq)
+{
+        struct uart_8250_port *up;
+	int ttyS;
+
+	if (released_irq != -1)
+		return -EBUSY;
+
+	released_irq = irq;
+	for (ttyS = 0; ttyS < UART_NR; ttyS++){
+		up =  &serial8250_ports[ttyS];
+		if (up->port.irq == irq && (irq_lists + irq)->head)
+			serial8250_unregister_port(up->port.line);
+        }
+	return 0;
+}
+
 static int __init serial8250_init(void)
 {
 	int ret, i;
drivers/serial/Kconfig renamed from drivers/serial/Kconfig~8250 +2 -2
diff -puN drivers/serial/Kconfig~8250 drivers/serial/Kconfig
@@ -86,8 +86,8 @@ config SERIAL_8250_ACPI
 	  namespace, say Y here.  If unsure, say N.
 
 config SERIAL_8250_NR_UARTS
-	int "Maximum number of non-legacy 8250/16550 serial ports"
-	depends on SERIAL_8250
+	int "Maximum number of non-legacy 8250/16550 serial ports" if SERIAL_8250
+	depends on SERIAL_8250 || KGDB_8250
 	default "4"
 	---help---
 	  Set this to the number of non-legacy serial ports you want
drivers/serial/Makefile renamed from drivers/serial/Makefile~8250 +1 -0
diff -puN drivers/serial/Makefile~8250 drivers/serial/Makefile
@@ -42,3 +42,4 @@ obj-$(CONFIG_SERIAL_SGI_L1_CONSOLE) += s
 obj-$(CONFIG_SERIAL_CPM) += cpm_uart/
 obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o
 obj-$(CONFIG_SERIAL_M32R_SIO) += m32r_sio.o
+obj-$(CONFIG_KGDB_8250) += kgdb_8250.o
drivers/serial/kgdb_8250.c new file +477 -0

477 lines not on this page · raw message

drivers/serial/serial_core.c renamed from drivers/serial/serial_core.c~8250 +5 -1
diff -puN drivers/serial/serial_core.c~8250 drivers/serial/serial_core.c
@@ -903,7 +903,11 @@ uart_tiocmset(struct tty_struct *tty, st
 static void uart_break_ctl(struct tty_struct *tty, int break_state)
 {
 	struct uart_state *state = tty->driver_data;
-	struct uart_port *port = state->port;
+	struct uart_port *port;
+
+	if (!state)
+		return;
+	port = state->port;
 
 	BUG_ON(!kernel_locked());
 
lib/Kconfig.debug renamed from lib/Kconfig.debug~8250 +101 -0

104 lines not on this page · raw message

_

author
#4 lore raw

PATCH 5/8 KGDB support for MIPS

Cc: Ralf Baechle <[email protected]>, Manish Lachwani <[email protected]> This adds KGDB support for MIPS and was done by Manish Lachwani. This has been tested on MIPS Malta and Sibyte 1250 SWARM (32 & 64).

---

 linux-2.6.10-rc1-trini/arch/mips/Kconfig.debug                   |   19 
 linux-2.6.10-rc1-trini/arch/mips/kernel/Makefile                 |    2 
 linux-2.6.10-rc1-trini/arch/mips/kernel/irq.c                    |    3 
 linux-2.6.10-rc1-trini/arch/mips/kernel/kgdb.c                   |  292 ++
 linux-2.6.10-rc1-trini/arch/mips/kernel/kgdb_handler.S           |   58 
 linux-2.6.10-rc1-trini/arch/mips/kernel/traps.c                  |   29 
 linux-2.6.10-rc1-trini/arch/mips/mips-boards/generic/Makefile    |    1 
 linux-2.6.10-rc1-trini/arch/mips/mips-boards/generic/init.c      |   64 
 linux-2.6.10-rc1-trini/arch/mips/mips-boards/malta/malta_int.c   |   25 
 linux-2.6.10-rc1-trini/arch/mips/mips-boards/malta/malta_setup.c |    8 
 linux-2.6.10-rc1-trini/arch/mips/sibyte/cfe/setup.c              |   14 
 linux-2.6.10-rc1-trini/arch/mips/sibyte/sb1250/Makefile          |    1 
 linux-2.6.10-rc1-trini/arch/mips/sibyte/sb1250/irq.c             |   72 
 linux-2.6.10-rc1-trini/arch/mips/sibyte/sb1250/kgdb_sibyte.c     |  158 +
 linux-2.6.10-rc1-trini/arch/mips/sibyte/swarm/Makefile           |    2 
 linux-2.6.10-rc1-trini/include/asm-mips/kdebug.h                 |   47 
 linux-2.6.10-rc1-trini/include/asm-mips/kgdb.h                   |   20 
 linux-2.6.10-rc1-trini/lib/Kconfig.debug                         |    9 
 linux-2.6.10-rc1/arch/mips/kernel/gdb-low.S                      |  370 ---
 linux-2.6.10-rc1/arch/mips/kernel/gdb-stub.c                     | 1089 ----------
 linux-2.6.10-rc1/arch/mips/sibyte/swarm/dbg_io.c                 |   76 
 21 files changed, 633 insertions(+), 1726 deletions(-)
arch/mips/Kconfig.debug renamed from arch/mips/Kconfig.debug~mips-lite +0 -19
diff -puN arch/mips/Kconfig.debug~mips-lite arch/mips/Kconfig.debug
@@ -27,25 +27,6 @@ config DEBUG_STACK_USAGE
 
 	  This option will slow down process creation somewhat.
 
-config KGDB
-	bool "Remote GDB kernel debugging"
-	depends on DEBUG_KERNEL
-	select DEBUG_INFO
-	help
-	  If you say Y here, it will be possible to remotely debug the MIPS
-	  kernel using gdb. This enlarges your kernel image disk size by
-	  several megabytes and requires a machine with more than 16 MB,
-	  better 32 MB RAM to avoid excessive linking time. This is only
-	  useful for kernel hackers. If unsure, say N.
-
-config GDB_CONSOLE
-	bool "Console output to GDB"
-	depends on KGDB
-	help
-	  If you are using GDB for remote debugging over a serial port and
-	  would like kernel messages to be formatted into GDB $O packets so
-	  that GDB prints them as program output, say 'Y'.
-
 config SB1XXX_CORELIS
 	bool "Corelis Debugger"
 	depends on SIBYTE_SB1xxx_SOC
arch/mips/kernel/Makefile renamed from arch/mips/kernel/Makefile~mips-lite +1 -1
diff -puN arch/mips/kernel/Makefile~mips-lite arch/mips/kernel/Makefile
@@ -48,7 +48,7 @@ obj-$(CONFIG_MIPS32_COMPAT)	+= ioctl32.o
 obj-$(CONFIG_MIPS32_N32)	+= binfmt_elfn32.o scall64-n32.o signal_n32.o
 obj-$(CONFIG_MIPS32_O32)	+= binfmt_elfo32.o scall64-o32.o ptrace32.o
 
-obj-$(CONFIG_KGDB)		+= gdb-low.o gdb-stub.o
+obj-$(CONFIG_KGDB)		+= kgdb_handler.o kgdb.o
 obj-$(CONFIG_PROC_FS)		+= proc.o
 
 obj-$(CONFIG_MIPS64)		+= cpu-bugs64.o
arch/mips/kernel/gdb-low.S deleted +0 -370

370 lines not on this page · raw message

arch/mips/kernel/gdb-stub.c deleted +0 -1089

1,089 lines not on this page · raw message

arch/mips/kernel/irq.c renamed from arch/mips/kernel/irq.c~mips-lite +3 -0
diff -puN arch/mips/kernel/irq.c~mips-lite arch/mips/kernel/irq.c
@@ -22,6 +22,7 @@
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/kallsyms.h>
+#include <linux/kgdb.h>
 
 #include <asm/atomic.h>
 #include <asm/system.h>
@@ -420,6 +421,8 @@ out:
 
 	irq_exit();
 
+	kgdb_process_breakpoint();
+
 	return 1;
 }
 
arch/mips/kernel/kgdb.c new file +292 -0

292 lines not on this page · raw message

arch/mips/kernel/kgdb_handler.S new file +58 -0

58 lines not on this page · raw message

arch/mips/kernel/traps.c renamed from arch/mips/kernel/traps.c~mips-lite +28 -1
diff -puN arch/mips/kernel/traps.c~mips-lite arch/mips/kernel/traps.c
@@ -10,6 +10,8 @@
  * Kevin D. Kissell, [email protected] and Carsten Langgaard, [email protected]
  * Copyright (C) 2000, 01 MIPS Technologies, Inc.
  * Copyright (C) 2002, 2003, 2004  Maciej W. Rozycki
+ *
+ * KGDB specific changes - Manish Lachwani ([email protected])
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -20,6 +22,7 @@
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 #include <linux/kallsyms.h>
+#include <linux/debugger.h>
 
 #include <asm/bootinfo.h>
 #include <asm/branch.h>
@@ -37,6 +40,7 @@
 #include <asm/mmu_context.h>
 #include <asm/watch.h>
 #include <asm/types.h>
+#include <asm/kdebug.h>
 
 extern asmlinkage void handle_mod(void);
 extern asmlinkage void handle_tlbl(void);
@@ -72,6 +76,21 @@ int (*board_be_handler)(struct pt_regs *
  */
 #define MODULE_RANGE (8*1024*1024)
 
+struct notifier_block *mips_die_chain;
+static spinlock_t die_notifier_lock = SPIN_LOCK_UNLOCKED;
+
+int register_die_notifier(struct notifier_block *nb)
+{
+	int err = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&die_notifier_lock, flags);
+	err = notifier_chain_register(&mips_die_chain, nb);
+	spin_unlock_irqrestore(&die_notifier_lock, flags);
+
+	return err;
+}
+
 /*
  * This routine abuses get_user()/put_user() to reference pointers
  * with at least a bit of error checking ...
@@ -265,8 +284,10 @@ NORET_TYPE void __die(const char * str, 
 void __die_if_kernel(const char * str, struct pt_regs * regs,
 		     const char * file, const char * func, unsigned long line)
 {
-	if (!user_mode(regs))
+	if (!user_mode(regs)) {
+		notify_die(DIE_TRAP, (char *)str, regs, 0);
 		__die(str, regs, file, func, line);
+	}
 }
 
 extern const struct exception_table_entry __start___dbe_table[];
@@ -921,6 +942,9 @@ void __init per_cpu_trap_init(void)
 	tlb_init();
 }
 
+/* Keep track of if we've done certain initialization already or not. */
+int kgdb_early_setup;
+
 void __init trap_init(void)
 {
 	extern char except_vec3_generic, except_vec3_r4000;
@@ -928,6 +952,9 @@ void __init trap_init(void)
 	extern char except_vec4;
 	unsigned long i;
 
+	if (kgdb_early_setup)
+		return;	/* Already done */
+
 	per_cpu_trap_init();
 
 	/*
arch/mips/mips-boards/generic/Makefile renamed from arch/mips/mips-boards/generic/Makefile~mips-lite +0 -1
diff -puN arch/mips/mips-boards/generic/Makefile~mips-lite arch/mips/mips-boards/generic/Makefile
@@ -21,6 +21,5 @@
 obj-y				:= mipsIRQ.o reset.o display.o init.o memory.o \
 				   printf.o cmdline.o time.o
 obj-$(CONFIG_PCI)		+= pci.o
-obj-$(CONFIG_KGDB)		+= gdb_hook.o
 
 EXTRA_AFLAGS := $(CFLAGS)
arch/mips/mips-boards/generic/init.c renamed from arch/mips/mips-boards/generic/init.c~mips-lite +0 -64

76 lines not on this page · raw message

arch/mips/mips-boards/malta/malta_int.c renamed from arch/mips/mips-boards/malta/malta_int.c~mips-lite +12 -13
diff -puN arch/mips/mips-boards/malta/malta_int.c~mips-lite arch/mips/mips-boards/malta/malta_int.c
@@ -40,12 +40,7 @@
 #include <asm/mips-boards/msc01_pci.h>
 
 extern asmlinkage void mipsIRQ(void);
-
-#ifdef CONFIG_KGDB
-extern void breakpoint(void);
-extern void set_debug_traps(void);
-extern int remote_debug;
-#endif
+extern int kgdb_early_setup;
 
 static spinlock_t mips_irq_lock = SPIN_LOCK_UNLOCKED;
 
@@ -189,16 +184,20 @@ void corehi_irqdispatch(struct pt_regs *
 
 void __init init_IRQ(void)
 {
+	if (kgdb_early_setup)
+		return;	/* Already done. */
 	set_except_vector(0, mipsIRQ);
 	init_generic_irq();
 	init_i8259_irqs();
+}
 
 #ifdef CONFIG_KGDB
-	if (remote_debug) {
-		set_debug_traps();
-		breakpoint();
-	}
-#endif
+void kgdb_mips_init(void)
+{
+	trap_init();
+	set_except_vector(0, mipsIRQ);
+	init_generic_irq();
+	init_i8259_irqs();
+	kgdb_early_setup = 1;
 }
-
-
+#endif
arch/mips/mips-boards/malta/malta_setup.c renamed from arch/mips/mips-boards/malta/malta_setup.c~mips-lite +0 -8
diff -puN arch/mips/mips-boards/malta/malta_setup.c~mips-lite arch/mips/mips-boards/malta/malta_setup.c
@@ -41,10 +41,6 @@ extern void mips_time_init(void);
 extern void mips_timer_setup(struct irqaction *irq);
 extern unsigned long mips_rtc_get_time(void);
 
-#ifdef CONFIG_KGDB
-extern void kgdb_config(void);
-#endif
-
 struct resource standard_io_resources[] = {
 	{ "dma1", 0x00, 0x1f, IORESOURCE_BUSY },
 	{ "timer", 0x40, 0x5f, IORESOURCE_BUSY },
@@ -93,10 +89,6 @@ static int __init malta_setup(void)
 	 */
 	enable_dma(4);
 
-#ifdef CONFIG_KGDB
-	kgdb_config ();
-#endif
-
 	if ((mips_revision_corid == MIPS_REVISION_CORID_BONITO64) ||
 	    (mips_revision_corid == MIPS_REVISION_CORID_CORE_20K) ||
 	    (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL_BON)) {
arch/mips/sibyte/cfe/setup.c renamed from arch/mips/sibyte/cfe/setup.c~mips-lite +0 -14
diff -puN arch/mips/sibyte/cfe/setup.c~mips-lite arch/mips/sibyte/cfe/setup.c
@@ -62,10 +62,6 @@ extern void * __rd_start, * __rd_end;
 static int reboot_smp = 0;
 #endif
 
-#ifdef CONFIG_KGDB
-extern int kgdb_port;
-#endif
-
 static void cfe_linux_exit(void)
 {
 #ifdef CONFIG_SMP
@@ -243,9 +239,6 @@ void __init prom_init(void)
 	int argc = fw_arg0;
 	char **envp = (char **) fw_arg2;
 	int *prom_vec = (int *) fw_arg3;
-#ifdef CONFIG_KGDB
-	char *arg;
-#endif
 
 	_machine_restart   = (void (*)(char *))cfe_linux_exit;
 	_machine_halt      = cfe_linux_exit;
@@ -309,13 +302,6 @@ void __init prom_init(void)
 		}
 	}
 
-#ifdef CONFIG_KGDB
-	if ((arg = strstr(arcs_cmdline,"kgdb=duart")) != NULL)
-		kgdb_port = (arg[10] == '0') ? 0 : 1;
-	else
-		kgdb_port = 1;
-#endif
-
 #ifdef CONFIG_BLK_DEV_INITRD
 	{
 		char *ptr;
arch/mips/sibyte/sb1250/Makefile renamed from arch/mips/sibyte/sb1250/Makefile~mips-lite +1 -0
diff -puN arch/mips/sibyte/sb1250/Makefile~mips-lite arch/mips/sibyte/sb1250/Makefile
@@ -4,5 +4,6 @@ obj-$(CONFIG_SMP)			+= smp.o
 obj-$(CONFIG_SIBYTE_TBPROF)		+= bcm1250_tbprof.o
 obj-$(CONFIG_SIBYTE_STANDALONE)		+= prom.o
 obj-$(CONFIG_SIBYTE_BUS_WATCHER)	+= bus_watcher.o
+obj-$(CONFIG_KGDB_SIBYTE)		+= kgdb_sibyte.o
 
 EXTRA_AFLAGS := $(CFLAGS)
arch/mips/sibyte/sb1250/irq.c renamed from arch/mips/sibyte/sb1250/irq.c~mips-lite +6 -66

88 lines not on this page · raw message

arch/mips/sibyte/sb1250/kgdb_sibyte.c new file +158 -0

158 lines not on this page · raw message

arch/mips/sibyte/swarm/Makefile renamed from arch/mips/sibyte/swarm/Makefile~mips-lite +0 -2
diff -puN arch/mips/sibyte/swarm/Makefile~mips-lite arch/mips/sibyte/swarm/Makefile
@@ -1,3 +1 @@
 lib-y				= setup.o rtc_xicor1241.o rtc_m41t81.o
-
-lib-$(CONFIG_KGDB)		+= dbg_io.o
arch/mips/sibyte/swarm/dbg_io.c deleted +0 -76

76 lines not on this page · raw message

include/asm-mips/kdebug.h new file +47 -0

47 lines not on this page · raw message

include/asm-mips/kgdb.h new file +20 -0
diff -puN /dev/null include/asm-mips/kgdb.h
@@ -0,0 +1,20 @@
+#ifndef _ASM_KGDB_H_
+#define _ASM_KGDB_H_
+
+#include <linux/config.h>
+
+#define BUFMAX			2048
+#define NUMREGBYTES		(90*sizeof(long))
+#define BREAK_INSTR_SIZE	4
+
+#define BREAKPOINT()		__asm__ __volatile__ (		\
+					".globl breakinst\n\t"	\
+					".set\tnoreorder\n\t"	\
+					"nop\n"			\
+					"breakinst:\tbreak\n\t"	\
+					"nop\n\t"		\
+					".set\treorder")
+
+#define CHECK_EXCEPTION_STACK() 	1
+
+#endif                         /* _ASM_KGDB_H_ */
lib/Kconfig.debug renamed from lib/Kconfig.debug~mips-lite +7 -2
diff -puN lib/Kconfig.debug~mips-lite lib/Kconfig.debug
@@ -115,7 +115,7 @@ endif
 
 config KGDB
 	bool "KGDB: kernel debugging with remote gdb"
-	depends on DEBUG_KERNEL && (X86 || ((!SMP || BROKEN) && (PPC32)))
+	depends on DEBUG_KERNEL && (X86 || MIPS32 || ((!SMP || BROKEN) && PPC32))
 	help
 	  If you say Y here, it will be possible to remotely debug the
 	  kernel using gdb. This enlarges your kernel image disk size by
@@ -128,6 +128,7 @@ config KGDB
 choice
 	prompt "Method for KGDB communication"
 	depends on KGDB
+	default KGDB_SIBYTE if SIBYTE_SB1xxx_SOC
 	default KGDB_8250
 	help
 	  There are a number of different ways in which you can communicate
@@ -140,6 +141,10 @@ config KGDB_8250
 	  Uses generic serial port (8250) for kgdb. This is independent of the
 	  option 9250/16550 and compatible serial port.
 
+config KGDB_SIBYTE
+	bool "KGDB: On the Broadcom SWARM serial port"
+	depends on MIPS && SIBYTE_SB1xxx_SOC
+
 endchoice
 
 config KGDB_SIMPLE_SERIAL
@@ -153,7 +158,7 @@ config KGDB_SIMPLE_SERIAL
 	  If in doubt, say Y.
 
 choice
-	depends on KGDB_8250
+	depends on KGDB_8250 || KGDB_SIBYTE
     	prompt "Debug serial port BAUD"
 	default KGDB_115200BAUD
 	help

_

author
#5 lore raw

PATCH 6/8 KGDB support for ia64

Cc: David Mosberger-Tang <[email protected]>, Robert Picco <[email protected]>, Keldon Jones <[email protected]> This adds support for KGDB to ia64 and was done by Robert Picco and Keldon
Jones.

---

 linux-2.6.10-rc1-trini/arch/ia64/kernel/Makefile  |    1 
 linux-2.6.10-rc1-trini/arch/ia64/kernel/irq.c     |    4 
 linux-2.6.10-rc1-trini/arch/ia64/kernel/ivt.S     |   17 
 linux-2.6.10-rc1-trini/arch/ia64/kernel/kgdb.c    |  991 ++++++++++++++++++++++
 linux-2.6.10-rc1-trini/arch/ia64/kernel/process.c |    6 
 linux-2.6.10-rc1-trini/arch/ia64/kernel/smp.c     |   17 
 linux-2.6.10-rc1-trini/arch/ia64/kernel/traps.c   |   26 
 linux-2.6.10-rc1-trini/arch/ia64/kernel/unwind.c  |   61 +
 linux-2.6.10-rc1-trini/arch/ia64/mm/fault.c       |    3 
 linux-2.6.10-rc1-trini/drivers/firmware/pcdp.c    |   19 
 linux-2.6.10-rc1-trini/include/asm-ia64/kgdb.h    |   34 
 linux-2.6.10-rc1-trini/lib/Kconfig.debug          |    2 
 12 files changed, 1179 insertions(+), 2 deletions(-)
arch/ia64/kernel/Makefile renamed from arch/ia64/kernel/Makefile~ia64-lite +1 -0
diff -puN arch/ia64/kernel/Makefile~ia64-lite arch/ia64/kernel/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_PERFMON)		+= perfmon_defaul
 obj-$(CONFIG_IA64_CYCLONE)	+= cyclone.o
 obj-$(CONFIG_IA64_MCA_RECOVERY)	+= mca_recovery.o
 mca_recovery-y			+= mca_drv.o mca_drv_asm.o
+obj-$(CONFIG_KGDB)		+= kgdb.o
 
 # The gate DSO image is built using a special linker script.
 targets += gate.so gate-syms.o
arch/ia64/kernel/irq.c renamed from arch/ia64/kernel/irq.c~ia64-lite +4 -0
diff -puN arch/ia64/kernel/irq.c~ia64-lite arch/ia64/kernel/irq.c
@@ -42,6 +42,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/kallsyms.h>
+#include <linux/kgdb.h>
 #include <linux/notifier.h>
 #include <linux/bitops.h>
 
@@ -543,6 +544,9 @@ unsigned int do_IRQ(unsigned long irq, s
 		desc->handler->end(irq);
 		spin_unlock(&desc->lock);
 	}
+
+	kgdb_process_breakpoint();
+
 	return 1;
 }
 
arch/ia64/kernel/ivt.S renamed from arch/ia64/kernel/ivt.S~ia64-lite +17 -0
diff -puN arch/ia64/kernel/ivt.S~ia64-lite arch/ia64/kernel/ivt.S
@@ -68,6 +68,13 @@
 # define DBG_FAULT(i)
 #endif
 
+#ifdef	CONFIG_KGDB
+#define	KGDB_ENABLE_PSR_DB mov r31=psr;; movl r30=IA64_PSR_DB;; or r31=r31,r30;; \
+		mov psr.l=r31;; srlz.i;;
+#else
+#define	KGDB_ENABLE_PSR_DB
+#endif
+
 #define MINSTATE_VIRT	/* needed by minstate.h */
 #include "minstate.h"
 
@@ -473,6 +480,7 @@ ENTRY(page_fault)
 	movl r14=ia64_leave_kernel
 	;;
 	SAVE_REST
+	KGDB_ENABLE_PSR_DB
 	mov rp=r14
 	;;
 	adds out2=16,r12			// out2 = pointer to pt_regs
@@ -733,6 +741,8 @@ ENTRY(break_fault)
 	;;
 	srlz.i					// guarantee that interruption collection is on
 	;;
+	KGDB_ENABLE_PSR_DB
+	;;
 (p15)	ssm psr.i				// restore psr.i
 	;;
 	mov r3=NR_syscalls - 1
@@ -776,6 +786,7 @@ ENTRY(interrupt)
 	srlz.i			// ensure everybody knows psr.ic is back on
 	;;
 	SAVE_REST
+	KGDB_ENABLE_PSR_DB
 	;;
 	alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
 	mov out0=cr.ivr		// pass cr.ivr as first arg
@@ -1003,6 +1014,7 @@ ENTRY(non_syscall)
 	movl r15=ia64_leave_kernel
 	;;
 	SAVE_REST
+	KGDB_ENABLE_PSR_DB
 	mov rp=r15
 	;;
 	br.call.sptk.many b6=ia64_bad_break	// avoid WAW on CFM and ignore return addr
@@ -1036,6 +1048,7 @@ ENTRY(dispatch_unaligned_handler)
 	adds r3=8,r2				// set up second base pointer
 	;;
 	SAVE_REST
+	KGDB_ENABLE_PSR_DB
 	movl r14=ia64_leave_kernel
 	;;
 	mov rp=r14
@@ -1078,6 +1091,10 @@ ENTRY(dispatch_to_fault_handler)
 	adds r3=8,r2				// set up second base pointer for SAVE_REST
 	;;
 	SAVE_REST
+	cmp.eq p6,p0=29,out0
+(p6)	br.cond.spnt 1f;;			// debug_vector
+	KGDB_ENABLE_PSR_DB
+1:
 	movl r14=ia64_leave_kernel
 	;;
 	mov rp=r14
arch/ia64/kernel/kgdb.c new file +991 -0

991 lines not on this page · raw message

arch/ia64/kernel/process.c renamed from arch/ia64/kernel/process.c~ia64-lite +6 -0
diff -puN arch/ia64/kernel/process.c~ia64-lite arch/ia64/kernel/process.c
@@ -415,6 +415,9 @@ copy_thread (int nr, unsigned long clone
 	 */
 	child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET)
 				 & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_PP | IA64_PSR_UP));
+#ifdef	CONFIG_KGDB
+	child_ptregs->cr_ipsr |= IA64_PSR_DB;
+#endif
 
 	/*
 	 * NOTE: The calling convention considers all floating point
@@ -643,6 +646,9 @@ kernel_thread (int (*fn)(void *), void *
 	regs.pt.r11 = (unsigned long) arg;	/* 2nd argument */
 	/* Preserve PSR bits, except for bits 32-34 and 37-45, which we can't read.  */
 	regs.pt.cr_ipsr = ia64_getreg(_IA64_REG_PSR) | IA64_PSR_BN;
+#ifdef	CONFIG_KGDB
+	regs.pt.cr_ipsr |= IA64_PSR_DB;
+#endif
 	regs.pt.cr_ifs = 1UL << 63;		/* mark as valid, empty frame */
 	regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR);
 	regs.sw.ar_bspstore = (unsigned long) current + IA64_RBS_OFFSET;
arch/ia64/kernel/smp.c renamed from arch/ia64/kernel/smp.c~ia64-lite +17 -0
diff -puN arch/ia64/kernel/smp.c~ia64-lite arch/ia64/kernel/smp.c
@@ -47,6 +47,7 @@
 #include <asm/tlbflush.h>
 #include <asm/unistd.h>
 #include <asm/mca.h>
+#include <linux/kgdb.h>
 
 /*
  * Structure and data for smp_call_function(). This is designed to minimise static memory
@@ -66,6 +67,9 @@ static volatile struct call_data_struct 
 
 #define IPI_CALL_FUNC		0
 #define IPI_CPU_STOP		1
+#ifdef	CONFIG_KGDB
+#define	IPI_KGDB_INTERRUPT	2
+#endif
 
 /* This needs to be cacheline aligned because it is written to by *other* CPUs.  */
 static DEFINE_PER_CPU(u64, ipi_operation) ____cacheline_aligned;
@@ -155,6 +159,11 @@ handle_IPI (int irq, void *dev_id, struc
 			      case IPI_CPU_STOP:
 				stop_this_cpu();
 				break;
+#ifdef	CONFIG_KGDB
+			      case IPI_KGDB_INTERRUPT:
+				kgdb_wait_ipi(regs);
+				break;
+#endif
 
 			      default:
 				printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which);
@@ -303,6 +312,14 @@ smp_call_function_single (int cpuid, voi
 }
 EXPORT_SYMBOL(smp_call_function_single);
 
+#ifdef	CONFIG_KGDB
+void
+smp_send_nmi_allbutself(void)
+{
+	send_IPI_allbutself(IPI_KGDB_INTERRUPT);
+}
+#endif
+
 /*
  * this function sends a 'generic call function' IPI to all other CPUs
  * in the system.
arch/ia64/kernel/traps.c renamed from arch/ia64/kernel/traps.c~ia64-lite +25 -1
diff -puN arch/ia64/kernel/traps.c~ia64-lite arch/ia64/kernel/traps.c
@@ -15,6 +15,7 @@
 #include <linux/vt_kern.h>		/* For unblank_screen() */
 #include <linux/module.h>       /* for EXPORT_SYMBOL */
 #include <linux/hardirq.h>
+#include <linux/kgdb.h>
 
 #include <asm/fpswa.h>
 #include <asm/ia32.h>
@@ -92,6 +93,8 @@ die (const char *str, struct pt_regs *re
   	} else
 		printk(KERN_ERR "Recursive die() failure, output suppressed\n");
 
+	CHK_DEBUGGER(1, SIGTRAP, err, regs,);
+
 	bust_spinlocks(0);
 	die.lock_owner = -1;
 	spin_unlock_irq(&die.lock);
@@ -119,7 +122,9 @@ ia64_bad_break (unsigned long break_num,
 
 	switch (break_num) {
 	      case 0: /* unknown error (used by GCC for __builtin_abort()) */
+#ifndef	CONFIG_KGDB
 		die_if_kernel("bugcheck!", regs, break_num);
+#endif
 		sig = SIGILL; code = ILL_ILLOPC;
 		break;
 
@@ -172,8 +177,10 @@ ia64_bad_break (unsigned long break_num,
 		break;
 
 	      default:
+#ifndef	CONFIG_KGDB
 		if (break_num < 0x40000 || break_num > 0x100000)
 			die_if_kernel("Bad break", regs, break_num);
+#endif
 
 		if (break_num < 0x80000) {
 			sig = SIGILL; code = __ILL_BREAK;
@@ -181,6 +188,13 @@ ia64_bad_break (unsigned long break_num,
 			sig = SIGTRAP; code = TRAP_BRKPT;
 		}
 	}
+#ifdef	CONFIG_KGDB
+	/*
+	 * We don't want to trap simulator system calls.
+	 */
+	if (break_num != 0x80001)
+		CHK_DEBUGGER(11, sig, break_num, regs, return);
+#endif
 	siginfo.si_signo = sig;
 	siginfo.si_errno = 0;
 	siginfo.si_code = code;
@@ -487,9 +501,18 @@ ia64_fault (unsigned long vector, unsign
 		sprintf(buf, "Unsupported data reference");
 		break;
 
+	      case 36: /* Single Step Trap */
+#ifdef	CONFIG_KGDB
+		if (linux_debug_hook != (gdb_debug_hook *) NULL && !user_mode(regs) &&
+			kgdb_hwbreak_sstep[smp_processor_id()]) {
+			kgdb_hwbreak_sstep[smp_processor_id()] = 0;
+			regs->cr_ipsr &= ~IA64_PSR_SS;
+			return;
+		}
+#endif
 	      case 29: /* Debug */
+		CHK_DEBUGGER(vector, SIGTRAP, isr, regs, return);
 	      case 35: /* Taken Branch Trap */
-	      case 36: /* Single Step Trap */
 		if (fsys_mode(current, regs)) {
 			extern char __kernel_syscall_via_break[];
 			/*
@@ -604,6 +627,7 @@ ia64_fault (unsigned long vector, unsign
 		sprintf(buf, "Fault %lu", vector);
 		break;
 	}
+	CHK_DEBUGGER(vector, SIGTRAP, isr, regs,);
 	die_if_kernel(buf, regs, error);
 	force_sig(SIGILL, current);
 }
arch/ia64/kernel/unwind.c renamed from arch/ia64/kernel/unwind.c~ia64-lite +61 -0

77 lines not on this page · raw message

arch/ia64/mm/fault.c renamed from arch/ia64/mm/fault.c~ia64-lite +3 -0
diff -puN arch/ia64/mm/fault.c~ia64-lite arch/ia64/mm/fault.c
@@ -9,6 +9,7 @@
 #include <linux/mm.h>
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
+#include <linux/kgdb.h>
 
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -232,6 +233,8 @@ ia64_do_page_fault (unsigned long addres
 	 */
 	bust_spinlocks(1);
 
+	CHK_DEBUGGER(14, SIGSEGV, isr, regs,);
+
 	if (address < PAGE_SIZE)
 		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference (address %016lx)\n", address);
 	else
drivers/firmware/pcdp.c renamed from drivers/firmware/pcdp.c~ia64-lite +19 -0
diff -puN drivers/firmware/pcdp.c~ia64-lite drivers/firmware/pcdp.c
@@ -56,7 +56,11 @@ uart_edge_level(int rev, struct pcdp_uar
 }
 
 static void __init
+#ifndef	CONFIG_KGDB
 setup_serial_console(int rev, struct pcdp_uart *uart)
+#else
+setup_serial_console(int rev, struct pcdp_uart *uart, int line)
+#endif
 {
 #ifdef CONFIG_SERIAL_8250_CONSOLE
 	struct uart_port port;
@@ -64,6 +68,9 @@ setup_serial_console(int rev, struct pcd
 	int mapsize = 64;
 
 	memset(&port, 0, sizeof(port));
+#ifdef	CONFIG_KGDB
+	port.line = line;
+#endif
 	port.uartclk = uart->clock_rate;
 	if (!port.uartclk)	/* some FW doesn't supply this */
 		port.uartclk = BASE_BAUD * 16;
@@ -110,6 +117,9 @@ setup_serial_console(int rev, struct pcd
 
 	snprintf(options, sizeof(options), "%lun%d", uart->baud,
 		uart->bits ? uart->bits : 8);
+#ifdef	CONFIG_KGDB
+	if (!line)
+#endif
 	add_preferred_console("ttyS", port.line, options);
 
 	printk(KERN_INFO "PCDP: serial console at %s 0x%lx (ttyS%d, options %s)\n",
@@ -156,10 +166,19 @@ efi_setup_pcdp_console(char *cmdline)
 	for (i = 0, uart = pcdp->uart; i < pcdp->num_uarts; i++, uart++) {
 		if (uart->flags & PCDP_UART_PRIMARY_CONSOLE || serial) {
 			if (uart->type == PCDP_CONSOLE_UART) {
+#ifndef	CONFIG_KGDB
 				setup_serial_console(pcdp->rev, uart);
 				return;
+#else
+				setup_serial_console(pcdp->rev, uart, 0);
+				serial = 0;
+#endif
 			}
 		}
+#ifdef	CONFIG_KGDB
+		else if (uart->type == PCDP_DEBUG_UART)
+				setup_serial_console(pcdp->rev, uart, 1);
+#endif
 	}
 
 	end = (struct pcdp_device *) ((u8 *) pcdp + pcdp->length);
include/asm-ia64/kgdb.h new file +34 -0
diff -puN /dev/null include/asm-ia64/kgdb.h
@@ -0,0 +1,34 @@
+#ifndef _ASM_KGDB_H_
+#define _ASM_KGDB_H_
+
+/*
+ * Copyright (C) 2001-2004 Amit S. Kale
+ */
+
+#include <linux/ptrace.h>
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+/* Longer buffer is needed to list all threads */
+#define BUFMAX 1024
+
+/* Number of bytes of registers.  */
+#define NUMREGBYTES 0
+
+#define BREAKNUM        0x00003333300LL
+#define KGDBBREAKNUM    0x6665UL
+
+extern volatile int kgdb_hwbreak_sstep[NR_CPUS];
+
+#define BREAKPOINT() asm volatile ("break.m 0x6665")
+#define BREAK_INSTR_SIZE       16
+
+#define CHECK_EXCEPTION_STACK() 	1
+
+#define	SERIAL_PORT_DFNS	{0,}, {0,}, {0,}, {0,}
+
+extern void smp_send_nmi_allbutself(void);
+extern void kgdb_wait_ipi(struct pt_regs *);
+
+#endif				/* _ASM_KGDB_H_ */
lib/Kconfig.debug renamed from lib/Kconfig.debug~ia64-lite +1 -1
diff -puN lib/Kconfig.debug~ia64-lite lib/Kconfig.debug
@@ -115,7 +115,7 @@ endif
 
 config KGDB
 	bool "KGDB: kernel debugging with remote gdb"
-	depends on DEBUG_KERNEL && (X86 || MIPS32 || ((!SMP || BROKEN) && PPC32))
+	depends on DEBUG_KERNEL && (X86 || MIPS32 || IA64 || ((!SMP || BROKEN) && PPC32))
 	help
 	  If you say Y here, it will be possible to remotely debug the
 	  kernel using gdb. This enlarges your kernel image disk size by

_

author
#6 lore raw

PATCH 7/8 KGDB support for x86_64

Cc: Andi Kleen <[email protected]>
This adds KGDB support for x86_64.

---

 linux-2.6.10-rc1-trini/arch/x86_64/Kconfig.debug   |    3 
 linux-2.6.10-rc1-trini/arch/x86_64/kernel/Makefile |    3 
 linux-2.6.10-rc1-trini/arch/x86_64/kernel/irq.c    |    8 
 linux-2.6.10-rc1-trini/arch/x86_64/kernel/kgdb.c   |  448 +++++++++++++++++++++
 linux-2.6.10-rc1-trini/arch/x86_64/kernel/traps.c  |    3 
 linux-2.6.10-rc1-trini/include/asm-x86_64/kgdb.h   |   56 ++
 linux-2.6.10-rc1-trini/lib/Kconfig.debug           |    2 
 7 files changed, 518 insertions(+), 5 deletions(-)
arch/x86_64/Kconfig.debug renamed from arch/x86_64/Kconfig.debug~x86_64-lite +0 -3
diff -puN arch/x86_64/Kconfig.debug~x86_64-lite arch/x86_64/Kconfig.debug
@@ -41,7 +41,4 @@ config IOMMU_LEAK
          Add a simple leak tracer to the IOMMU code. This is useful when you
 	 are debugging a buggy device driver that leaks IOMMU mappings.
 
-#config X86_REMOTE_DEBUG
-#       bool "kgdb debugging stub"
-
 endmenu
arch/x86_64/kernel/Makefile renamed from arch/x86_64/kernel/Makefile~x86_64-lite +3 -0
diff -puN arch/x86_64/kernel/Makefile~x86_64-lite arch/x86_64/kernel/Makefile
@@ -10,6 +10,8 @@ obj-y	:= process.o semaphore.o signal.o 
 		setup64.o bootflag.o e820.o reboot.o warmreboot.o
 obj-y += mce.o
 
+CFLAGS_vsyscall.o := -g0
+
 obj-$(CONFIG_MTRR)		+= ../../i386/kernel/cpu/mtrr/
 obj-$(CONFIG_ACPI_BOOT)		+= acpi/
 obj-$(CONFIG_X86_MSR)		+= msr.o
@@ -27,6 +29,7 @@ obj-$(CONFIG_DUMMY_IOMMU)	+= pci-nommu.o
 obj-$(CONFIG_SWIOTLB)		+= swiotlb.o
 
 obj-$(CONFIG_MODULES)		+= module.o
+obj-$(CONFIG_KGDB)		+= kgdb.o
 
 obj-y				+= topology.o
 obj-y				+= intel_cacheinfo.o
arch/x86_64/kernel/irq.c renamed from arch/x86_64/kernel/irq.c~x86_64-lite +8 -0
diff -puN arch/x86_64/kernel/irq.c~x86_64-lite arch/x86_64/kernel/irq.c
@@ -14,6 +14,7 @@
 #include <linux/interrupt.h>
 #include <linux/seq_file.h>
 #include <linux/module.h>
+#include <linux/kgdb.h>
 #include <asm/uaccess.h>
 #include <asm/io_apic.h>
 
@@ -103,6 +104,13 @@ asmlinkage unsigned int do_IRQ(struct pt
 	__do_IRQ(irq, regs);
 	irq_exit();
 
+	/*
+	 * Do not call breakpoint as on the x86_64 architecture if the
+	 * exception tables are not set.
+	 */
+	if(CHECK_EXCEPTION_STACK())
+		kgdb_process_breakpoint();
+
 	return 1;
 }
 
arch/x86_64/kernel/kgdb.c new file +448 -0

448 lines not on this page · raw message

arch/x86_64/kernel/traps.c renamed from arch/x86_64/kernel/traps.c~x86_64-lite +2 -1
diff -puN arch/x86_64/kernel/traps.c~x86_64-lite arch/x86_64/kernel/traps.c
@@ -28,6 +28,7 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/debugger.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -642,7 +643,7 @@ asmlinkage void *do_debug(struct pt_regs
 	tsk->thread.debugreg6 = condition;
 
 	/* Mask out spurious TF errors due to lazy TF clearing */
-	if (condition & DR_STEP) {
+	if (condition & DR_STEP && !debugger_step) {
 		/*
 		 * The TF error should be masked out only if the current
 		 * process is not traced and if the TRAP flag has been set
include/asm-x86_64/kgdb.h new file +56 -0

56 lines not on this page · raw message

lib/Kconfig.debug renamed from lib/Kconfig.debug~x86_64-lite +1 -1
diff -puN lib/Kconfig.debug~x86_64-lite lib/Kconfig.debug
@@ -115,7 +115,7 @@ endif
 
 config KGDB
 	bool "KGDB: kernel debugging with remote gdb"
-	depends on DEBUG_KERNEL && (X86 || MIPS32 || IA64 || ((!SMP || BROKEN) && PPC32))
+	depends on DEBUG_KERNEL && (X86 || MIPS32 || IA64 || X86_64 || ((!SMP || BROKEN) && PPC32))
 	help
 	  If you say Y here, it will be possible to remotely debug the
 	  kernel using gdb. This enlarges your kernel image disk size by

_

author
#7 lore raw

PATCH 8/8 KGDB over ethernet driver

Cc: Jeff Garzik <[email protected]>, Matt Mackall <[email protected]> This adds a KGDB over ethernet driver that makes use of the netpoll API to function.

---

 linux-2.6.10-rc1-trini/drivers/net/Makefile   |    1 
 linux-2.6.10-rc1-trini/drivers/net/kgdb_eth.c |  132 ++++++++++++++++++++++++++
 linux-2.6.10-rc1-trini/kernel/kgdb.c          |    9 +
 linux-2.6.10-rc1-trini/lib/Kconfig.debug      |    8 +
 4 files changed, 150 insertions(+)
drivers/net/Makefile renamed from drivers/net/Makefile~eth +1 -0
diff -puN drivers/net/Makefile~eth drivers/net/Makefile
@@ -196,3 +196,4 @@ obj-$(CONFIG_HAMRADIO) += hamradio/
 obj-$(CONFIG_IRDA) += irda/
 
 obj-$(CONFIG_NETCONSOLE) += netconsole.o
+obj-$(CONFIG_KGDB_ETH) += kgdb_eth.o
drivers/net/kgdb_eth.c new file +132 -0

132 lines not on this page · raw message

kernel/kgdb.c renamed from kernel/kgdb.c~eth +9 -0
diff -puN kernel/kgdb.c~eth kernel/kgdb.c
@@ -52,6 +52,7 @@
 #include <asm/cacheflush.h>
 #include <linux/init.h>
 #include <linux/sysrq.h>
+#include <linux/netpoll.h>
 
 extern int pid_max;
 extern int pidhash_init_done;
@@ -730,6 +731,10 @@ int kgdb_handle_exception(int exVector, 
 
 acquirelock:
 
+#ifdef CONFIG_KGDB_ETH
+	netpoll_set_trap(1);
+#endif
+
 	/*
 	 * Interrupts will be restored by the 'trap return' code, except when
 	 * single stepping.
@@ -1144,6 +1149,10 @@ acquirelock:
 	}
 
       kgdb_exit:
+#ifdef CONFIG_KGDB_ETH
+	netpoll_set_trap(0);
+#endif
+
 	kgdb_info[processor].debuggerinfo = NULL;
 	kgdb_info[processor].task = NULL;
 	procindebug[smp_processor_id()] = 0;
lib/Kconfig.debug renamed from lib/Kconfig.debug~eth +8 -0
diff -puN lib/Kconfig.debug~eth lib/Kconfig.debug
@@ -145,6 +145,14 @@ config KGDB_SIBYTE
 	bool "KGDB: On the Broadcom SWARM serial port"
 	depends on MIPS && SIBYTE_SB1xxx_SOC
 
+config KGDB_ETH
+	bool "KGDB: On ethernet"
+	select NETPOLL
+	select NETPOLL_TRAP
+	select NETPOLL_RX
+	help
+	  Uses ethernet interface for kgdb.
+
 endchoice
 
 config KGDB_SIMPLE_SERIAL

_

#8 lore raw

Re: [patch 7/8] KGDB support for x86_64

In reply to Tom Rini
Quoted 3 lines · Tom Rini

Cc: Andi Kleen <[email protected]>
This adds KGDB support for x86_64.

Can you please explain what the additional hooks are good for?

arch/x86_64/kernel/Makefile obj-y := process.o semaphore.o signal.o · line 14

Quoted 7 lines

+++ linux-2.6.10-rc1-trini/arch/x86_64/kernel/Makefile 2004-10-29 11:26:45.757144605 -0700

arch/x86_64/kernel/Makefile renamed from arch/x86_64/kernel/Makefile~x86_64-lite +2 -0
@@ -10,6 +10,8 @@ obj-y	:= process.o semaphore.o signal.o 
 		setup64.o bootflag.o e820.o reboot.o warmreboot.o
 obj-y += mce.o
 
+CFLAGS_vsyscall.o := -g0
+

What's this?

Quoted 5 lines
arch/x86_64/kernel/irq.c renamed from arch/x86_64/kernel/irq.c~x86_64-lite +1 -0
+#include <linux/kgdb.h>
 #include <asm/uaccess.h>
 #include <asm/io_apic.h>

arch/x86_64/kernel/irq.c asmlinkage unsigned int do_IRQ(struct pt · line 113

Quoted 10 lines
arch/x86_64/kernel/irq.c renamed from arch/x86_64/kernel/irq.c~x86_64-lite +7 -0
@@ -103,6 +104,13 @@ asmlinkage unsigned int do_IRQ(struct pt
 	__do_IRQ(irq, regs);
 	irq_exit();
 
+	/*
+	 * Do not call breakpoint as on the x86_64 architecture if the
+	 * exception tables are not set.
+	 */
+	if(CHECK_EXCEPTION_STACK())
+		kgdb_process_breakpoint();
+

And that? Why do you need to check breakpoints in interrupts?

arch/x86_64/kernel/traps.c asmlinkage void *do_debug(struct pt_regs · line 646

Quoted 11 lines
arch/x86_64/kernel/traps.c renamed from arch/x86_64/kernel/traps.c~x86_64-lite +2 -1
 #include <linux/moduleparam.h>
+#include <linux/debugger.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -642,7 +643,7 @@ asmlinkage void *do_debug(struct pt_regs
 	tsk->thread.debugreg6 = condition;
 
 	/* Mask out spurious TF errors due to lazy TF clearing */
-	if (condition & DR_STEP) {
+	if (condition & DR_STEP && !debugger_step) {

This also looks bogus. What is this exactly for and why is it not handled through the debug chain?

-Andi

author
#9 lore raw

Re: [patch 3/8] KGDB support for ppc32

In reply to Tom Rini
Quoted 6 lines · Tom Rini

Cc: Matt Porter <[email protected]>
This adds KGDB support for ppc32 and was done by myself. Note that this currently doesn't work on 40x || BOOKE, but that problem is more generic (the current ppc stub doesn't work either) and Matt Porter is close to having a tested solution now.

As Matt has posted his work which makes KGDB functional again, the following small patch is needed on top of this to make 40x || BOOKE work with this stub.

 linux-2.6.10-rc1/arch/ppc/kernel/kgdb.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
arch/ppc/kernel/kgdb.c +2 -2
@@ -54,7 +54,7 @@
 	{ 0x0d00, 0x04 /* SIGILL */  },		/* reserved */
 	{ 0x0e00, 0x04 /* SIGILL */  },		/* reserved */
 	{ 0x0f00, 0x04 /* SIGILL */  },		/* reserved */
-	{ 0x2000, 0x05 /* SIGTRAP */},		/* debug */
+	{ 0x2002, 0x05 /* SIGTRAP */},		/* debug */
 #else
 	{ 0x0200, 0x0b /* SIGSEGV */ },		/* machine check */
 	{ 0x0300, 0x0b /* SIGSEGV */ },		/* address error (store) */
@@ -240,8 +240,8 @@
 			if (remcom_in_buffer[0] == 's')
 			{
 #if defined (CONFIG_40x) || defined(CONFIG_BOOKE)
+				mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC);
 				linux_regs->msr |= MSR_DE;
-				current->thread.dbcr0 |= (DBCR0_IDM | DBCR0_IC);
 #else
 				linux_regs->msr |= MSR_SE;
 #endif
Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
author
#10 lore raw
In reply to Tom Rini
Quoted 4 lines · Tom Rini

Cc: <[email protected]>, <[email protected]>
The following series of patches adds (or in some cases, replaces) KGDB support for i386, ppc32, ia64, x86_64 and mips (both 32 and 64bit tested). This version of KGDB can be used either via serial or ethernet.

... Not off to a good start today, forgot to refresh the descs one last time before sending. Only this and I think 2/8 will go out twice, sorry for the noise.

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
author
#11 lore raw
In reply to Tom Rini
Quoted 4 lines

diff -puN kernel/sched.c~core-lite kernel/sched.c

kernel/sched.c renamed from kernel/sched.c~core-lite +0 -0

[snip]

kernel/sched.c void __might_sleep(char *file, int line) · line 4579

Quoted 13 lines
kernel/sched.c renamed from kernel/sched.c~core-lite +6 -0
@@ -4567,6 +4568,12 @@ void __might_sleep(char *file, int line)
 #if defined(in_atomic)
 	static unsigned long prev_jiffy;	/* ratelimiting */
 
+	if (atomic_read(&debugger_active))
+		return;
+
+	if (atomic_read(&debugger_active))
+		return;
+
 	if ((in_atomic() || irqs_disabled()) &&
 	    system_state == SYSTEM_RUNNING) {
 		if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)

Olaf Hering pointed this out to me privately. Obvious patch follows.

(And, er, I fogot this on all of the other patches too, as I said, not a good start to the day...)

kernel/sched.c +0 -3
diff -u linux-2.6.10-rc1/kernel/sched.c linux-2.6.10-rc1/kernel/sched.c
@@ -4571,9 +4571,6 @@
 	if (atomic_read(&debugger_active))
 		return;
 
-	if (atomic_read(&debugger_active))
-		return;
-
 	if ((in_atomic() || irqs_disabled()) &&
 	    system_state == SYSTEM_RUNNING) {
 		if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/