Skip to contentSkip to conversation

arm64: KGDB Support

PATCH Superseded vijay.kilari at gmail.com 3 participants 11 messages Jan 22, 2014 – Jan 23, 2014

Subsystems (3)

v7 of 10 Superseded Latest is v10 →

lore
Share & tools
lore
#0 lore raw

v7 cover arm64: KGDB Support

From: Vijaya Kumar K <[email protected]>

Based on the step-handler and break-handler hooks patch from Sandeepa, KGDB debugging support is added for EL1 debug in AArch64 mode.

In first patch, PSTATE.D is set correctly

In second patch,register layout is updated to be inline with GDB tool. Basic GDB connection, break point set/clear and info commands are supported except step/next debugging

With second patch, step/next debugging support is added, where in pc is updated to point to the instruction to be stepped and stopped.

With third patch, the compile time breakpoint instruction reordering is fixed by making kgbd_breakpoint() as noinline

Tested with ARM64 simulator

v7:
- Changes made to set PSTATE.D properly
- Performed KGDB boot tests
- Fixed compilation warnings in driver/misc/kgbdts.c

Results:

kgdb boot test:

  [32927.237895] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
  [32927.266066] kgdb: Registered I/O driver kgdbts.
  [32927.266419] kgdb: Waiting for connection from remote gdb...
  [32927.268598] kgdbts:RUN plant and detach test
  [32927.270683] kgdbts:RUN sw breakpoint test
  [32927.287659] kgdbts:RUN bad memory access test
  [32927.290322] kgdbts:RUN singlestep test 1000 iterations
  [32927.330342] kgdbts:RUN singlestep [0/1000]
  [32931.286356] kgdbts:RUN singlestep [100/1000]
  [32935.242536] kgdbts:RUN singlestep [200/1000]
  [32939.205392] kgdbts:RUN singlestep [300/1000]
  [32943.169522] kgdbts:RUN singlestep [400/1000]
  [32947.231868] kgdbts:RUN singlestep [500/1000]
  [32951.188008] kgdbts:RUN singlestep [600/1000]
  [32955.332243] kgdbts:RUN singlestep [700/1000]
  [32959.467109] kgdbts:RUN singlestep [800/1000]
  [32963.430888] kgdbts:RUN singlestep [900/1000]
  [32967.346992] kgdbts:RUN do_fork for 100 breakpoints

kgdb test from sysfs:

~ # echo V1F1000 > /sys/module/kgdbts/parameters/kgdbts

  [33231.554237] kgdb: Registered I/O driver kgdbts.
  [33231.554677] kgdbts:RUN plant and detach test
  [33231.557072] kgdbts:RUN sw breakpoint test
  [33231.576980] kgdbts:RUN bad memory access test
  [33231.580022] kgdbts:RUN singlestep test 1000 iterations
  [33231.627056] kgdbts:RUN singlestep [0/1000]
  [33235.954027] kgdbts:RUN singlestep [100/1000]
  [33240.429086] kgdbts:RUN singlestep [200/1000]
  [33244.687118] kgdbts:RUN singlestep [300/1000]
  [33248.945191] kgdbts:RUN singlestep [400/1000]
  [33253.203751] kgdbts:RUN singlestep [500/1000]
  [33257.462019] kgdbts:RUN singlestep [600/1000]
  [33261.817809] kgdbts:RUN singlestep [700/1000]
  [33266.081268] kgdbts:RUN singlestep [800/1000]
  [33270.339813] kgdbts:RUN singlestep [900/1000]
  [33274.712404] kgdbts:RUN do_fork for 1000 breakpoints
  ~ #

v6:
- Change pstate register to 8 bytes to make endian nuetral. Use GDB below GDB patch to display pstate in Big endian mode.
https://sourceware.org/ml/gdb-patches/2013-12/msg00720.html
Thanks to Andrew.

v5:
- Updated BRK #imm16 value to 0x400 & 0x401 as per recommendation as per Marcus recommendataion
http://patchwork.ozlabs.org/patch/290801/
- Rebased to 3.13 AArch64 kernel

v4:
- Updated kgdb_single_step and kgdb_cpu_doing_single_step variables properly based on gdb state

v3:
- Rebased to v4 version of Sandeepa Prabhu's patch (patch 1)
- Made dynamic break point instruction encoding generic
- Made ESR value encoding generic for dynamic and compile break point
- Used memcpy and memset to copy register contents to gdb buffer
- Fixed reordering of break point instruction by compiler with patch 3
- Rebased against AAach64 upstream kernel

v2:
- Moved break instruction encoding to debug-monitors.h file
- Fixed endianess of compile break instruction encoding
- Updated I/O buffer sizes
- Updated register buffer size
- Remove changes to debug_exception handler in entry.S for
- ELR update and step debugging with update pc instead of ELR
- Rebased against AArch64 upstream kernel

v1:
- Initial patch-set

Vijaya Kumar K (6):
arm64: Add macros to manage processor debug state
arm64: KGDB: Add Basic KGDB support
arm64: KGDB: Add step debugging support
KGDB: make kgdb_breakpoint() as noinline
misc: debug: remove compilation warnings
arm64: KGDB: Add KGDB config

 arch/arm64/Kconfig                      |    1 +
 arch/arm64/include/asm/debug-monitors.h |   65 ++++--
 arch/arm64/include/asm/irqflags.h       |   22 ++
 arch/arm64/include/asm/kgdb.h           |   84 ++++++++
 arch/arm64/kernel/Makefile              |    1 +
 arch/arm64/kernel/debug-monitors.c      |    3 +-
 arch/arm64/kernel/kgdb.c                |  336 +++++++++++++++++++++++++++++++
 drivers/misc/kgdbts.c                   |   12 +-
 kernel/debug/debug_core.c               |    2 +-
 9 files changed, 502 insertions(+), 24 deletions(-)
 create mode 100644 arch/arm64/include/asm/kgdb.h
 create mode 100644 arch/arm64/kernel/kgdb.c
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH v7 1/6 arm64: Add macros to manage processor debug state

From: Vijaya Kumar K <[email protected]>

Add macros to enable and disable to manage PSTATE.D for debugging. The macros local_dbg_save and local_dbg_restore are moved to irqflags.h file

KGDB boot tests fail because of PSTATE.D is masked. unmask it for debugging support

---
 arch/arm64/include/asm/debug-monitors.h |   18 ++----------------
 arch/arm64/include/asm/irqflags.h       |   22 ++++++++++++++++++++++
 arch/arm64/kernel/debug-monitors.c      |    3 ++-
 3 files changed, 26 insertions(+), 17 deletions(-)
arch/arm64/include/asm/debug-monitors.h +2 -16
index 6231479..bc48880 100644
@@ -43,22 +43,8 @@ enum debug_el {
 #ifndef __ASSEMBLY__
 struct task_struct;
 
-#define local_dbg_save(flags)							\
-	do {									\
-		typecheck(unsigned long, flags);				\
-		asm volatile(							\
-		"mrs	%0, daif			// local_dbg_save\n"	\
-		"msr	daifset, #8"						\
-		: "=r" (flags) : : "memory");					\
-	} while (0)
-
-#define local_dbg_restore(flags)						\
-	do {									\
-		typecheck(unsigned long, flags);				\
-		asm volatile(							\
-		"msr	daif, %0			// local_dbg_restore\n"	\
-		: : "r" (flags) : "memory");					\
-	} while (0)
+#define local_dbg_enable()	asm("msr	daifclr, #8" : : : "memory")
+#define local_dbg_disable()	asm("msr	daifset, #8" : : : "memory")
 
 #define DBG_ARCH_ID_RESERVED	0	/* In case of ptrace ABI updates. */
 
arch/arm64/include/asm/irqflags.h +22 -0
index b2fcfbc..f163b11 100644
@@ -90,5 +90,27 @@ static inline int arch_irqs_disabled_flags(unsigned long flags)
 	return flags & PSR_I_BIT;
 }
 
