Skip to contentSkip to conversation

Add KGDB support to PA-RISC

PATCH New Sven Schnelle 1 participant 4 messages Apr 4, 2019 PA-RISC architecture

lore
Share & tools
lore
#0 lore raw

v2 cover Add KGDB support to PA-RISC

Hi,

this is v2 of the patch set. Changes compared to v1:

- add a missing #ifdef CONFIG_KGDB in traps.c, to fix a compile error when CONFIG_KGDB is not enabled.
- call __patch_text() in kgdb, as kgdb already stops all CPUs.

Sven Schnelle (3):
parisc: add set_fixmap()/clear_fixmap()
parisc: add parisc code patching
parisc: add KGDB support

 arch/parisc/Kconfig              |   1 +
 arch/parisc/include/asm/fixmap.h |  19 ++-
 arch/parisc/include/asm/kgdb.h   |  68 ++++++++++
 arch/parisc/include/asm/patch.h  |  11 ++
 arch/parisc/kernel/Makefile      |   4 +-
 arch/parisc/kernel/kgdb.c        | 210 +++++++++++++++++++++++++++++++
 arch/parisc/kernel/patch.c       |  78 ++++++++++++
 arch/parisc/kernel/traps.c       |  17 +++
 arch/parisc/mm/Makefile          |   2 +-
 arch/parisc/mm/fixmap.c          |  43 +++++++
 arch/parisc/mm/init.c            |  14 ++-
 11 files changed, 459 insertions(+), 8 deletions(-)
 create mode 100644 arch/parisc/include/asm/kgdb.h
 create mode 100644 arch/parisc/include/asm/patch.h
 create mode 100644 arch/parisc/kernel/kgdb.c
 create mode 100644 arch/parisc/kernel/patch.c
 create mode 100644 arch/parisc/mm/fixmap.c
Signature · 1 line
2.20.1
#1 lore raw

PATCH v2 1/3 parisc: add set_fixmap()/clear_fixmap()

These functions will be used for adding code patching functions later.

---
 arch/parisc/include/asm/fixmap.h | 19 +++++++++++++-
 arch/parisc/mm/Makefile          |  2 +-
 arch/parisc/mm/fixmap.c          | 43 ++++++++++++++++++++++++++++++++
 arch/parisc/mm/init.c            | 14 +++++++----
 4 files changed, 71 insertions(+), 7 deletions(-)
 create mode 100644 arch/parisc/mm/fixmap.c
arch/parisc/include/asm/fixmap.h +18 -1
index f7c3a0905de4..288da73d4cc0 100644
@@ -15,17 +15,34 @@
  * from areas congruently mapped with user space.  It is 8MB large
  * and must be 16MB aligned */
 #define TMPALIAS_MAP_START	((__PAGE_OFFSET) - 16*1024*1024)
+
+#define FIXMAP_SIZE		(FIX_BITMAP_COUNT << PAGE_SHIFT)
+#define FIXMAP_START		(TMPALIAS_MAP_START - FIXMAP_SIZE)
 /* This is the kernel area for all maps (vmalloc, dma etc.)  most
  * usually, it extends up to TMPALIAS_MAP_START.  Virtual addresses
  * 0..GATEWAY_PAGE_SIZE are reserved for the gateway page */
 #define KERNEL_MAP_START	(GATEWAY_PAGE_SIZE)
-#define KERNEL_MAP_END		(TMPALIAS_MAP_START)
+#define KERNEL_MAP_END		(FIXMAP_START)
 
 #ifndef __ASSEMBLY__
+
+
+enum fixed_addresses {
+	/* Support writing RO kernel text via kprobes, jump labels, etc. */
+	FIX_TEXT_POKE0,
+	FIX_BITMAP_COUNT
+};
+
 extern void *parisc_vmalloc_start;
 #define PCXL_DMA_MAP_SIZE	(8*1024*1024)
 #define VMALLOC_START		((unsigned long)parisc_vmalloc_start)
 #define VMALLOC_END		(KERNEL_MAP_END)
