QEMU can generate both non-makedumpfile (just elf) and makedumpfile formatted kdumps. In neither case will crash_notes have prstatus, as crash_kexec doesn't run in the kernel, however the elf notes will contain the prstatus, and we can dig them out of there. --- arm.c | 22 ++++++++++++++++++++++ arm64.c | 22 ++++++++++++++++++++++ defs.h | 1 + netdump.c | 21 +++++++++++++++++++++ 4 files changed, 66 insertions(+) diff --git a/arm.c b/arm.c index ffc7c06d0f42c..8fc3d48a8ac89 100644 --- a/arm.c +++ b/arm.c @@ -597,6 +597,28 @@ arm_get_crash_notes(void) note = (Elf32_Nhdr *)buf; p = buf + sizeof(Elf32_Nhdr); + /* + * dumpfiles created with qemu won't have crash_notes, but there will + * be elf notes. + */ + if (note->n_namesz == 0 && (DISKDUMP_DUMPFILE() || KDUMP_DUMPFILE())) { + if (DISKDUMP_DUMPFILE()) + note = diskdump_get_prstatus_percpu(i); + else if (KDUMP_DUMPFILE()) + note = netdump_get_prstatus_percpu(i); + if (note) { + /* + * SIZE(note_buf) accounts for a "final note", which is a + * trailing empty elf note header. + */ + long notesz = SIZE(note_buf) - sizeof(Elf32_Nhdr); + + if (sizeof(Elf32_Nhdr) + roundup(note->n_namesz, 4) + + note->n_descsz == notesz) + BCOPY((char *)note, buf, notesz); + } + } + if (note->n_type != NT_PRSTATUS) { error(WARNING, "invalid note (n_type != NT_PRSTATUS)\n"); goto fail; diff --git a/arm64.c b/arm64.c index d85ad7214dd39..6278a993217c1 100644 --- a/arm64.c +++ b/arm64.c @@ -1827,6 +1827,28 @@ arm64_get_crash_notes(void) note = (Elf64_Nhdr *)buf; p = buf + sizeof(Elf64_Nhdr); + /* + * dumpfiles created with qemu won't have crash_notes, but there will + * be elf notes. + */ + if (note->n_namesz == 0 && (DISKDUMP_DUMPFILE() || KDUMP_DUMPFILE())) { + if (DISKDUMP_DUMPFILE()) + note = diskdump_get_prstatus_percpu(i); + else if (KDUMP_DUMPFILE()) + note = netdump_get_prstatus_percpu(i); + if (note) { + /* + * SIZE(note_buf) accounts for a "final note", which is a + * trailing empty elf note header. + */ + long notesz = SIZE(note_buf) - sizeof(Elf64_Nhdr); + + if (sizeof(Elf64_Nhdr) + roundup(note->n_namesz, 4) + + note->n_descsz == notesz) + BCOPY((char *)note, buf, notesz); + } + } + if (note->n_type != NT_PRSTATUS) { error(WARNING, "invalid note (n_type != NT_PRSTATUS)\n"); goto fail; diff --git a/defs.h b/defs.h index 3e5dbd99942b2..8a4045ec78c37 100644 --- a/defs.h +++ b/defs.h @@ -5720,6 +5720,7 @@ void dump_registers_for_qemu_mem_dump(void); void kdump_backup_region_init(void); void display_regs_from_elf_notes(int, FILE *); void display_ELF_note(int, int, void *, FILE *); +void *netdump_get_prstatus_percpu(int); #define PRSTATUS_NOTE (1) #define QEMU_NOTE (2) diff --git a/netdump.c b/netdump.c index bfa818fdef8e1..3ff49f0577c23 100644 --- a/netdump.c +++ b/netdump.c @@ -2345,6 +2345,27 @@ dump_Elf64_Nhdr(Elf64_Off offset, int store) return len; } +void * +netdump_get_prstatus_percpu(int cpu) +{ + int online; + + if ((cpu < 0) || (cpu >= nd->num_prstatus_notes)) + return NULL; + + /* + * If no cpu mapping was done, then there must be + * a one-to-one relationship between the number + * of online cpus and the number of notes. + */ + if ((online = get_cpus_online()) && + (online == kt->cpus) && + (online != nd->num_prstatus_notes)) + return NULL; + + return nd->nt_prstatus_percpu[cpu]; +} + /* * Send the request to the proper architecture hander. */ -- 2.4.3 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility