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 <nakayama.ts@xxxxxxxxxxxxxx> 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 <nakayama.ts@xxxxxxxxxxxxxx> --- 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 <nakayama.ts@xxxxxxxxxxxxxx> 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 <nakayama.ts@xxxxxxxxxxxxxx> --- 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 <nakayama.ts@xxxxxxxxxxxxxx> 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 <nakayama.ts@xxxxxxxxxxxxxx> --- 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 <nakayama.ts@xxxxxxxxxxxxxx> 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 <nakayama.ts@xxxxxxxxxxxxxx> --- 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 Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility