Co-developed-by: Alexey Makhalov <alexey.makha...@broadcom.com>
Co-developed-by: Tao Liu <l...@redhat.com>
Signed-off-by: Tao Liu <l...@redhat.com>
---
 ppc64.c | 43 +++++++++++++++++++++++++++++++++++++------
 1 file changed, 37 insertions(+), 6 deletions(-)

diff --git a/ppc64.c b/ppc64.c
index 532eb3f..fec3b2a 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -2053,6 +2053,7 @@ ppc64_back_trace_cmd(struct bt_info *bt)
        char buf[BUFSIZE];
        struct gnu_request *req;
        extern void print_stack_text_syms(struct bt_info *, ulong, ulong);
+       extra_stacks_idx = 0;
 
         bt->flags |= BT_EXCEPTION_FRAME;
 
@@ -2071,6 +2072,24 @@ ppc64_back_trace_cmd(struct bt_info *bt)
         req->pc = bt->instptr;
         req->sp = bt->stkptr;
 
+       if (tt->panic_task == bt->task) {
+               struct ppc64_pt_regs *pr = (struct ppc64_pt_regs *)bt->machdep;
+               if (pr->nip != req->pc || pr->gpr[1] != req->sp) {
+                       if (!extra_stacks_regs[extra_stacks_idx]) {
+                               extra_stacks_regs[extra_stacks_idx] =
+                                       (struct user_regs_bitmap_struct *)
+                                       GETBUF(sizeof(struct 
user_regs_bitmap_struct *));
+                       }
+                       extra_stacks_regs[extra_stacks_idx]->ur.nip = req->pc;
+                       extra_stacks_regs[extra_stacks_idx]->ur.gpr[1] = 
req->sp;
+                       SET_BIT(extra_stacks_regs[extra_stacks_idx]->bitmap,
+                               REG_SEQ(ppc64_pt_regs, nip));
+                       SET_BIT(extra_stacks_regs[extra_stacks_idx]->bitmap,
+                               REG_SEQ(ppc64_pt_regs, gpr[0]) + 1);
+                       gdb_add_substack (extra_stacks_idx++);
+               }
+       }
+
        if (bt->flags &
        (BT_TEXT_SYMBOLS|BT_TEXT_SYMBOLS_PRINT|BT_TEXT_SYMBOLS_NOPRINT)) {
                if (!INSTACK(req->sp, bt))
@@ -2552,6 +2571,12 @@ ppc64_get_current_task_reg(int regno, const char *name, 
int size,
        tc = CURRENT_CONTEXT();
        if (!tc)
                return FALSE;
+
+       if (sid && sid <= extra_stacks_idx) {
+               ur_bitmap = extra_stacks_regs[sid - 1];
+               goto get_sub;
+       }
+
        BZERO(&bt_setup, sizeof(struct bt_info));
        clone_bt_info(&bt_setup, &bt_info, tc);
        fill_stackbuf(&bt_info);
@@ -2570,39 +2595,45 @@ ppc64_get_current_task_reg(int regno, const char *name, 
int size,
                goto get_all;
        }
 
+get_sub:
        switch (regno) {
        case PPC64_R0_REGNUM ... PPC64_R31_REGNUM:
                if (!NUM_IN_BITMAP(ur_bitmap->bitmap,
                    REG_SEQ(ppc64_pt_regs, gpr[0]) + regno - PPC64_R0_REGNUM)) {
-                       FREEBUF(ur_bitmap);
+                       if (!sid)
+                               FREEBUF(ur_bitmap);
                        return FALSE;
                }
                break;
        case PPC64_PC_REGNUM:
                if (!NUM_IN_BITMAP(ur_bitmap->bitmap,
                    REG_SEQ(ppc64_pt_regs, nip))) {
-                       FREEBUF(ur_bitmap);
+                       if (!sid)
+                               FREEBUF(ur_bitmap);
                        return FALSE;
                }
                break;
        case PPC64_MSR_REGNUM:
                if (!NUM_IN_BITMAP(ur_bitmap->bitmap,
                    REG_SEQ(ppc64_pt_regs, msr))) {
-                       FREEBUF(ur_bitmap);
+                       if (!sid)
+                               FREEBUF(ur_bitmap);
                        return FALSE;
                }
                break;
        case PPC64_LR_REGNUM:
                if (!NUM_IN_BITMAP(ur_bitmap->bitmap,
                    REG_SEQ(ppc64_pt_regs, link))) {
-                       FREEBUF(ur_bitmap);
+                       if (!sid)
+                               FREEBUF(ur_bitmap);
                        return FALSE;
                }
                break;
        case PPC64_CTR_REGNUM:
                if (!NUM_IN_BITMAP(ur_bitmap->bitmap,
                    REG_SEQ(ppc64_pt_regs, ctr))) {
-                       FREEBUF(ur_bitmap);
+                       if (!sid)
+                               FREEBUF(ur_bitmap);
                        return FALSE;
                }
                break;
@@ -2645,7 +2676,7 @@ get_all:
                ret = TRUE;
                break;
        }
-       if (bt_info.need_free) {
+       if (!sid && bt_info.need_free) {
                FREEBUF(ur_bitmap);
                bt_info.need_free = FALSE;
        }
-- 
2.47.0
--
Crash-utility mailing list -- devel@lists.crash-utility.osci.io
To unsubscribe send an email to devel-le...@lists.crash-utility.osci.io
https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
Contribution Guidelines: https://github.com/crash-utility/crash/wiki

Reply via email to