Module Name:    src
Committed By:   ryo
Date:           Fri May 22 19:29:26 UTC 2020

Modified Files:
        src/sys/arch/aarch64/aarch64: cpuswitch.S db_machdep.c db_trace.c
            vm_machdep.c
        src/sys/arch/aarch64/include: db_machdep.h

Log Message:
fix to do backtrace properly for running LWPs and cpu_lwp_fork().
when dump of pcb_tf, only the switchframe part is now displayed instead of the 
whole trapframe.


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/aarch64/aarch64/cpuswitch.S
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/aarch64/aarch64/db_machdep.c
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/aarch64/aarch64/db_trace.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/aarch64/aarch64/vm_machdep.c
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/aarch64/include/db_machdep.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/aarch64/aarch64/cpuswitch.S
diff -u src/sys/arch/aarch64/aarch64/cpuswitch.S:1.19 src/sys/arch/aarch64/aarch64/cpuswitch.S:1.20
--- src/sys/arch/aarch64/aarch64/cpuswitch.S:1.19	Fri May 15 09:08:10 2020
+++ src/sys/arch/aarch64/aarch64/cpuswitch.S	Fri May 22 19:29:26 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: cpuswitch.S,v 1.19 2020/05/15 09:08:10 ryo Exp $ */
+/* $NetBSD: cpuswitch.S,v 1.20 2020/05/22 19:29:26 ryo Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
 #include "opt_ddb.h"
 #include "opt_kasan.h"
 
-RCSID("$NetBSD: cpuswitch.S,v 1.19 2020/05/15 09:08:10 ryo Exp $")
+RCSID("$NetBSD: cpuswitch.S,v 1.20 2020/05/22 19:29:26 ryo Exp $")
 
 	ARMV8_DEFINE_OPTIONS
 
@@ -60,6 +60,10 @@ ENTRY_NP(cpu_switchto)
 	stp	x25, x26, [sp, #TF_X25]
 	stp	x27, x28, [sp, #TF_X27]
 	stp	x29, x30, [sp, #TF_X29]
+#ifdef DDB
+	str	lr, [sp, #TF_PC]		/* for backtrace */
+	str	xzr, [sp, #TF_SP]		/* mark as switchframe */
+#endif
 
 	/*
 	 * Save the current stack pointer and the CPACR and save them in
@@ -76,6 +80,9 @@ ENTRY_NP(cpu_switchto)
 	DISABLE_INTERRUPT
 	ldr	x6, [x1, #L_PCB]	/* x6 = lwp_getpcb(newlwp) */
 	ldr	x4, [x6, #PCB_TF]	/* get trapframe ptr (aka SP) */
+#ifdef DDB
+	str	xzr, [x6, #PCB_TF]	/* clear l->l_addr->pcb_tf */
+#endif
 	ldr	x5, [x1, #L_MD_CPACR]	/* get cpacr_el1 */
 	mov	sp, x4			/* restore stack pointer */
 	msr	cpacr_el1, x5		/* restore cpacr_el1 */
@@ -190,6 +197,9 @@ ENTRY_NP(cpu_switchto_softint)
 	str	x19, [x3, #CI_CURLWP]	/* curcpu()->ci_curlwp := x19 */
 	ldr	x6, [x19, #L_PCB]	/* x6 = lwp_getpcb(curlwp) */
 	ldr	x4, [x6, #PCB_TF]	/* x4 := pinned_lwp->l_addr->pcb_tf */
+#ifdef DDB
+	str	xzr, [x6, #PCB_TF]	/* clear l->l_addr->pcb_tf */
+#endif
 	ldr	x5, [x19, #L_MD_CPACR]	/* x5 := pinned_lwp->l_md_cpacr */
 	mov	sp, x4			/* restore pinned_lwp sp */
 	msr	cpacr_el1, x5		/* restore pinned_lwp cpacr */

Index: src/sys/arch/aarch64/aarch64/db_machdep.c
diff -u src/sys/arch/aarch64/aarch64/db_machdep.c:1.23 src/sys/arch/aarch64/aarch64/db_machdep.c:1.24
--- src/sys/arch/aarch64/aarch64/db_machdep.c:1.23	Fri May 22 04:46:26 2020
+++ src/sys/arch/aarch64/aarch64/db_machdep.c	Fri May 22 19:29:26 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: db_machdep.c,v 1.23 2020/05/22 04:46:26 ryo Exp $ */
+/* $NetBSD: db_machdep.c,v 1.24 2020/05/22 19:29:26 ryo Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_machdep.c,v 1.23 2020/05/22 04:46:26 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_machdep.c,v 1.24 2020/05/22 19:29:26 ryo Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd32.h"
@@ -264,6 +264,29 @@ dump_trapframe(struct trapframe *tf, voi
 	    tf->tf_reg[30],  tf->tf_sp);
 }
 
+void
+dump_switchframe(struct trapframe *tf, void (*pr)(const char *, ...))
+{
+	struct trapframe tf_buf;
+
+	db_read_bytes((db_addr_t)tf, sizeof(tf_buf), (char *)&tf_buf);
+	tf = &tf_buf;
+
+	(*pr)("   x19=%016"PRIxREGISTER",    x20=%016"PRIxREGISTER"\n",
+	    tf->tf_reg[19], tf->tf_reg[20]);
+	(*pr)("   x21=%016"PRIxREGISTER",    x22=%016"PRIxREGISTER"\n",
+	    tf->tf_reg[21], tf->tf_reg[22]);
+	(*pr)("   x23=%016"PRIxREGISTER",    x24=%016"PRIxREGISTER"\n",
+	    tf->tf_reg[23], tf->tf_reg[24]);
+	(*pr)("   x25=%016"PRIxREGISTER",    x26=%016"PRIxREGISTER"\n",
+	    tf->tf_reg[25], tf->tf_reg[26]);
+	(*pr)("   x27=%016"PRIxREGISTER",    x28=%016"PRIxREGISTER"\n",
+	    tf->tf_reg[27], tf->tf_reg[28]);
+	(*pr)("fp=x29=%016"PRIxREGISTER", lr=x30=%016"PRIxREGISTER"\n",
+	    tf->tf_reg[29], tf->tf_reg[30]);
+}
+
+
 #if defined(_KERNEL)
 static void
 show_cpuinfo(struct cpu_info *ci)
@@ -373,7 +396,7 @@ db_md_lwp_cmd(db_expr_t addr, bool have_
 
 	db_printf("\tl->l_addr.pcb_tf    =%p\n", pcb->pcb_tf);
 	if (pcb->pcb_tf != l->l_md.md_utf)
-		dump_trapframe(pcb->pcb_tf, db_printf);
+		dump_switchframe(pcb->pcb_tf, db_printf);
 	db_printf("\tl->l_md.md_cpacr  =%016" PRIx64 "\n", l->l_md.md_cpacr);
 	db_printf("\tl->l_md.md_flags  =%08x\n", l->l_md.md_flags);
 
@@ -881,7 +904,7 @@ db_md_watch_cmd(db_expr_t addr, bool hav
 volatile struct cpu_info *db_trigger;
 volatile struct cpu_info *db_onproc;
 volatile struct cpu_info *db_newcpu;
-volatile int db_readytoswitch[MAXCPUS];
+volatile struct trapframe *db_readytoswitch[MAXCPUS];
 
 #ifdef _KERNEL
 void
@@ -896,8 +919,9 @@ db_md_switch_cpu_cmd(db_expr_t addr, boo
 
 	if (!have_addr) {
 		for (i = 0; i < ncpu; i++) {
-			if (db_readytoswitch[i] != 0)
-				db_printf("cpu%d: ready\n", i);
+			if (db_readytoswitch[i] != NULL)
+				db_printf("cpu%d: ready. tf=%p\n", i,
+				    db_readytoswitch[i]);
 			else
 				db_printf("cpu%d: not responding\n", i);
 		}
@@ -969,7 +993,7 @@ kdb_trap(int type, struct trapframe *tf)
 		db_trigger = ci;
 		membar_producer();
 	}
-	db_readytoswitch[ci->ci_index] = 1;
+	db_readytoswitch[ci->ci_index] = tf;
 	membar_producer();
 #endif
 
@@ -1024,7 +1048,7 @@ kdb_trap(int type, struct trapframe *tf)
 		__asm __volatile ("sev; sev; sev");
 	}
 	db_trigger = NULL;
-	db_readytoswitch[ci->ci_index] = 0;
+	db_readytoswitch[ci->ci_index] = NULL;
 	membar_producer();
 #endif
 

Index: src/sys/arch/aarch64/aarch64/db_trace.c
diff -u src/sys/arch/aarch64/aarch64/db_trace.c:1.10 src/sys/arch/aarch64/aarch64/db_trace.c:1.11
--- src/sys/arch/aarch64/aarch64/db_trace.c:1.10	Wed May 13 06:08:51 2020
+++ src/sys/arch/aarch64/aarch64/db_trace.c	Fri May 22 19:29:26 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: db_trace.c,v 1.10 2020/05/13 06:08:51 ryo Exp $ */
+/* $NetBSD: db_trace.c,v 1.11 2020/05/22 19:29:26 ryo Exp $ */
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <[email protected]>
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.10 2020/05/13 06:08:51 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.11 2020/05/22 19:29:26 ryo Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -208,12 +208,37 @@ db_stack_trace_print(db_expr_t addr, boo
 		} else
 #endif
 		{
+			struct pcb pcb_buf;
 			struct pcb *pcb = lwp_getpcb(&l);
 
-			tf = pcb->pcb_tf;
-			db_read_bytes((db_addr_t)&tf->tf_reg[29], sizeof(fp), (char *)&fp);
-			(*pr)("trace: pid %d lid %d at tf %p\n",
-			    p.p_pid, l.l_lid, tf);
+			db_read_bytes((db_addr_t)pcb, sizeof(pcb_buf),
+			    (char *)&pcb_buf);
+			tf = pcb_buf.pcb_tf;
+			if (tf != 0) {
+				db_read_bytes((db_addr_t)&tf->tf_reg[29],
+				    sizeof(fp), (char *)&fp);
+				(*pr)("trace: pid %d lid %d at tf %p (in pcb)\n",
+				    p.p_pid, l.l_lid, tf);
+			}
+#if defined(MULTIPROCESSOR) && defined(_KERNEL)
+			else if (l.l_stat == LSONPROC ||
+			    (l.l_pflag & LP_RUNNING) != 0) {
+
+				/* running lwp on other cpus */
+				extern struct trapframe *db_readytoswitch[];
+				struct cpu_info cpuinfobuf;
+
+				db_read_bytes((db_addr_t)l.l_cpu,
+				    sizeof(cpuinfobuf), (char *)&cpuinfobuf);
+				tf = db_readytoswitch[cpuinfobuf.ci_index];
+
+				(*pr)("trace: pid %d lid %d at tf %p (in kdb_trap)\n",
+				    p.p_pid, l.l_lid, tf);
+			}
+#endif
+			else {
+				(*pr)("trace: no trapframe found for lwp: %p\n", (void *)addr);
+			}
 		}
 	} else if (tf == NULL) {
 		fp = addr;
@@ -227,14 +252,20 @@ db_stack_trace_print(db_expr_t addr, boo
 
 	if (tf != NULL) {
 #if defined(_KERNEL)
-		(*pr)("---- trapframe %p (%zu bytes) ----\n",
+		bool is_switchframe = (tf->tf_sp == 0);
+		(*pr)("---- %s %p (%zu bytes) ----\n",
+		    is_switchframe ? "switchframe" : "trapframe",
 		    tf, sizeof(*tf));
-		dump_trapframe(tf, pr);
+		if (is_switchframe)
+			dump_switchframe(tf, pr);
+		else
+			dump_trapframe(tf, pr);
 		(*pr)("------------------------"
 		      "------------------------\n");
 
 #endif
 		lastfp = lastlr = lr = fp = 0;
+
 		db_read_bytes((db_addr_t)&tf->tf_pc, sizeof(lr), (char *)&lr);
 		db_read_bytes((db_addr_t)&tf->tf_reg[29], sizeof(fp), (char *)&fp);
 		lr = aarch64_strip_pac(lr);

Index: src/sys/arch/aarch64/aarch64/vm_machdep.c
diff -u src/sys/arch/aarch64/aarch64/vm_machdep.c:1.6 src/sys/arch/aarch64/aarch64/vm_machdep.c:1.7
--- src/sys/arch/aarch64/aarch64/vm_machdep.c:1.6	Sun Apr 12 07:49:58 2020
+++ src/sys/arch/aarch64/aarch64/vm_machdep.c	Fri May 22 19:29:26 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: vm_machdep.c,v 1.6 2020/04/12 07:49:58 maxv Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.7 2020/05/22 19:29:26 ryo Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -29,8 +29,10 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "opt_ddb.h"
+
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.6 2020/04/12 07:49:58 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.7 2020/05/22 19:29:26 ryo Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -140,6 +142,11 @@ cpu_lwp_fork(struct lwp *l1, struct lwp 
 	ktf->tf_reg[29] = 0;
 	KASSERT(reg_daif_read() == 0);
 	ktf->tf_lr = (uintptr_t)lwp_trampoline;
+#ifdef DDB
+	ktf->tf_pc = (uint64_t)&&backtrace_here;
+	ktf->tf_sp = 0;	/* mark as switchframe */
+ backtrace_here:
+#endif
 
 	pcb2->pcb_tf = ktf;
 }

Index: src/sys/arch/aarch64/include/db_machdep.h
diff -u src/sys/arch/aarch64/include/db_machdep.h:1.8 src/sys/arch/aarch64/include/db_machdep.h:1.9
--- src/sys/arch/aarch64/include/db_machdep.h:1.8	Fri Oct 12 01:28:58 2018
+++ src/sys/arch/aarch64/include/db_machdep.h	Fri May 22 19:29:26 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: db_machdep.h,v 1.8 2018/10/12 01:28:58 ryo Exp $ */
+/* $NetBSD: db_machdep.h,v 1.9 2020/05/22 19:29:26 ryo Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -202,6 +202,7 @@ db_addr_t db_branch_taken(db_expr_t, db_
 
 #define DB_MACHINE_COMMANDS
 void dump_trapframe(struct trapframe *, void (*)(const char *, ...));
+void dump_switchframe(struct trapframe *, void (*)(const char *, ...));
 const char *strdisasm(vaddr_t);
 const char *strdisasm_aarch32(vaddr_t);
 void db_machdep_init(void);

Reply via email to