On OPAL based systems, when a thread is running an OPAL API, the stack
pointer and instruction pointer would be pointing at OPAL address but
'bt' output for such thread would complain that the stack pointer is
invalid. Update error/log message for better context.
Signed-off-by: Hari Bathini <hbathini(a)linux.ibm.com>
---
ppc64.c | 36 ++++++++++++++++++++++++++++++++----
1 file changed, 32 insertions(+), 4 deletions(-)
diff --git a/ppc64.c b/ppc64.c
index cf41765..041480b 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -65,8 +65,26 @@ static ulong hugepage_dir(ulong pte);
static ulong pgd_page_vaddr_l4(ulong pgd);
static ulong pud_page_vaddr_l4(ulong pud);
static ulong pmd_page_vaddr_l4(ulong pmd);
+static int is_opal_context(ulong sp, ulong nip);
void opalmsg(void);
+static int is_opal_context(ulong sp, ulong nip)
+{
+ uint64_t opal_start, opal_end;
+
+ if (!(machdep->flags & OPAL_FW))
+ return FALSE;
+
+ opal_start = machdep->machspec->opal.base;
+ opal_end = opal_start + machdep->machspec->opal.size;
+
+ if (((sp >= opal_start) && (sp < opal_end)) ||
+ ((nip >= opal_start) && (nip < opal_end)))
+ return TRUE;
+
+ return FALSE;
+}
+
static inline int is_hugepage(ulong pte)
{
if ((machdep->flags & BOOK3E) ||
@@ -2270,7 +2288,11 @@ ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong
*ksp)
{
struct ppc64_pt_regs *pt_regs;
unsigned long unip;
- int in_user_space = FALSE;
+ /*
+ * TRUE: task is running in a different context (userspace, OPAL..)
+ * FALSE: task is probably running in kernel space.
+ */
+ int out_of_context = FALSE;
pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
if (!pt_regs || !pt_regs->gpr[1]) {
@@ -2283,20 +2305,25 @@ ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong
*ksp)
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 {
+ *nip = pt_regs->nip;
if (IN_TASK_VMA(bt_in->task, *ksp)) {
fprintf(fp, "%0lx: Task is running in user space\n",
bt_in->task);
- in_user_space = TRUE;
+ out_of_context = TRUE;
+ } else if (is_opal_context(*ksp, *nip)) {
+ fprintf(fp, "%0lx: Task is running in OPAL (firmware) context\n",
+ bt_in->task);
+ out_of_context = TRUE;
} else
fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
bt_in->task, *ksp);
- *nip = pt_regs->nip;
}
if (bt_in->flags &&
@@ -2307,7 +2334,8 @@ ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong
*ksp)
* Print the collected regs for the active task
*/
ppc64_print_regs(pt_regs);
- if (in_user_space)
+
+ if (out_of_context)
return TRUE;
if (!IS_KVADDR(*ksp))
return FALSE;