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);