+/*
+ * save and restore debug state
+ */
+static inline unsigned long local_dbg_save(void)
+{
+	unsigned long flags;
+	asm volatile(
+		"mrs	%0, daif		// local_dbg_save"
+		"msr	daifset, #8"
+		: "=r" (flags) : : "memory");
+	return flags;
+}
+
+static inline void local_dbg_restore(unsigned long flags)
+{
+	asm volatile(
+		"msr	daif, %0	// local_dbg_restore"
+		:
+		: "r" (flags)
+		: "memory");
+}
+
 #endif
 #endif
arch/arm64/kernel/debug-monitors.c +2 -1
index 23586bd..774ad04 100644
@@ -51,7 +51,7 @@ u8 debug_monitors_arch(void)
 static void mdscr_write(u32 mdscr)
 {
 	unsigned long flags;
-	local_dbg_save(flags);
+	flags = local_dbg_save();
 	asm volatile("msr mdscr_el1, %0" :: "r" (mdscr));
 	local_dbg_restore(flags);
 }
@@ -138,6 +138,7 @@ static void clear_os_lock(void *unused)
 {
 	asm volatile("msr oslar_el1, %0" : : "r" (0));
 	isb();
+	local_dbg_enable();
 }
 
 static int os_lock_notify(struct notifier_block *self,
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH 1/6 arm64: Add macros to manage processor debug state

Hello,

Quoted 32 lines · vijay.kilari at gmail.com

From: Vijaya Kumar K <[email protected]>

Add macros to enable and disable to manage PSTATE.D for debugging. The macros local_dbg_save and local_dbg_restore are moved to irqflags.h file

KGDB boot tests fail because of PSTATE.D is masked. unmask it for debugging support

---
 arch/arm64/include/asm/debug-monitors.h |   18 ++----------------
 arch/arm64/include/asm/irqflags.h       |   22 ++++++++++++++++++++++
 arch/arm64/kernel/debug-monitors.c      |    3 ++-
 3 files changed, 26 insertions(+), 17 deletions(-)
arch/arm64/include/asm/debug-monitors.h +0 -8
index 6231479..bc48880 100644
@@ -43,22 +43,8 @@ enum debug_el {
 #ifndef __ASSEMBLY__
 struct task_struct;
 
-#define local_dbg_save(flags)							\
-	do {									\
-		typecheck(unsigned long, flags);				\
-		asm volatile(							\
-		"mrs	%0, daif			// local_dbg_save\n"	\
-		"msr	daifset, #8"						\
-		: "=r" (flags) : : "memory");					\
-	} while (0)

arch/arm64/include/asm/debug-monitors.h enum debug_el { · line 47

Quoted 10 lines
arch/arm64/include/asm/debug-monitors.h +2 -8
-
-#define local_dbg_restore(flags)						\
-	do {									\
-		typecheck(unsigned long, flags);				\
-		asm volatile(							\
-		"msr	daif, %0			// local_dbg_restore\n"	\
-		: : "r" (flags) : "memory");					\
-	} while (0)
+#define local_dbg_enable()	asm("msr	daifclr, #8" : : : "memory")
+#define local_dbg_disable()	asm("msr	daifset, #8" : : : "memory")

Any reason not to move these to irqflags.h too?

Quoted 39 lines
arch/arm64/include/asm/debug-monitors.h +0 -0
 #define DBG_ARCH_ID_RESERVED	0	/* In case of ptrace ABI updates. */
 
arch/arm64/include/asm/irqflags.h +22 -0
index b2fcfbc..f163b11 100644
@@ -90,5 +90,27 @@ static inline int arch_irqs_disabled_flags(unsigned long flags)
 	return flags & PSR_I_BIT;
 }
 
+/*
+ * save and restore debug state
+ */
+static inline unsigned long local_dbg_save(void)
+{
+	unsigned long flags;
+	asm volatile(
+		"mrs	%0, daif		// local_dbg_save"
+		"msr	daifset, #8"
+		: "=r" (flags) : : "memory");
+	return flags;
+}
+
+static inline void local_dbg_restore(unsigned long flags)
+{
+	asm volatile(
+		"msr	daif, %0	// local_dbg_restore"
+		:
+		: "r" (flags)
+		: "memory");
+}
+
 #endif
 #endif
arch/arm64/kernel/debug-monitors.c +0 -0
index 23586bd..774ad04 100644

arch/arm64/kernel/debug-monitors.c u8 debug_monitors_arch(void) · line 54

Quoted 5 lines
arch/arm64/kernel/debug-monitors.c +1 -1
@@ -51,7 +51,7 @@ u8 debug_monitors_arch(void)
 static void mdscr_write(u32 mdscr)
 {
 	unsigned long flags;
-	local_dbg_save(flags);
+	flags = local_dbg_save();

Why are you changing the API? This is now pointlessly different to irqs.

Will

#3 lore raw

PATCH v7 1/6 arm64: Add macros to manage processor debug state

Quoted 39 lines · Will Deacon

Hello,

Quoted 36 lines · vijay.kilari at gmail.com

From: Vijaya Kumar K <[email protected]>

Add macros to enable and disable to manage PSTATE.D for debugging. The macros local_dbg_save and local_dbg_restore are moved to irqflags.h file

KGDB boot tests fail because of PSTATE.D is masked. unmask it for debugging support

---
 arch/arm64/include/asm/debug-monitors.h |   18 ++----------------
 arch/arm64/include/asm/irqflags.h       |   22 ++++++++++++++++++++++
 arch/arm64/kernel/debug-monitors.c      |    3 ++-
 3 files changed, 26 insertions(+), 17 deletions(-)
arch/arm64/include/asm/debug-monitors.h +0 -12
index 6231479..bc48880 100644
@@ -43,22 +43,8 @@ enum debug_el {
 #ifndef __ASSEMBLY__
 struct task_struct;
 
-#define local_dbg_save(flags)                                                        \
-     do {                                                                    \
-             typecheck(unsigned long, flags);                                \
-             asm volatile(                                                   \
-             "mrs    %0, daif                        // local_dbg_save\n"    \
-             "msr    daifset, #8"                                            \
-             : "=r" (flags) : : "memory");                                   \
-     } while (0)
-
-#define local_dbg_restore(flags)                                             \
-     do {                                                                    \
-             typecheck(unsigned long, flags);                                \
Quoted 8 lines

arch/arm64/include/asm/debug-monitors.h enum debug_el { · line 47

Quoted 6 lines
arch/arm64/include/asm/debug-monitors.h +2 -4
-             asm volatile(                                                   \
-             "msr    daif, %0                        // local_dbg_restore\n" \
-             : : "r" (flags) : "memory");                                    \
-     } while (0)
+#define local_dbg_enable()   asm("msr        daifclr, #8" : : : "memory")
+#define local_dbg_disable()  asm("msr        daifset, #8" : : : "memory")

Any reason not to move these to irqflags.h too?

Can me moved to irqflags.h file

Quoted 39 lines
Quoted 39 lines
arch/arm64/include/asm/debug-monitors.h +0 -0
 #define DBG_ARCH_ID_RESERVED 0       /* In case of ptrace ABI updates. */
 
arch/arm64/include/asm/irqflags.h +22 -0
index b2fcfbc..f163b11 100644
@@ -90,5 +90,27 @@ static inline int arch_irqs_disabled_flags(unsigned long flags)
      return flags & PSR_I_BIT;
 }
 
+/*
+ * save and restore debug state
+ */
+static inline unsigned long local_dbg_save(void)
+{
+     unsigned long flags;
+     asm volatile(
+             "mrs    %0, daif                // local_dbg_save"
+             "msr    daifset, #8"
+             : "=r" (flags) : : "memory");
+     return flags;
+}
+
+static inline void local_dbg_restore(unsigned long flags)
+{
+     asm volatile(
+             "msr    daif, %0        // local_dbg_restore"
+             :
+             : "r" (flags)
+             : "memory");
+}
+
 #endif
 #endif
arch/arm64/kernel/debug-monitors.c +0 -0
index 23586bd..774ad04 100644
Quoted 8 lines

arch/arm64/kernel/debug-monitors.c u8 debug_monitors_arch(void) · line 54

Quoted 6 lines
arch/arm64/kernel/debug-monitors.c +1 -1
@@ -51,7 +51,7 @@ u8 debug_monitors_arch(void)
 static void mdscr_write(u32 mdscr)
 {
      unsigned long flags;
-     local_dbg_save(flags);
+     flags = local_dbg_save();

Why are you changing the API? This is now pointlessly different to irqs.

To be in line with arch_local_irq_save & arch_local_save_flags in irqflags.h, I moved this macros into functions and accordingly changed the caller. I could not find any code using this local_dbg_{save, restore} except from debug-monitors.c file

If required, I can think of renaming local_dbg_{save,restore} as local_dbg_{save,restore}_flags

Quoted 2 lines

Will

#4 lore raw

PATCH 1/6 arm64: Add macros to manage processor debug state

Quoted 14 lines · Vijay Kilari
Quoted 4 lines · Will Deacon
Quoted 4 lines
arch/arm64/kernel/debug-monitors.c +0 -0
index 23586bd..774ad04 100644
Quoted 8 lines

arch/arm64/kernel/debug-monitors.c u8 debug_monitors_arch(void) · line 54

Quoted 6 lines
arch/arm64/kernel/debug-monitors.c +1 -1
@@ -51,7 +51,7 @@ u8 debug_monitors_arch(void)
 static void mdscr_write(u32 mdscr)
 {
      unsigned long flags;
-     local_dbg_save(flags);
+     flags = local_dbg_save();

Why are you changing the API? This is now pointlessly different to irqs.

Quoted 7 lines

To be in line with arch_local_irq_save & arch_local_save_flags in irqflags.h, I moved this macros into functions and accordingly changed the caller. I could not find any code using this local_dbg_{save, restore} except from debug-monitors.c file

If required, I can think of renaming local_dbg_{save,restore} as local_dbg_{save,restore}_flags

No, I'd rather local_dbg_{save, restore} were aligned with local_irq_{save, restore} (as defined in include/linux/irqflags.h).

Will

#5 lore raw

PATCH v7 2/6 arm64: KGDB: Add Basic KGDB support

In reply to vijay.kilari at gmail.com

From: Vijaya Kumar K <[email protected]>

Add KGDB debug support for kernel debugging.
With this patch, basic KGDB debugging is possible.GDB register layout is updated and GDB tool can establish connection with target and can set/clear breakpoints.

---
 arch/arm64/include/asm/debug-monitors.h |   47 +++++
 arch/arm64/include/asm/kgdb.h           |   84 +++++++++
 arch/arm64/kernel/Makefile              |    1 +
 arch/arm64/kernel/kgdb.c                |  288 +++++++++++++++++++++++++++++++
 4 files changed, 420 insertions(+)
arch/arm64/include/asm/debug-monitors.h +47 -0
index bc48880..8d8b417 100644
@@ -26,6 +26,53 @@
 #define DBG_ESR_EVT_HWWP	0x2
 #define DBG_ESR_EVT_BRK		0x6
 
+/*
+ * Break point instruction encoding
+ */
+#define BREAK_INSTR_SIZE		4
+
+/*
+ * ESR values expected for dynamic and compile time BRK instruction
+ */
+#define DBG_ESR_VAL_BRK(x)	(0xf2000000 | ((x) & 0xfffff))
+
+/*
+ * #imm16 values used for BRK instruction generation
+ * Allowed values for kgbd are 0x400 - 0x7ff
+ * 0x400: for dynamic BRK instruction
+ * 0x401: for compile time BRK instruction
+ */
+#define KGDB_DYN_DGB_BRK_IMM		0x400
+#define KDBG_COMPILED_DBG_BRK_IMM	0x401
+
+/*
+ * BRK instruction encoding
+ * The #imm16 value should be placed at bits[20:5] within BRK ins
+ */
+#define AARCH64_BREAK_MON	0xd4200000
+
+/*
+ * Extract byte from BRK instruction
+ */
+#define KGDB_DYN_DGB_BRK_INS_BYTE(x) \
+	((((AARCH64_BREAK_MON) & 0xffe0001f) >> (x * 8)) & 0xff)
+
+/*
+ * Extract byte from BRK #imm16
+ */
+#define KGBD_DYN_DGB_BRK_IMM_BYTE(x) \
+	(((((KGDB_DYN_DGB_BRK_IMM) & 0xffff) << 5) >> (x * 8)) & 0xff)
+
+#define KGDB_DYN_DGB_BRK_BYTE(x) \
+	(KGDB_DYN_DGB_BRK_INS_BYTE(x) | KGBD_DYN_DGB_BRK_IMM_BYTE(x))
+
+#define  KGDB_DYN_BRK_INS_BYTE0  KGDB_DYN_DGB_BRK_BYTE(0)
+#define  KGDB_DYN_BRK_INS_BYTE1  KGDB_DYN_DGB_BRK_BYTE(1)
+#define  KGDB_DYN_BRK_INS_BYTE2  KGDB_DYN_DGB_BRK_BYTE(2)
+#define  KGDB_DYN_BRK_INS_BYTE3  KGDB_DYN_DGB_BRK_BYTE(3)
+
+#define CACHE_FLUSH_IS_SAFE		1
+
 enum debug_el {
 	DBG_ACTIVE_EL0 = 0,
 	DBG_ACTIVE_EL1,
arch/arm64/include/asm/kgdb.h new file +84 -0

84 lines not on this page · raw message

arch/arm64/kernel/Makefile +1 -0
index 5ba2fd4..b9b87fa 100644
@@ -18,6 +18,7 @@ arm64-obj-$(CONFIG_SMP)			+= smp.o smp_spin_table.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
 arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
 arm64-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
+arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
 
 obj-y					+= $(arm64-obj-y) vdso/
 obj-m					+= $(arm64-obj-m)
arch/arm64/kernel/kgdb.c new file +288 -0

288 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#6 lore raw

PATCH v7 3/6 arm64: KGDB: Add step debugging support

In reply to vijay.kilari at gmail.com

From: Vijaya Kumar K <[email protected]>

Add KGDB software step debugging support for EL1 debug in AArch64 mode.

KGDB registers step debug handler with debug monitor. On receiving 'step' command from GDB tool, target enables software step debugging and step address is updated in ELR.

Software Step debugging is disabled when 'continue' command is received

---
 arch/arm64/kernel/kgdb.c |   64 ++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 56 insertions(+), 8 deletions(-)
arch/arm64/kernel/kgdb.c +56 -8
index 4b7a569..75c9cf1 100644
@@ -137,13 +137,26 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
 
 static int compiled_break;
 
+static void kgdb_arch_update_addr(struct pt_regs *regs,
+				char *remcom_in_buffer)
+{
+	unsigned long addr;
+	char *ptr;
+
+	ptr = &remcom_in_buffer[1];
+	if (kgdb_hex2long(&ptr, &addr))
+		kgdb_arch_set_pc(regs, addr);
+	else if (compiled_break == 1)
+		kgdb_arch_set_pc(regs, regs->pc + 4);
+
+	compiled_break = 0;
+}
+
 int kgdb_arch_handle_exception(int exception_vector, int signo,
 			       int err_code, char *remcom_in_buffer,
 			       char *remcom_out_buffer,
 			       struct pt_regs *linux_regs)
 {
-	unsigned long addr;
-	char *ptr;
 	int err;
 
 	switch (remcom_in_buffer[0]) {
@@ -162,13 +175,36 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,
 		 * to the next instruction else we will just breakpoint
 		 * over and over again.
 		 */
-		ptr = &remcom_in_buffer[1];
-		if (kgdb_hex2long(&ptr, &addr))
-			kgdb_arch_set_pc(linux_regs, addr);
-		else if (compiled_break == 1)
-			kgdb_arch_set_pc(linux_regs, linux_regs->pc + 4);
+		kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
+		atomic_set(&kgdb_cpu_doing_single_step, -1);
+		kgdb_single_step =  0;
+
+		/*
+		 * Received continue command, disable single step
+		 */
+		if (kernel_active_single_step())
+			kernel_disable_single_step();
+
+		err = 0;
+		break;
+	case 's':
+		/*
+		 * Update step address value with address passed
+		 * with step packet.
+		 * On debug exception return PC is copied to ELR
+		 * So just update PC.
+		 * If no step address is passed, resume from the address
+		 * pointed by PC. Do not update PC
+		 */
+		kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
+		atomic_set(&kgdb_cpu_doing_single_step, raw_smp_processor_id());
+		kgdb_single_step =  1;
 
-		compiled_break = 0;
+		/*
+		 * Enable single step handling
+		 */
+		if (!kernel_active_single_step())
+			kernel_enable_single_step(linux_regs);
 		err = 0;
 		break;
 	default:
@@ -191,6 +227,12 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr)
 	return 0;
 }
 
+static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr)
+{
+	kgdb_handle_exception(1, SIGTRAP, 0, regs);
+	return 0;
+}
+
 static struct break_hook kgdb_brkpt_hook = {
 	.esr_mask	= 0xffffffff,
 	.esr_val	= DBG_ESR_VAL_BRK(KGDB_DYN_DGB_BRK_IMM),
@@ -203,6 +245,10 @@ static struct break_hook kgdb_compiled_brkpt_hook = {
 	.fn		= kgdb_compiled_brk_fn
 };
 
+static struct step_hook kgdb_step_hook = {
+	.fn		= kgdb_step_brk_fn
+};
+
 static void kgdb_call_nmi_hook(void *ignored)
 {
 	kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
@@ -259,6 +305,7 @@ int kgdb_arch_init(void)
 
 	register_break_hook(&kgdb_brkpt_hook);
 	register_break_hook(&kgdb_compiled_brkpt_hook);
+	register_step_hook(&kgdb_step_hook);
 	return 0;
 }
 
@@ -271,6 +318,7 @@ void kgdb_arch_exit(void)
 {
 	unregister_break_hook(&kgdb_brkpt_hook);
 	unregister_break_hook(&kgdb_compiled_brkpt_hook);
+	unregister_step_hook(&kgdb_step_hook);
 	unregister_die_notifier(&kgdb_notifier);
 }
 
Signature · 1 line
1.7.9.5
#7 lore raw

PATCH v7 4/6 KGDB: make kgdb_breakpoint() as noinline

In reply to vijay.kilari at gmail.com

From: Vijaya Kumar K <[email protected]>

The function kgdb_breakpoint() sets up break point at compile time by calling arch_kgdb_breakpoint(); Though this call is surrounded by wmb() barrier, the compile can still re-order the break point, because this scheduling barrier is not a code motion barrier in gcc.

Making kgdb_breakpoint() as noinline solves this problem of code reording around break point instruction and also avoids problem of being called as inline function from other places

More details about discussion on this can be found here
http://comments.gmane.org/gmane.linux.ports.arm.kernel/269732

---
 kernel/debug/debug_core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/debug/debug_core.c +1 -1
index 7d2f35e..cf04798 100644
@@ -1034,7 +1034,7 @@ int dbg_io_get_char(void)
  * otherwise as a quick means to stop program execution and "break" into
  * the debugger.
  */
-void kgdb_breakpoint(void)
+noinline void kgdb_breakpoint(void)
 {
 	atomic_inc(&kgdb_setting_breakpoint);
 	wmb(); /* Sync point before breakpoint */
Signature · 1 line
1.7.9.5
#8 lore raw

PATCH v7 5/6 misc: debug: remove compilation warnings

In reply to vijay.kilari at gmail.com

From: Vijaya Kumar K <[email protected]>

Resolve following compiler warnings
warning: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'u64' [-Wformat]

tested for warnings on arm32 & arm64

---
 drivers/misc/kgdbts.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/misc/kgdbts.c +6 -6
index 36f5d52..78e10b2 100644
@@ -350,8 +350,8 @@ static int check_single_step(char *put_str, char *arg)
 	kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs,
 		 NUMREGBYTES);
 	gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs);
-	v2printk("Singlestep stopped at IP: %lx\n",
-		   instruction_pointer(&kgdbts_regs));
+	v2printk("Singlestep stopped at IP: %llx\n",
+		   (unsigned long long)instruction_pointer(&kgdbts_regs));
 
 	if (sstep_thread_id != cont_thread_id) {
 		/*
@@ -376,8 +376,8 @@ static int check_single_step(char *put_str, char *arg)
 continue_test:
 	matched_id = 0;
 	if (instruction_pointer(&kgdbts_regs) == addr) {
-		eprintk("kgdbts: SingleStep failed at %lx\n",
-			   instruction_pointer(&kgdbts_regs));
+		eprintk("kgdbts: SingleStep failed at %llx\n",
+			(unsigned long long)instruction_pointer(&kgdbts_regs));
 		return 1;
 	}
 
@@ -491,8 +491,8 @@ static int emul_sstep_put(char *put_str, char *arg)
 		kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs,
 			 NUMREGBYTES);
 		gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs);
-		v2printk("Stopped at IP: %lx\n",
-			 instruction_pointer(&kgdbts_regs));
+		v2printk("Stopped at IP: %llx\n",
+			 (unsigned long long)instruction_pointer(&kgdbts_regs));
 		/* Want to stop at IP + break instruction size by default */
 		sstep_addr = cont_addr + BREAK_INSTR_SIZE;
 		break;
Signature · 1 line
1.7.9.5
maintainer
#9 lore raw

PATCH v7 5/6 misc: debug: remove compilation warnings

Quoted 29 lines · vijay.kilari at gmail.com

From: Vijaya Kumar K <[email protected]>

Resolve following compiler warnings
warning: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'u64' [-Wformat]

tested for warnings on arm32 & arm64

---
 drivers/misc/kgdbts.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/misc/kgdbts.c +2 -2
index 36f5d52..78e10b2 100644
@@ -350,8 +350,8 @@ static int check_single_step(char *put_str, char *arg)
 	kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs,
 		 NUMREGBYTES);
 	gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs);
-	v2printk("Singlestep stopped at IP: %lx\n",
-		   instruction_pointer(&kgdbts_regs));
+	v2printk("Singlestep stopped at IP: %llx\n",
+		   (unsigned long long)instruction_pointer(&kgdbts_regs));
 
 	if (sstep_thread_id != cont_thread_id) {
 		/*

drivers/misc/kgdbts.c static int check_single_step(char *put_str, char *arg) · line 380

Quoted 7 lines
drivers/misc/kgdbts.c +2 -2
@@ -376,8 +376,8 @@ static int check_single_step(char *put_str, char *arg)
 continue_test:
 	matched_id = 0;
 	if (instruction_pointer(&kgdbts_regs) == addr) {
-		eprintk("kgdbts: SingleStep failed at %lx\n",
-			   instruction_pointer(&kgdbts_regs));
+		eprintk("kgdbts: SingleStep failed at %llx\n",
+			(unsigned long long)instruction_pointer(&kgdbts_regs));

I think we could simply add the cast to the definition of instruction_pointer() on arm64. Even the generic instruction_pointer() definition returns unsigned long.

Signature · 1 line
Catalin
#10 lore raw

PATCH v7 6/6 arm64: KGDB: Add KGDB config

In reply to vijay.kilari at gmail.com

From: Vijaya Kumar K <[email protected]>

Add HAVE_ARCH_KGDB for arm64 Kconfig

---
 arch/arm64/Kconfig |    1 +
 1 file changed, 1 insertion(+)
arch/arm64/Kconfig +1 -0
index 6d4dd22..c7a08e0 100644
@@ -28,6 +28,7 @@ config ARM64
 	select HAVE_HW_BREAKPOINT if PERF_EVENTS
 	select HAVE_MEMBLOCK
 	select HAVE_PERF_EVENTS
+	select HAVE_ARCH_KGDB
 	select IRQ_DOMAIN
 	select MODULES_USE_ELF_RELA
 	select NO_BOOTMEM
Signature · 1 line
1.7.9.5