+
+#define __fix_to_virt(_x) (FIXMAP_START + ((_x) << PAGE_SHIFT))
+
+void set_fixmap(enum fixed_addresses idx, phys_addr_t phys);
+void clear_fixmap(enum fixed_addresses idx);
+
 #endif /*__ASSEMBLY__*/
 
 #endif /*_ASM_FIXMAP_H*/
arch/parisc/mm/Makefile +1 -1
index 134393de69d2..20e39b043a60 100644
@@ -2,5 +2,5 @@
 # Makefile for arch/parisc/mm
 #
 
-obj-y	 := init.o fault.o ioremap.o
+obj-y	 := init.o fault.o ioremap.o fixmap.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
arch/parisc/mm/fixmap.c new file +43 -0

43 lines not on this page · raw message

arch/parisc/mm/init.c +9 -5
index d0b166256f1a..b2b52de2b82b 100644
@@ -622,15 +622,19 @@ void __init mem_init(void)
 	 * But keep code for debugging purposes.
 	 */
 	printk("virtual kernel memory layout:\n"
-	       "    vmalloc : 0x%px - 0x%px   (%4ld MB)\n"
-	       "    memory  : 0x%px - 0x%px   (%4ld MB)\n"
-	       "      .init : 0x%px - 0x%px   (%4ld kB)\n"
-	       "      .data : 0x%px - 0x%px   (%4ld kB)\n"
-	       "      .text : 0x%px - 0x%px   (%4ld kB)\n",
+	       "     vmalloc : 0x%px - 0x%px   (%4ld MB)\n"
+	       "     fixmap  : 0x%px - 0x%px   (%4ld kB)\n"
+	       "     memory  : 0x%px - 0x%px   (%4ld MB)\n"
+	       "       .init : 0x%px - 0x%px   (%4ld kB)\n"
+	       "       .data : 0x%px - 0x%px   (%4ld kB)\n"
+	       "       .text : 0x%px - 0x%px   (%4ld kB)\n",
 
 	       (void*)VMALLOC_START, (void*)VMALLOC_END,
 	       (VMALLOC_END - VMALLOC_START) >> 20,
 
+	       (void *)FIXMAP_START, (void *)(FIXMAP_START + FIXMAP_SIZE),
+	       (unsigned long)(FIXMAP_SIZE / 1024),
+
 	       __va(0), high_memory,
 	       ((unsigned long)high_memory - (unsigned long)__va(0)) >> 20,
 
Signature · 1 line
2.20.1
#2 lore raw

PATCH v2 2/3 parisc: add parisc code patching

In reply to Sven Schnelle

Instead of re-mapping the whole kernel text with RWX rights add a patch_text() which can be used to replace instructions in the kernel .text section. Based on the ARM implementation.

---
 arch/parisc/include/asm/patch.h | 11 +++++
 arch/parisc/kernel/Makefile     |  3 +-
 arch/parisc/kernel/patch.c      | 78 +++++++++++++++++++++++++++++++++
 3 files changed, 91 insertions(+), 1 deletion(-)
 create mode 100644 arch/parisc/include/asm/patch.h
 create mode 100644 arch/parisc/kernel/patch.c
arch/parisc/include/asm/patch.h new file +11 -0
new file mode 100644
index 000000000000..685b58a13968
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _PARISC_KERNEL_PATCH_H
+#define _PARISC_KERNEL_PATCH_H
+
+/* stop machine and patch kernel text */
+void patch_text(void *addr, unsigned int insn);
+
+/* patch kernel text with machine already stopped (e.g. in kgdb) */
+void __patch_text(void *addr, unsigned int insn);
+
+#endif
arch/parisc/kernel/Makefile +2 -1
index 8e5f1ab65c68..d29bbd1a73b2 100644
@@ -9,7 +9,8 @@ obj-y	     	:= cache.o pacache.o setup.o pdt.o traps.o time.o irq.o \
 		   pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \
 		   ptrace.o hardware.o inventory.o drivers.o alternative.o \
 		   signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \
-		   process.o processor.o pdc_cons.o pdc_chassis.o unwind.o
+		   process.o processor.o pdc_cons.o pdc_chassis.o unwind.o \
+		   patch.o
 
 ifdef CONFIG_FUNCTION_TRACER
 # Do not profile debug and lowlevel utilities
arch/parisc/kernel/patch.c new file +78 -0

78 lines not on this page · raw message

Signature · 1 line
2.20.1
#3 lore raw

PATCH v2 3/3 parisc: add KGDB support

In reply to Sven Schnelle

This patch add KGDB support to PA-RISC. It also implements single-stepping utilizing the recovery counter.

---
 arch/parisc/Kconfig            |   1 +
 arch/parisc/include/asm/kgdb.h |  68 +++++++++++
 arch/parisc/kernel/Makefile    |   1 +
 arch/parisc/kernel/kgdb.c      | 210 +++++++++++++++++++++++++++++++++
 arch/parisc/kernel/traps.c     |  17 +++
 5 files changed, 297 insertions(+)
 create mode 100644 arch/parisc/include/asm/kgdb.h
 create mode 100644 arch/parisc/kernel/kgdb.c
arch/parisc/Kconfig +1 -0
index c8e621296092..a80c19c7fc0e 100644
@@ -54,6 +54,7 @@ config PARISC
 	select CPU_NO_EFFICIENT_FFS
 	select NEED_DMA_MAP_STATE
 	select NEED_SG_DMA_LENGTH
+	select HAVE_ARCH_KGDB
 
 	help
 	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
arch/parisc/include/asm/kgdb.h new file +68 -0

68 lines not on this page · raw message

arch/parisc/kernel/Makefile +1 -0
index d29bbd1a73b2..5012da96c196 100644
@@ -33,3 +33,4 @@ obj-$(CONFIG_64BIT)	+= perf.o perf_asm.o $(obj64-y)
 obj-$(CONFIG_PARISC_CPU_TOPOLOGY)	+= topology.o
 obj-$(CONFIG_FUNCTION_TRACER)		+= ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o
+obj-$(CONFIG_KGDB)			+= kgdb.o
arch/parisc/kernel/kgdb.c new file +210 -0

210 lines not on this page · raw message

arch/parisc/kernel/traps.c +17 -0
index 7e1ccafadf57..4a0516524f2a 100644
@@ -42,6 +42,7 @@
 #include <asm/unwind.h>
 #include <asm/tlbflush.h>
 #include <asm/cacheflush.h>
+#include <linux/kgdb.h>
 
 #include "../math-emu/math-emu.h"	/* for handle_fpe() */
 
@@ -293,6 +294,14 @@ static void handle_break(struct pt_regs *regs)
 			(tt == BUG_TRAP_TYPE_NONE) ? 9 : 0);
 	}
 
+#ifdef CONFIG_KGDB
+	if (unlikely(iir == PARISC_KGDB_COMPILED_BREAK_INSN ||
+		iir == PARISC_KGDB_BREAK_INSN)) {
+		kgdb_handle_exception(9, SIGTRAP, 0, regs);
+		return;
+	}
+#endif
+
 	if (unlikely(iir != GDB_BREAK_INSN))
 		parisc_printk_ratelimited(0, regs,
 			KERN_DEBUG "break %d,%d: pid=%d command='%s'\n",
@@ -518,6 +527,14 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
 	case  3:
 		/* Recovery counter trap */
 		regs->gr[0] &= ~PSW_R;
+
+#ifdef CONFIG_KGDB
+		if (kgdb_single_step) {
+			kgdb_handle_exception(0, SIGTRAP, 0, regs);
+			return;
+		}
+#endif
+
 		if (user_space(regs))
 			handle_gdb_break(regs, TRAP_TRACE);
 		/* else this must be the start of a syscall - just let it run */
Signature · 1 line
2.20.1