Skip to contentSkip to conversation

Add KGDB support to parisc

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

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover Add KGDB support to parisc

Hi,

these series add fixed mappings, a function to patch kernel text with RO kernel text and kgdb support to parisc.

Fixed mappings are located at the end of the VMALLOC address range. patch_text() is introduced based on the ARM implementation, which utilizies fixed mappings. patch_text() only supports late patching, but we might extend it later with early patching functionality. And last but not least the last patch adds KGDB functionality. KGDB was tested on C3750 with a 32 and 64 bit kernel, on C8000 with 64 bit.

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  |   7 ++
 arch/parisc/kernel/Makefile      |   4 +-
 arch/parisc/kernel/kgdb.c        | 210 +++++++++++++++++++++++++++++++
 arch/parisc/kernel/patch.c       |  78 ++++++++++++
 arch/parisc/kernel/traps.c       |  15 +++
 arch/parisc/mm/Makefile          |   2 +-
 arch/parisc/mm/fixmap.c          |  43 +++++++
 arch/parisc/mm/init.c            |  14 ++-
 11 files changed, 453 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 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 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 |  7 +++
 arch/parisc/kernel/Makefile     |  3 +-
 arch/parisc/kernel/patch.c      | 78 +++++++++++++++++++++++++++++++++
 3 files changed, 87 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 +7 -0
new file mode 100644
index 000000000000..24ceb84519e4
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _PARISC_KERNEL_PATCH_H
+#define _PARISC_KERNEL_PATCH_H
+
+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 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     |  15 +++
 5 files changed, 295 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 +15 -0
index 7e1ccafadf57..91f94fc2abd3 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,12 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
 	case  3:
 		/* Recovery counter trap */
 		regs->gr[0] &= ~PSW_R;
+
+		if (kgdb_single_step) {
+			kgdb_handle_exception(0, SIGTRAP, 0, regs);
+			return;
+		}
+
 		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