Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/aarch64 fix to do backtrace properly for running LW...



details:   https://anonhg.NetBSD.org/src/rev/6c50d1a7d490
branches:  trunk
changeset: 933221:6c50d1a7d490
user:      ryo <ryo%NetBSD.org@localhost>
date:      Fri May 22 19:29:26 2020 +0000

description:
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.

diffstat:

 sys/arch/aarch64/aarch64/cpuswitch.S  |  14 ++++++++-
 sys/arch/aarch64/aarch64/db_machdep.c |  40 +++++++++++++++++++++++-----
 sys/arch/aarch64/aarch64/db_trace.c   |  47 +++++++++++++++++++++++++++++-----
 sys/arch/aarch64/aarch64/vm_machdep.c |  11 ++++++-
 sys/arch/aarch64/include/db_machdep.h |   3 +-
 5 files changed, 94 insertions(+), 21 deletions(-)

diffs (278 lines):

diff -r ad94ee612503 -r 6c50d1a7d490 sys/arch/aarch64/aarch64/cpuswitch.S
--- a/sys/arch/aarch64/aarch64/cpuswitch.S      Fri May 22 19:02:59 2020 +0000
+++ b/sys/arch/aarch64/aarch64/cpuswitch.S      Fri May 22 19:29:26 2020 +0000
@@ -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 @@
        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 @@
        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 @@
        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 */
diff -r ad94ee612503 -r 6c50d1a7d490 sys/arch/aarch64/aarch64/db_machdep.c
--- a/sys/arch/aarch64/aarch64/db_machdep.c     Fri May 22 19:02:59 2020 +0000
+++ b/sys/arch/aarch64/aarch64/db_machdep.c     Fri May 22 19:29:26 2020 +0000
@@ -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 @@
            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_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 @@
 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 @@
 
        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 @@
                db_trigger = ci;
                membar_producer();
        }
-       db_readytoswitch[ci->ci_index] = 1;
+       db_readytoswitch[ci->ci_index] = tf;
        membar_producer();
 #endif
 
@@ -1024,7 +1048,7 @@
                __asm __volatile ("sev; sev; sev");
        }
        db_trigger = NULL;
-       db_readytoswitch[ci->ci_index] = 0;
+       db_readytoswitch[ci->ci_index] = NULL;
        membar_producer();
 #endif
 
diff -r ad94ee612503 -r 6c50d1a7d490 sys/arch/aarch64/aarch64/db_trace.c
--- a/sys/arch/aarch64/aarch64/db_trace.c       Fri May 22 19:02:59 2020 +0000
+++ b/sys/arch/aarch64/aarch64/db_trace.c       Fri May 22 19:29:26 2020 +0000
@@ -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 <ryo%nerv.org@localhost>
@@ -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 @@
                } 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 @@
 
        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);
diff -r ad94ee612503 -r 6c50d1a7d490 sys/arch/aarch64/aarch64/vm_machdep.c
--- a/sys/arch/aarch64/aarch64/vm_machdep.c     Fri May 22 19:02:59 2020 +0000
+++ b/sys/arch/aarch64/aarch64/vm_machdep.c     Fri May 22 19:29:26 2020 +0000
@@ -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 @@
        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;
 }
diff -r ad94ee612503 -r 6c50d1a7d490 sys/arch/aarch64/include/db_machdep.h
--- a/sys/arch/aarch64/include/db_machdep.h     Fri May 22 19:02:59 2020 +0000
+++ b/sys/arch/aarch64/include/db_machdep.h     Fri May 22 19:29:26 2020 +0000
@@ -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 @@
 
 #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);



Home | Main Index | Thread Index | Old Index