Hello Dave,
I'm trying to use crash configured with PPC on linux-2.6.27 powerpc.
And when crash started with /dev/mem, I found some problems and fixed them.
I'm afraid that PPC32 is now not maintained for long time,
most people use PPC64 only?
I don't know true reason but if possible, please check attached patch set.
Report of problems which I met as below:
[problem 1] Display type mismatch WARNING
WARNING: machine type mismatch:
crash utility: PPC
vmlinux: (unknown)
-> Simply lacking of verification, remove WARNING with 0001
[problem 2] Display vmalloc fault WARNING
WARNING: cannot access vmalloc'd module memory
-> PTE index was wrong, fix with 0002
[problem 3] Repeat "invalid task address in pid_hash:" 500 times
crash: invalid task address in pid_hash: c8818450
-> Alignment check was too old, fix with 0003
[problem 4] bt command is always SEGV while accessing stack frame
-> Similar to problem 3, fix with 0004
I continue to test the basic command regressions or
update PPC implementation by learning from PPC64.
Thanks,
Toshi
>From 7093d0859d3e09eb1c4b96255aacbbeca536eb01 Mon Sep 17 00:00:00 2001
From: Toshikazu Nakayama <[email protected]>
Date: Mon, 24 Oct 2011 17:08:11 +0900
Subject: [PATCH 1/4] Be possible to verify EM_PPC kernel
Add the machine type of EM_PPC at is_kernel().
Signed-off-by: Toshikazu Nakayama <[email protected]>
---
symbols.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/symbols.c b/symbols.c
index 3b7b3f0..ce5fc7e 100755
--- a/symbols.c
+++ b/symbols.c
@@ -2906,6 +2906,11 @@ is_kernel(char *file)
goto bailout;
break;
+ case EM_PPC:
+ if (machine_type_mismatch(file, "PPC", NULL, 0))
+ goto bailout;
+ break;
+
default:
if (machine_type_mismatch(file, "(unknown)", NULL, 0))
goto bailout;
--
1.7.7.rc0.72.g4b5ea
>From 985d1cceaf2aa7fdde84140317c57e91cd809571 Mon Sep 17 00:00:00 2001
From: Toshikazu Nakayama <[email protected]>
Date: Mon, 24 Oct 2011 17:12:55 +0900
Subject: [PATCH 2/4] ppc: fix corrupted PTE translation
The PTE index value is set with (ulong) cast.
Must be with (ulong *).
Signed-off-by: Toshikazu Nakayama <[email protected]>
---
ppc.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/ppc.c b/ppc.c
index 4223ca2..f3d8646 100755
--- a/ppc.c
+++ b/ppc.c
@@ -300,9 +300,10 @@ ppc_uvtop(struct task_context *tc, ulong vaddr, physaddr_t *paddr, int verbose)
if (machdep->flags & CPU_BOOKE)
page_table = page_middle + (BTOP(vaddr) & (PTRS_PER_PTE - 1));
- else
- page_table = (ulong *)(((pgd_pte & (ulong)machdep->pagemask) + machdep->kvbase) +
- ((ulong)BTOP(vaddr) & (PTRS_PER_PTE-1)));
+ else {
+ page_table = (ulong *)((pgd_pte & (ulong)machdep->pagemask) + machdep->kvbase);
+ page_table += ((ulong)BTOP(vaddr) & (PTRS_PER_PTE-1));
+ }
if (verbose)
fprintf(fp, " PMD: %lx => %lx\n",(ulong)page_middle,
@@ -388,9 +389,10 @@ ppc_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose)
if (machdep->flags & CPU_BOOKE)
page_table = page_middle + (BTOP(kvaddr) & (PTRS_PER_PTE - 1));
- else
- page_table = (ulong *)(((pgd_pte & (ulong)machdep->pagemask) + machdep->kvbase) +
- ((ulong)BTOP(kvaddr) & (PTRS_PER_PTE-1)));
+ else {
+ page_table = (ulong *)((pgd_pte & (ulong)machdep->pagemask) + machdep->kvbase);
+ page_table += ((ulong)BTOP(kvaddr) & (PTRS_PER_PTE-1));
+ }
if (verbose)
fprintf(fp, " PMD: %lx => %lx\n", (ulong)page_middle,
--
1.7.7.rc0.72.g4b5ea
>From 4147834bf6756e428fa4b9b923dccb7414762670 Mon Sep 17 00:00:00 2001
From: Toshikazu Nakayama <[email protected]>
Date: Mon, 24 Oct 2011 17:34:02 +0900
Subject: [PATCH 3/4] ppc: update ppc_is_task_addr()
If (tt->flags & THREAD_INFO), task_struct is not stacksize-aligned.
Fix like x86.
Signed-off-by: Toshikazu Nakayama <[email protected]>
---
ppc.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/ppc.c b/ppc.c
index f3d8646..2bc1562 100755
--- a/ppc.c
+++ b/ppc.c
@@ -436,7 +436,8 @@ ppc_vmalloc_start(void)
}
/*
- * PPC allows the idle_task to be non-page aligned, so we have to make
+ * PPC tasks are all stacksize-aligned, except when split from the stack.
+ * PPC also allows the idle_task to be non-page aligned, so we have to make
* an additional check through the idle_threads array.
*/
static int
@@ -444,7 +445,9 @@ ppc_is_task_addr(ulong task)
{
int i;
- if (IS_KVADDR(task) && (ALIGNED_STACK_OFFSET(task) == 0))
+ if (tt->flags & THREAD_INFO)
+ return IS_KVADDR(task);
+ else if (IS_KVADDR(task) && (ALIGNED_STACK_OFFSET(task) == 0))
return TRUE;
for (i = 0; i < kt->cpus; i++)
--
1.7.7.rc0.72.g4b5ea
>From 693aaab8cfb4fa98c6410a7fed0af7666921a7ba Mon Sep 17 00:00:00 2001
From: Toshikazu Nakayama <[email protected]>
Date: Mon, 24 Oct 2011 17:40:29 +0900
Subject: [PATCH 4/4] ppc: update get_ppc_frame()
If (tt->flags & THREAD_INFO), backtrace got SEGV.
Don't use task pointer with stack base.
Apply reading pt_regs to instruction get, definie frame overhead and stack
size macros, skip __switch_to frame in bt, like PPC64.
Signed-off-by: Toshikazu Nakayama <[email protected]>
---
defs.h | 3 +++
ppc.c | 50 ++++++++++++++++++++++++++++----------------------
2 files changed, 31 insertions(+), 22 deletions(-)
diff --git a/defs.h b/defs.h
index a9a158d..d6231e1 100755
--- a/defs.h
+++ b/defs.h
@@ -2610,6 +2610,9 @@ struct load_module {
#define _SECTION_SIZE_BITS 24
#define _MAX_PHYSMEM_BITS 44
+#define STACK_FRAME_OVERHEAD 16
+#define PPC_STACK_SIZE 8192
+
#endif /* PPC */
#ifdef IA64
diff --git a/ppc.c b/ppc.c
index 2bc1562..a8e7193 100755
--- a/ppc.c
+++ b/ppc.c
@@ -64,7 +64,7 @@ ppc_init(int when)
machdep->pageshift = ffs(machdep->pagesize) - 1;
machdep->pageoffset = machdep->pagesize - 1;
machdep->pagemask = ~((ulonglong)machdep->pageoffset);
- machdep->stacksize = machdep->pagesize * 2;
+ machdep->stacksize = PPC_STACK_SIZE;
if ((machdep->pgd = (char *)malloc(PAGESIZE())) == NULL)
error(FATAL, "cannot malloc pgd space.");
machdep->pmd = machdep->pgd;
@@ -1023,7 +1023,9 @@ get_ppc_frame(struct bt_info *bt, ulong *getpc, ulong *getsp)
ulong offset;
ulong *stack;
ulong task;
+ struct ppc_pt_regs regs;
+ ip = 0;
task = bt->task;
stack = (ulong *)bt->stackbuf;
@@ -1036,27 +1038,31 @@ get_ppc_frame(struct bt_info *bt, ulong *getpc, ulong *getsp)
else
sp = stack[OFFSET(task_struct_thread_ksp)/sizeof(long)];
- /*
- * get the offset to the first pointer in the stack frame
- * linked list. here is a small picture:
- *
- * ksp
- * >c73e9d30: c73e9d50 c007efbc 00000000 00000008
- * ^^^^^^^^ = Pointer to first stack frame.
- * c73e9d40: c0742000 00000000 c02071e0 c73e9d50
- * >c73e9d50: c73e9d80 c0013928 c73e8000 c73e9d60
- * ^^^^^^^^ ^^^^^^^^ Pointer to return function
- * | (LR save word)
- * \-----------> Pointer to next stack frame
- * c73e9d60: c73e9d80 c73e9e10 c01e0000 00000007
- * c73e9d70: 00000000 00000000 7fffffff c73e9d80
- */
-
- offset = (stack[(sp-task)/sizeof(long)]-task)/sizeof(long);
-
- sp = stack[offset];
- ip = stack[(sp - task)/sizeof(long)+1];
-
+ if (!INSTACK(sp, bt))
+ goto out;
+
+ readmem(sp + STACK_FRAME_OVERHEAD, KVADDR, ®s,
+ sizeof(struct ppc_pt_regs),
+ "PPC pt_regs", FAULT_ON_ERROR);
+ ip = regs.nip;
+ if (STREQ(closest_symbol(ip), "__switch_to")) {
+ /* NOTE: _switch_to() calls _switch() which
+ * is asm. _switch leaves pc == lr.
+ * Working through this frame is tricky,
+ * and this mess isn't going to help if we
+ * actually dumped here. Most likely the
+ * analyzer is trying to backtrace a task.
+ * Need to skip 2 frames.
+ */
+ sp = stack[(sp - bt->stackbase)/sizeof(ulong)];
+ if (!INSTACK(sp, bt))
+ goto out;
+ sp = stack[(sp - bt->stackbase)/sizeof(ulong)];
+ if (!INSTACK(sp + 4, bt))
+ goto out;
+ ip = stack[(sp + 4 - bt->stackbase)/sizeof(ulong)];
+ }
+out:
if (DUMPFILE() && getsp && STREQ(closest_symbol(sp), "panic")) {
*getsp = sp;
return;
--
1.7.7.rc0.72.g4b5ea
--
Crash-utility mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility