Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP5:Update
crash.16840
crash-Fix-for-the-PPC64-bt-command-for-non-pani...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File crash-Fix-for-the-PPC64-bt-command-for-non-panicking-activ.patch of Package crash.16840
From 3db3d3992d781c1e42587d2d2bf81e785408e0c2 Mon Sep 17 00:00:00 2001 From: Dave Anderson <anderson@redhat.com> Date: Tue, 24 Jan 2017 14:37:03 -0500 Subject: [PATCH] Fix for the PPC64 "bt" command for non-panicking active tasks in FADUMP-generated dumpfiles (Firmware Assisted Dump facility). Without the patch, backtraces of those tasks may be of the form "#0 [c0000000700b3a90] (null) at c0000000700b3b50 (unreliable)". This patch uses and displays the ptregs register set saved in the dumpfile header for the non-panicking active tasks. (hbathini@linux.vnet.ibm.com) --- diskdump.c | 22 ++++++++++ ppc64.c | 133 ++++++++++++++++++++---------------------------------------- 2 files changed, 67 insertions(+), 88 deletions(-) diff --git a/diskdump.c b/diskdump.c index 31cd0d6..0385a9e 100644 --- a/diskdump.c +++ b/diskdump.c @@ -1266,8 +1266,30 @@ get_diskdump_regs_ppc(struct bt_info *bt, ulong *eip, ulong *esp) static void get_diskdump_regs_ppc64(struct bt_info *bt, ulong *eip, ulong *esp) { + int cpu; + Elf64_Nhdr *note; + size_t len; + if ((bt->task == tt->panic_task) && DISKDUMP_VALID()) bt->machdep = &dd->sub_header->elf_regs; + else if (KDUMP_CMPRS_VALID() && + (bt->task == tt->panic_task || + (is_task_active(bt->task) && dd->num_prstatus_notes > 1))) { + cpu = bt->tc->processor; + if (dd->nt_prstatus_percpu[cpu] == NULL) { + if(CRASHDEBUG(1)) + error(INFO, + "registers not collected for cpu %d\n", + cpu); + } else { + note = (Elf64_Nhdr *) + dd->nt_prstatus_percpu[cpu]; + len = sizeof(Elf64_Nhdr); + len = roundup(len + note->n_namesz, 4); + bt->machdep = (void *)((char *)note + len + + MEMBER_OFFSET("elf_prstatus", "pr_reg")); + } + } machdep->get_stack_frame(bt, eip, esp); } diff --git a/ppc64.c b/ppc64.c index 2efa953..1d0a409 100755 --- a/ppc64.c +++ b/ppc64.c @@ -60,18 +60,6 @@ static int is_hugepage(ulong pte); static int is_hugepd(ulong pte); static ulong hugepage_dir(ulong pte); -static inline uint get_ptetype(ulong pte) -{ - uint pte_type = 0; /* 0: regular entry; 1: huge pte; 2: huge pd */ - - if (is_hugepage(pte)) - pte_type = 1; - else if (is_hugepd(pte)) - pte_type = 2; - - return pte_type; -} - static int is_hugepage(ulong pte) { /* @@ -93,6 +81,18 @@ static inline int is_hugepd(ulong pte) return ((pte & PD_HUGE) == 0x0); } +static inline uint get_ptetype(ulong pte) +{ + uint pte_type = 0; /* 0: regular entry; 1: huge pte; 2: huge pd */ + + if (is_hugepage(pte)) + pte_type = 1; + else if (is_hugepd(pte)) + pte_type = 2; + + return pte_type; +} + static inline ulong hugepage_dir(ulong pte) { if (THIS_KERNEL_VERSION >= LINUX(3,10,0)) @@ -1949,66 +1949,11 @@ ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs *regs, } /* - * get SP and IP from the saved ptregs. - */ -static int -ppc64_kdump_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp) -{ - struct ppc64_pt_regs *pt_regs; - unsigned long unip; - - pt_regs = (struct ppc64_pt_regs *)bt_in->machdep; - if (!pt_regs || !pt_regs->gpr[1]) { - /* - * Not collected regs. May be the corresponding CPU not - * responded to an IPI. - */ - fprintf(fp, "%0lx: GPR1 register value (SP) was not saved\n", - bt_in->task); - return FALSE; - } - *ksp = pt_regs->gpr[1]; - if (IS_KVADDR(*ksp)) { - readmem(*ksp+16, KVADDR, &unip, sizeof(ulong), "Regs NIP value", - FAULT_ON_ERROR); - *nip = unip; - } else { - if (IN_TASK_VMA(bt_in->task, *ksp)) - fprintf(fp, "%0lx: Task is running in user space\n", - bt_in->task); - else - fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n", - bt_in->task, *ksp); - *nip = pt_regs->nip; - } - - if (bt_in->flags && - ((BT_TEXT_SYMBOLS|BT_TEXT_SYMBOLS_PRINT|BT_TEXT_SYMBOLS_NOPRINT))) - return TRUE; - - /* - * Print the collected regs for the active task - */ - ppc64_print_regs(pt_regs); - if (!IS_KVADDR(*ksp)) - return FALSE; - - fprintf(fp, " NIP [%016lx] %s\n", pt_regs->nip, - closest_symbol(pt_regs->nip)); - if (unip != pt_regs->link) - fprintf(fp, " LR [%016lx] %s\n", pt_regs->link, - closest_symbol(pt_regs->link)); - - return TRUE; -} - -/* * Get the starting point for the active cpus in a diskdump/netdump. */ static int ppc64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp) { - int panic_task; int i; char *sym; ulong *up; @@ -2021,25 +1966,13 @@ ppc64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp) struct ppc64_pt_regs *pt_regs; struct syment *sp; - /* - * For the kdump vmcore, Use SP and IP values that are saved in ptregs. - */ - if (pc->flags & KDUMP) - return ppc64_kdump_stack_frame(bt_in, nip, ksp); - bt = &bt_local; BCOPY(bt_in, bt, sizeof(struct bt_info)); ms = machdep->machspec; - ur_nip = ur_ksp = 0; - - panic_task = tt->panic_task == bt->task ? TRUE : FALSE; check_hardirq = check_softirq = tt->flags & IRQSTACKS ? TRUE : FALSE; - if (panic_task && bt->machdep) { - pt_regs = (struct ppc64_pt_regs *)bt->machdep; - ur_nip = pt_regs->nip; - ur_ksp = pt_regs->gpr[1]; - } else if (bt->task != tt->panic_task) { + + if (bt->task != tt->panic_task) { char cpu_frozen = FALSE; /* * Determine whether the CPU responded to an IPI. @@ -2158,15 +2091,39 @@ retry: alter_stackbuf(bt); check_intrstack = FALSE; goto retry; - } + } + /* - * We didn't find what we were looking for, so just use what was - * passed in the ELF header. + * We didn't find what we were looking for, so try to use + * the SP and IP values saved in ptregs. */ - if (ur_nip && ur_ksp) { - *nip = ur_nip; - *ksp = ur_ksp; - return TRUE; + pt_regs = (struct ppc64_pt_regs *)bt_in->machdep; + if (!pt_regs || !pt_regs->gpr[1]) { + /* + * Not collected regs. May be the corresponding CPU did not + * respond to an IPI. + */ + if (CRASHDEBUG(1)) + fprintf(fp, "%0lx: GPR1(SP) register value not saved\n", + bt_in->task); + } else { + *ksp = pt_regs->gpr[1]; + if (IS_KVADDR(*ksp)) { + readmem(*ksp+16, KVADDR, nip, sizeof(ulong), + "Regs NIP value", FAULT_ON_ERROR); + ppc64_print_regs(pt_regs); + return TRUE; + } else { + if (IN_TASK_VMA(bt_in->task, *ksp)) + fprintf(fp, "%0lx: Task is running in user space\n", + bt_in->task); + else + fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n", + bt_in->task, *ksp); + *nip = pt_regs->nip; + ppc64_print_regs(pt_regs); + return FALSE; + } } console("ppc64_get_dumpfile_stack_frame: cannot find SP for panic task\n");
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor