On Wed, Sep 18, 2024 at 3:37 PM <devel-request@lists.crash-utility.osci.io> wrote:
Date: Wed, 18 Sep 2024 11:42:05 +1200
From: Tao Liu <ltao@redhat.com>
Subject: [Crash-utility] [PATCH v1 3/3] ppc64: fix the bug eframe
        won't print for newer kernel
To: devel@lists.crash-utility.osci.io
Cc: adityag@linux.ibm.com,      Tao Liu <ltao@redhat.com>
Message-ID: <20240917234205.7783-4-ltao@redhat.com>
Content-Type: text/plain; charset="US-ASCII"; x-default=true

The value of EXCP_FRAME_MARKER is outdated for kernel>=6.1.0, and also
its offset is changed since kernel>=6.2.0. This patch will fix the issue

Can you help to add the related kernel commits to the patch log?
Otherwise I have to find it and check why the crash tool needs to be changed.

by updating its values.

Before:
  crash> bt
    ...
    #8 [c00000000a327b80] system_call_exception at c000000000031a30
    #9 [c00000000a327e50] system_call_vectored_common at c00000000000d05c

After:
  crash> bt
    ...
    #8 [c00000000a327b80] system_call_exception at c000000000031a30
    #9 [c00000000a327e50] system_call_vectored_common at c00000000000d05c
    System Call Vectored [3000] exception frame:
    R0:  0000000000000004    R1:  00007fffc3345f40    R2:  0000000000100000
    R3:  0000000000000001    R4:  000000012572c620    R5:  0000000000000002
    R6:  0000000000000001    R7:  0000000000000004    R8:  0000000000000001
    ...

Signed-off-by: Tao Liu <ltao@redhat.com>
---
 defs.h  |  5 ++++-
 ppc64.c | 37 +++++++++++++++++++++++++++----------
 2 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/defs.h b/defs.h
index d5cb8cc..ceeb6cc 100644
--- a/defs.h
+++ b/defs.h
@@ -4645,7 +4645,10 @@ struct efi_memory_desc_t {

 #define STACK_SWITCH_FRAME_REGS         48
 #define STACK_FRAME_OVERHEAD            112
-#define EXCP_FRAME_MARKER               0x7265677368657265
+#define EXCP_FRAME_MARKER \
+       (THIS_KERNEL_VERSION >= LINUX(6,1,0) ? \
+         (__BYTE_ORDER == __BIG_ENDIAN ? 0x52454753 : 0x53474552) : \
+       0x7265677368657265)

 
Here, a code comment is needed, where does the magic number come from?

 #define _SECTION_SIZE_BITS     24
 #define _MAX_PHYSMEM_BITS      44
diff --git a/ppc64.c b/ppc64.c
index 8af7b8a..5416281 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -2217,19 +2217,34 @@ ppc64_back_trace(struct gnu_request *req, struct bt_info *bt)
                                eframe_found = TRUE;
                        else if (STREQ(req->name, ".ret_from_except"))
                                eframe_found = TRUE;
-               } else if ((newsp - req->sp - STACK_FRAME_OVERHEAD) >=
-                               sizeof(struct ppc64_pt_regs)) {
-                        readmem(req->sp+0x60, KVADDR, &marker,
-                               sizeof(ulong), "stack frame", FAULT_ON_ERROR);
-                       if (marker == EXCP_FRAME_MARKER)
-                               eframe_found = TRUE;
+               } else if (THIS_KERNEL_VERSION >= LINUX(6,2,0) && is_ppc64_elf_abi_v2()) {

Looks like there is no better way? Can you help to describe the details?

Thanks
Lianbo

+                       if ((newsp - req->sp - STACK_SWITCH_FRAME_REGS) >=
+                           sizeof(struct ppc64_pt_regs)) {
+                               readmem(req->sp+0x20, KVADDR, &marker,
+                                       sizeof(ulong), "stack frame",
+                                       FAULT_ON_ERROR);
+                       }
+               } else {
+                       if ((newsp - req->sp - STACK_FRAME_OVERHEAD) >=
+                           sizeof(struct ppc64_pt_regs)) {
+                               readmem(req->sp+0x60, KVADDR, &marker,
+                                       sizeof(ulong), "stack frame",
+                                       FAULT_ON_ERROR);
+                       }
                }
-               if (eframe_found) {
+
+               if (eframe_found || marker == EXCP_FRAME_MARKER) {
                        char *efrm_str = NULL;
                        struct ppc64_pt_regs regs;
-                       readmem(req->sp+STACK_FRAME_OVERHEAD, KVADDR, &regs,
-                               sizeof(struct ppc64_pt_regs),
-                               "exception frame", FAULT_ON_ERROR);
+                       if (THIS_KERNEL_VERSION >= LINUX(6,2,0) && is_ppc64_elf_abi_v2()) {
+                               readmem(req->sp+STACK_SWITCH_FRAME_REGS, KVADDR, &regs,
+                                       sizeof(struct ppc64_pt_regs),
+                                       "exception frame", FAULT_ON_ERROR);
+                       } else {
+                               readmem(req->sp+STACK_FRAME_OVERHEAD, KVADDR, &regs,
+                                       sizeof(struct ppc64_pt_regs),
+                                       "exception frame", FAULT_ON_ERROR);
+                       }

                        efrm_str = ppc64_check_eframe(&regs);
                        if (efrm_str) {
@@ -2440,6 +2455,8 @@ ppc64_check_eframe(struct ppc64_pt_regs *regs)
                return("Denormalisation");
        case 0x1700:   
                return("Altivec Assist");
+       case 0x3000:
+               return("System Call Vectored");
        }

        /* No exception frame exists */
--
2.40.1