(2012/06/23 0:36), Dave Anderson wrote:
----- Original Message -----
OK, doing it that way looks reasonable, and safely segregated to PPC only. Just two more suggestions -- first, please do me a favor by running "make warn" prior to posting a patch, and fix these: $ make warn TARGET: X86_64 CRASH: 6.0.8rc15 GDB: 7.3.1 cc -c -g -DX86_64 -DGDB_7_3_1 build_data.c -Wall -O2 -Wstrict-prototypes -Wmissing-prototypes -fstack-protector cc -c -g -DX86_64 -DGDB_7_3_1 ppc.c -Wall -O2 -Wstrict-prototypes -Wmissing-prototypes -fstack-protector cc -c -g -DX86_64 -DGDB_7_3_1 netdump.c -Wall -O2 -Wstrict-prototypes -Wmissing-prototypes -fstack-protector netdump.c: In function 'get_netdump_regs_ppc': netdump.c:2603: warning: pointer targets in passing argument 2 of 'relocate_nt_prstatus_percpu_ppc' differ in signedness cc -c -g -DX86_64 -DGDB_7_3_1 diskdump.c -Wall -O2 -Wstrict-prototypes -Wmissing-prototypes -fstack-protector diskdump.c:1061: warning: no previous prototype for ‘relocate_nt_prstatus_percpu_ppc’ diskdump.c: In function 'get_diskdump_regs_ppc': diskdump.c:1103: warning: pointer targets in passing argument 2 of 'relocate_nt_prstatus_percpu_ppc' differ in signedness ...
Thanks for your checking out. I shuold use unit * for argument 2.
Secondly, since your new relocate_nt_prstatus_percpu_ppc() and verify_crash_note_in_kernel_ppc() functions are used for both kdump ELF and compressed kdump formats, and since they are PPC-specific, can you just move the two functions into ppc.c? All that should require is to #include elf.h.
Make sense. I move them into ppc.c, then function calls in diskdump.c and netdump.c are wrapped with "if defined (PPC)" so that those lines will be invalid when other arch is build (x86_64 build was no problem). I remake and attach patch. Thanks, Toshi
Thanks, Dave -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility
Date: Thu, 21 Jun 2012 10:39:45 +0900 Subject: [PATCH] ppc: fix up back trace for panic or active tasks problem When dump file is not contained enough NT_PRSTATUS notes for all online cpus, ppc diskdump and netdump can not do correct "bt". Relocate NT_PRSTATUS instances into corresponding cpu maps. This can do only once when first "bt" command is required. I couldn't found out good entry point for this while initialization time. Signed-off-by: Toshikazu Nakayama <nakayama.ts@xxxxxxxxxxxxxx> --- defs.h | 1 + diskdump.c | 7 ++++- netdump.c | 4 +++ ppc.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 1 deletions(-) diff --git a/defs.h b/defs.h index 2145312..09e1bed 100755 --- a/defs.h +++ b/defs.h @@ -4746,6 +4746,7 @@ void ppc64_dump_machdep_table(ulong); #ifdef PPC void ppc_init(int); void ppc_dump_machdep_table(ulong); +void ppc_relocate_nt_prstatus_percpu(void **, uint *); #define display_idt_table() \ error(FATAL, "-d option is not applicable to PowerPC architecture\n") #define KSYMS_START (0x1) diff --git a/diskdump.c b/diskdump.c index e3f04e8..79dc131 100644 --- a/diskdump.c +++ b/diskdump.c @@ -1018,6 +1018,11 @@ get_diskdump_regs_ppc(struct bt_info *bt, ulong *eip, ulong *esp) Elf32_Nhdr *note; int len; +#if defined (PPC) + if (KDUMP_CMPRS_VALID()) + ppc_relocate_nt_prstatus_percpu(dd->nt_prstatus_percpu, + &dd->num_prstatus_notes); +#endif if (KDUMP_CMPRS_VALID() && (bt->task == tt->panic_task || (is_task_active(bt->task) && dd->num_prstatus_notes > 1))) { @@ -1030,7 +1035,7 @@ get_diskdump_regs_ppc(struct bt_info *bt, ulong *eip, ulong *esp) "panic" : "active", bt->task); len = sizeof(Elf32_Nhdr); len = roundup(len + note->n_namesz, 4); - bt->machdep = (void *)((char *)note + len + + bt->machdep = (void *)((char *)note + len + MEMBER_OFFSET("elf_prstatus", "pr_reg")); } diff --git a/netdump.c b/netdump.c index 51bbc35..faed2ec 100644 --- a/netdump.c +++ b/netdump.c @@ -2595,6 +2595,10 @@ get_netdump_regs_ppc(struct bt_info *bt, ulong *eip, ulong *esp) Elf32_Nhdr *note; size_t len; +#if defined (PPC) + ppc_relocate_nt_prstatus_percpu(nd->nt_prstatus_percpu, + &nd->num_prstatus_notes); +#endif if ((bt->task == tt->panic_task) || (is_task_active(bt->task) && nd->num_prstatus_notes > 1)) { /* diff --git a/ppc.c b/ppc.c index bc5f201..90fe246 100755 --- a/ppc.c +++ b/ppc.c @@ -16,6 +16,7 @@ */ #ifdef PPC #include "defs.h" +#include <elf.h> #define MAX_PLATFORM_LEN 32 /* length for platform string */ @@ -414,6 +415,8 @@ ppc_init(int when) symbol_exists("hardirq_ctx")) STRUCT_SIZE_INIT(irq_ctx, "hardirq_ctx"); + STRUCT_SIZE_INIT(note_buf, "note_buf_t"); + STRUCT_SIZE_INIT(elf_prstatus, "elf_prstatus"); break; case POST_INIT: @@ -1932,4 +1935,79 @@ try_closest: } } } + +/* + * Try to relocate NT_PRSTATUS notes according by in kernel crash_notes. + * Function is only called from ppc's get_regs. + */ +static int +verify_crash_note_in_kernel(int cpu) +{ + int ret; + Elf32_Nhdr *note32; + ulong crash_notes_ptr; + char *buf, *name; + + ret = TRUE; + if (!readmem(symbol_value("crash_notes"), KVADDR, &crash_notes_ptr, + sizeof(ulong), "crash_notes", QUIET|RETURN_ON_ERROR) || + !crash_notes_ptr) + goto out; + + buf = GETBUF(SIZE(note_buf)); + if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF)) + crash_notes_ptr += kt->__per_cpu_offset[cpu]; + if (!readmem(crash_notes_ptr, KVADDR, buf, SIZE(note_buf), + "cpu crash_notes", QUIET|RETURN_ON_ERROR)) + goto freebuf; + + note32 = (Elf32_Nhdr *)buf; + name = (char *)(note32 + 1); + if (note32->n_type != NT_PRSTATUS || + note32->n_namesz != strlen("CORE") + 1 || + strncmp(name, "CORE", note32->n_namesz) || + note32->n_descsz != SIZE(elf_prstatus)) + ret = FALSE; +freebuf: + FREEBUF(buf); +out: + return ret; +} + +void +ppc_relocate_nt_prstatus_percpu(void **nt_prstatus_percpu, + uint *num_prstatus_notes) +{ + static int relocated = FALSE; + void **nt_ptr; + int i, j, nrcpus; + size_t size; + + /* relocation is possible only once */ + if (relocated == TRUE) + return; + relocated = TRUE; + if (!symbol_exists("crash_notes") || + !VALID_STRUCT(note_buf) || !VALID_STRUCT(elf_prstatus)) + return; + + size = NR_CPUS * sizeof(void *); + nt_ptr = (void **)GETBUF(size); + BCOPY(nt_prstatus_percpu, nt_ptr, size); + BZERO(nt_prstatus_percpu, size); + + *num_prstatus_notes = 0; + nrcpus = (kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS : NR_CPUS); + for (i = 0, j = 0; i < nrcpus; i++) { + if (!in_cpu_map(ONLINE, i)) + continue; + if (verify_crash_note_in_kernel(i)) + nt_prstatus_percpu[i] = nt_ptr[j++]; + else if (CRASHDEBUG(1)) + error(WARNING, "cpu#%d: not saved crash_notes\n", i); + /* num_prstatus_notes is always equal to online cpus in ppc */ + (*num_prstatus_notes)++; + } + FREEBUF(nt_ptr); +} #endif /* PPC */ -- 1.7.0.4
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility