Skip to contentSkip to conversation

A different KGDB stub

PATCH In review Tom Rini 1 participant 1 message Feb 12, 2004

lore
Share & tools
lore

Tom Rini

author
#0 lore raw

PATCH 6/6 A different KGDB stub

The following is the x86_64-specific bits to this KGDB stub.

 arch/x86_64/Kconfig              |    5 
 arch/x86_64/kernel/Makefile      |    1 
 arch/x86_64/kernel/entry.S       |   41 ++-
 arch/x86_64/kernel/irq.c         |    2 
 arch/x86_64/kernel/nmi.c         |   16 +
 arch/x86_64/kernel/traps.c       |    6 
 arch/x86_64/kernel/x86_64-stub.c |  523 +++++++++++++++++++++++++++++++++++++++
 arch/x86_64/mm/fault.c           |    8 
 include/asm-x86_64/dwarf2.h      |    2 
 include/asm-x86_64/kgdb.h        |   57 ++++
 include/asm-x86_64/processor.h   |    1 
 include/asm-x86_64/system.h      |   50 +++
 12 files changed, 703 insertions(+), 9 deletions(-)
arch/x86_64/Kconfig +1 -4
@@ -463,10 +463,7 @@
          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
+source "kernel/Kconfig.kgdb"
 
 source "security/Kconfig"
 
arch/x86_64/kernel/Makefile +1 -0
@@ -24,6 +24,7 @@
 obj-$(CONFIG_DUMMY_IOMMU)	+= pci-nommu.o pci-dma.o
 
 obj-$(CONFIG_MODULES)		+= module.o
+obj-$(CONFIG_KGDB)		+= x86_64-stub.o
 
 obj-y				+= topology.o
 
arch/x86_64/kernel/entry.S +38 -3

62 lines not on this page · raw message

arch/x86_64/kernel/irq.c +2 -0
@@ -405,6 +405,8 @@
 	spin_unlock(&desc->lock);
 
 	irq_exit();
+
+	kgdb_process_breakpoint();
 	return 1;
 }
 
arch/x86_64/kernel/nmi.c +15 -1
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/sysdev.h>
 #include <linux/nmi.h>
+#include <linux/debugger.h>
 
 #include <asm/smp.h>
 #include <asm/mtrr.h>
@@ -317,13 +318,26 @@
 		return;
 
 	sum = read_pda(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 ...
 		 */
 		alert_counter[cpu]++;
 		if (alert_counter[cpu] == 5*nmi_hz) {
+
+			CHK_DEBUGGER(2,SIGSEGV,0,regs,)
+
 			if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_BAD) { 
 				alert_counter[cpu] = 0; 
 				return;
arch/x86_64/kernel/traps.c +5 -1
@@ -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>
@@ -363,6 +364,7 @@
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
+	CHK_DEBUGGER(1,SIGTRAP,err,regs,)
 	oops_begin();
 	handle_BUG(regs);
 	__die(str, regs, err);
@@ -436,6 +438,7 @@
 #define DO_ERROR(trapnr, signr, str, name) \
 asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
 { \
+	CHK_DEBUGGER(1,SIGTRAP,error_code,regs,return) \
 	if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) == NOTIFY_BAD) \
 		return; \
 	do_trap(trapnr, signr, str, regs, error_code, NULL); \
@@ -614,7 +617,7 @@
 	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
@@ -643,6 +646,7 @@
 	force_sig_info(SIGTRAP, &info, tsk);	
 clear_dr7:
 	asm volatile("movq %0,%%db7"::"r"(0UL));
+	CHK_DEBUGGER(1,SIGTRAP,error_code,regs,return)
 	notify_die(DIE_DEBUG, "debug", regs, error_code, 1, SIGTRAP);
 	return;
 
arch/x86_64/kernel/x86_64-stub.c new file +523 -0

523 lines not on this page · raw message

arch/x86_64/mm/fault.c +8 -0
@@ -23,6 +23,7 @@
 #include <linux/vt_kern.h>		/* For unblank_screen() */
 #include <linux/compiler.h>
 #include <linux/module.h>
+#include <linux/debugger.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -290,6 +291,11 @@
 		return;
 
  again:
+	if (debugger_memerr_expected) {
+		/* This fault was caused by memory access through a debugger.
+		 * Don't handle it like user accesses */
+		goto no_context;
+	}
 	down_read(&mm->mmap_sem);
 
 	vma = find_vma(mm, address);
@@ -410,6 +416,8 @@
 
 	if (is_errata93(regs, address))
 		return; 
+
+	CHK_DEBUGGER(14, SIGSEGV,error_code, regs,)
 
 /*
  * Oops. The kernel tried to access some bad page. We'll have to
include/asm-x86_64/dwarf2.h +2 -0
@@ -12,6 +12,8 @@
    See "as.info" for details on these pseudo ops. Unfortunately 
    they are only supported in very new binutils, so define them 
    away for older version. 
+
+   If you want to build a KGDB kernel install the new assembler.
  */
 
 #ifdef CONFIG_DEBUG_INFO
include/asm-x86_64/kgdb.h new file +57 -0

57 lines not on this page · raw message

include/asm-x86_64/processor.h +1 -0
@@ -252,6 +252,7 @@
 	unsigned long	*io_bitmap_ptr;
 /* cached TLS descriptors. */
 	u64 tls_array[GDT_ENTRY_TLS_ENTRIES];
+	void		*debuggerinfo;
 };
 
 #define INIT_THREAD  {}
include/asm-x86_64/system.h +50 -0

56 lines not on this page · raw message

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/