Эх сурвалжийг харах

microblaze: Support brki rX, 0x18 for user application debugging

This is the first patch which add support for
user application debugging through brki rX, 0x18 vector.

This patch has side effect which also remove security issue
to use brki rX, 0x18 to freeze kernel.

Support for old gdb support via priviledged exception
(brk r0, r0) is still there. It will be remove in future.

Signed-off-by: Michal Simek <monstr@monstr.eu>
Michal Simek 15 жил өмнө
parent
commit
751f1605e0

+ 12 - 18
arch/microblaze/kernel/entry.S

@@ -778,19 +778,22 @@ C_ENTRY(_debug_exception):
 
 
 	addik	r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack.  */
 	addik	r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack.  */
 	SAVE_REGS;
 	SAVE_REGS;
+	swi	r17, r1, PTO+PT_R17;
+	swi	r16, r1, PTO+PT_R16;
+	swi	r16, r1, PTO+PT_PC;	/* Save LP */
 
 
 	swi	r0, r1, PTO + PT_MODE; /* Was in user-mode.  */
 	swi	r0, r1, PTO + PT_MODE; /* Was in user-mode.  */
 	lwi	r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
 	lwi	r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
 	swi	r11, r1, PTO+PT_R1; /* Store user SP.  */
 	swi	r11, r1, PTO+PT_R1; /* Store user SP.  */
-2:
+2:	lwi	CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
 	tovirt(r1,r1)
 	tovirt(r1,r1)
 
 
 	set_vms;
 	set_vms;
-	addi	r5, r0, SIGTRAP		     /* send the trap signal */
-	add	r6, r0, CURRENT_TASK; /* Get current task ptr into r11 */
-	addk	r7, r0, r0		     /* 3rd param zero */
-dbtrap_call:	rtbd	r0, send_sig;
+	addik	r5, r1, PTO;
 	addik	r15, r0, dbtrap_call;
 	addik	r15, r0, dbtrap_call;
+dbtrap_call: /* return point for kernel/user entry */
+	rtbd	r0, sw_exception
+	nop
 
 
 	set_bip;			/*  Ints masked for state restore*/
 	set_bip;			/*  Ints masked for state restore*/
 	lwi	r11, r1, PTO + PT_MODE;
 	lwi	r11, r1, PTO + PT_MODE;
@@ -838,6 +841,8 @@ dbtrap_call:	rtbd	r0, send_sig;
 	tophys(r1,r1);
 	tophys(r1,r1);
 
 
 	RESTORE_REGS
 	RESTORE_REGS
+	lwi	r17, r1, PTO+PT_R17;
+	lwi	r16, r1, PTO+PT_R16;
 	addik	r1, r1, STATE_SAVE_SIZE		/* Clean up stack space.  */
 	addik	r1, r1, STATE_SAVE_SIZE		/* Clean up stack space.  */
 
 
 
 
@@ -854,11 +859,10 @@ dbtrap_call:	rtbd	r0, send_sig;
 	tovirt(r1,r1);
 	tovirt(r1,r1);
 6:
 6:
 DBTRAP_return:		/* Make global symbol for debugging */
 DBTRAP_return:		/* Make global symbol for debugging */
-	rtbd	r14, 0;	/* Instructions to return from an IRQ */
+	rtbd	r16, 0;	/* Instructions to return from an IRQ */
 	nop;
 	nop;
 
 
 
 
-
 ENTRY(_switch_to)
 ENTRY(_switch_to)
 	/* prepare return value */
 	/* prepare return value */
 	addk	r3, r0, CURRENT_TASK
 	addk	r3, r0, CURRENT_TASK
@@ -946,13 +950,6 @@ ENTRY(_switch_to)
 ENTRY(_reset)
 ENTRY(_reset)
 	brai	0x70; /* Jump back to FS-boot */
 	brai	0x70; /* Jump back to FS-boot */
 
 
-ENTRY(_break)
-	mfs	r5, rmsr
-	swi	r5, r0, 0x250 + TOPHYS(r0_ram)
-	mfs	r5, resr
-	swi	r5, r0, 0x254 + TOPHYS(r0_ram)
-	bri	0
-
 	/* These are compiled and loaded into high memory, then
 	/* These are compiled and loaded into high memory, then
 	 * copied into place in mach_early_setup */
 	 * copied into place in mach_early_setup */
 	.section	.init.ivt, "ax"
 	.section	.init.ivt, "ax"
@@ -964,12 +961,9 @@ ENTRY(_break)
 	nop
 	nop
 	brai	TOPHYS(_user_exception); /* syscall handler */
 	brai	TOPHYS(_user_exception); /* syscall handler */
 	brai	TOPHYS(_interrupt);	/* Interrupt handler */
 	brai	TOPHYS(_interrupt);	/* Interrupt handler */
-	brai	TOPHYS(_break);		/* nmi trap handler */
+	brai	TOPHYS(_debug_exception);	/* debug trap handler */
 	brai	TOPHYS(_hw_exception_handler);	/* HW exception handler */
 	brai	TOPHYS(_hw_exception_handler);	/* HW exception handler */
 
 
-	.org	0x60
-	brai	TOPHYS(_debug_exception);	/* debug trap handler*/
-
 .section .rodata,"a"
 .section .rodata,"a"
 #include "syscall_table.S"
 #include "syscall_table.S"
 
 

+ 7 - 1
arch/microblaze/kernel/exceptions.c

@@ -48,6 +48,12 @@ void die(const char *str, struct pt_regs *fp, long err)
 	do_exit(err);
 	do_exit(err);
 }
 }
 
 
+/* for user application debugging */
+void sw_exception(struct pt_regs *regs)
+{
+	_exception(SIGTRAP, regs, TRAP_BRKPT, regs->r16);
+}
+
 void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
 void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
 {
 {
 	siginfo_t info;
 	siginfo_t info;
@@ -143,7 +149,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
 #ifdef CONFIG_MMU
 #ifdef CONFIG_MMU
 	case MICROBLAZE_PRIVILEGED_EXCEPTION:
 	case MICROBLAZE_PRIVILEGED_EXCEPTION:
 		pr_debug(KERN_WARNING "Privileged exception\n");
 		pr_debug(KERN_WARNING "Privileged exception\n");
-		/* "brk r0,r0" - used as debug breakpoint */
+		/* "brk r0,r0" - used as debug breakpoint - old toolchain */
 		if (get_user(code, (unsigned long *)regs->pc) == 0
 		if (get_user(code, (unsigned long *)regs->pc) == 0
 			&& code == 0x980c0000) {
 			&& code == 0x980c0000) {
 			_exception(SIGTRAP, regs, TRAP_BRKPT, addr);
 			_exception(SIGTRAP, regs, TRAP_BRKPT, addr);