This patch adds support for reading the register set on PPC32, from the ELF note in a dump. Signed-off-by: Suzuki K. Poulose <suzuki@xxxxxxxxxx> --- netdump.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 71 insertions(+), 0 deletions(-) diff --git a/netdump.c b/netdump.c index c0ee9ae..f7bf7d8 100644 --- a/netdump.c +++ b/netdump.c @@ -33,6 +33,7 @@ static size_t dump_Elf32_Nhdr(Elf32_Off offset, int); static void dump_Elf64_Ehdr(Elf64_Ehdr *); static void dump_Elf64_Phdr(Elf64_Phdr *, int); static size_t dump_Elf64_Nhdr(Elf64_Off offset, int); +static void get_netdump_regs_ppc(struct bt_info *, ulong *, ulong *); static void get_netdump_regs_ppc64(struct bt_info *, ulong *, ulong *); static void get_netdump_regs_arm(struct bt_info *, ulong *, ulong *); static physaddr_t xen_kdump_p2m(physaddr_t); @@ -2172,6 +2173,10 @@ get_netdump_regs(struct bt_info *bt, ulong *eip, ulong *esp) machdep->get_stack_frame(bt, eip, esp); break; + case EM_PPC: + return get_netdump_regs_ppc(bt, eip, esp); + break; + case EM_PPC64: return get_netdump_regs_ppc64(bt, eip, esp); break; @@ -2551,6 +2556,40 @@ next_sysrq: } static void +get_netdump_regs_ppc(struct bt_info *bt, ulong *eip, ulong *esp) +{ + Elf32_Nhdr *note; + size_t len; + + if ((bt->task == tt->panic_task) || + (is_task_active(bt->task) && nd->num_prstatus_notes > 1)) { + /* + * Registers are saved during the dump process for the + * panic task. Whereas in kdump, regs are captured for all + * CPUs if they responded to an IPI. + */ + if (nd->num_prstatus_notes > 1) { + if (!nd->nt_prstatus_percpu[bt->tc->processor]) + error(FATAL, + "cannot determine NT_PRSTATUS ELF note " + "for %s task: %lx\n", + (bt->task == tt->panic_task) ? + "panic" : "active", bt->task); + note = (Elf32_Nhdr *) + nd->nt_prstatus_percpu[bt->tc->processor]; + } else + note = (Elf32_Nhdr *)nd->nt_prstatus; + + len = sizeof(Elf32_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); +} + +static void get_netdump_regs_ppc64(struct bt_info *bt, ulong *eip, ulong *esp) { Elf64_Nhdr *note; @@ -2838,6 +2877,7 @@ xen_minor_version(void) * Contributed by: Sharyathi Nagesh (sharyath@xxxxxxxxxx) */ +static void *get_ppc_regs_from_elf_notes(struct task_context *); static void *get_ppc64_regs_from_elf_notes(struct task_context *); static void *get_x86_regs_from_elf_notes(struct task_context *); static void *get_x86_64_regs_from_elf_notes(struct task_context *); @@ -2876,6 +2916,7 @@ get_regs_from_elf_notes(struct task_context *tc) switch (e_machine) { case EM_386: + case EM_PPC: case EM_PPC64: case EM_X86_64: case EM_ARM: @@ -2895,6 +2936,8 @@ get_regs_from_elf_notes(struct task_context *tc) { case EM_386: return get_x86_regs_from_elf_notes(tc); + case EM_PPC: + return get_ppc_regs_from_elf_notes(tc); case EM_PPC64: return get_ppc64_regs_from_elf_notes(tc); case EM_X86_64: @@ -2964,6 +3007,34 @@ get_x86_64_regs_from_elf_notes(struct task_context *tc) } static void * +get_ppc_regs_from_elf_notes(struct task_context *tc) +{ + Elf32_Nhdr *note; + size_t len; + void *pt_regs; + extern struct vmcore_data *nd; + + pt_regs = NULL; + + /* + * Registers are always saved during the dump process for the + * panic task. Kdump also captures registers for all CPUs if + * they responded to an IPI. + */ + if (nd->num_prstatus_notes > 1) { + note = (Elf32_Nhdr *)nd->nt_prstatus_percpu[tc->processor]; + } else + note = (Elf32_Nhdr *)nd->nt_prstatus; + + len = sizeof(Elf32_Nhdr); + len = roundup(len + note->n_namesz, 4); + pt_regs = (void *)((char *)note + len + + MEMBER_OFFSET("elf_prstatus", "pr_reg")); + + return pt_regs; +} + +static void * get_ppc64_regs_from_elf_notes(struct task_context *tc) { Elf64_Nhdr *note; -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility