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
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(a)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)
#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()) {
+ 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, ®s,
- 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, ®s,
+ sizeof(struct ppc64_pt_regs),
+ "exception frame", FAULT_ON_ERROR);
+ } else {
+ readmem(req->sp+STACK_FRAME_OVERHEAD, KVADDR, ®s,
+ sizeof(struct ppc64_pt_regs),
+ "exception frame", FAULT_ON_ERROR);
+ }
efrm_str = ppc64_check_eframe(®s);
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