diff options
Diffstat (limited to 'arch/s390/kernel/crash_dump.c')
-rw-r--r-- | arch/s390/kernel/crash_dump.c | 70 |
1 files changed, 34 insertions, 36 deletions
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index c3620bafc374..376f6b6dfb3c 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -293,19 +293,6 @@ int remap_oldmem_pfn_range(struct vm_area_struct *vma, unsigned long from, prot); } -/* - * Alloc memory and panic in case of ENOMEM - */ -static void *kzalloc_panic(int len) -{ - void *rc; - - rc = kzalloc(len, GFP_KERNEL); - if (!rc) - panic("s390 kdump kzalloc (%d) failed", len); - return rc; -} - static const char *nt_name(Elf64_Word type) { const char *name = "LINUX"; @@ -451,11 +438,15 @@ static void *get_vmcoreinfo_old(unsigned long *size) if (copy_oldmem_kernel(nt_name, addr + sizeof(note), sizeof(nt_name) - 1)) return NULL; - if (strcmp(nt_name, "VMCOREINFO") != 0) + if (strcmp(nt_name, VMCOREINFO_NOTE_NAME) != 0) + return NULL; + vmcoreinfo = kzalloc(note.n_descsz, GFP_KERNEL); + if (!vmcoreinfo) return NULL; - vmcoreinfo = kzalloc_panic(note.n_descsz); - if (copy_oldmem_kernel(vmcoreinfo, addr + 24, note.n_descsz)) + if (copy_oldmem_kernel(vmcoreinfo, addr + 24, note.n_descsz)) { + kfree(vmcoreinfo); return NULL; + } *size = note.n_descsz; return vmcoreinfo; } @@ -465,39 +456,38 @@ static void *get_vmcoreinfo_old(unsigned long *size) */ static void *nt_vmcoreinfo(void *ptr) { + const char *name = VMCOREINFO_NOTE_NAME; unsigned long size; void *vmcoreinfo; vmcoreinfo = os_info_old_entry(OS_INFO_VMCOREINFO, &size); - if (!vmcoreinfo) - vmcoreinfo = get_vmcoreinfo_old(&size); + if (vmcoreinfo) + return nt_init_name(ptr, 0, vmcoreinfo, size, name); + + vmcoreinfo = get_vmcoreinfo_old(&size); if (!vmcoreinfo) return ptr; - return nt_init_name(ptr, 0, vmcoreinfo, size, "VMCOREINFO"); + ptr = nt_init_name(ptr, 0, vmcoreinfo, size, name); + kfree(vmcoreinfo); + return ptr; } static size_t nt_vmcoreinfo_size(void) { - const char *name = "VMCOREINFO"; - char nt_name[11]; - Elf64_Nhdr note; - void *addr; - - if (copy_oldmem_kernel(&addr, &S390_lowcore.vmcore_info, sizeof(addr))) - return 0; - - if (copy_oldmem_kernel(¬e, addr, sizeof(note))) - return 0; + const char *name = VMCOREINFO_NOTE_NAME; + unsigned long size; + void *vmcoreinfo; - memset(nt_name, 0, sizeof(nt_name)); - if (copy_oldmem_kernel(nt_name, addr + sizeof(note), - sizeof(nt_name) - 1)) - return 0; + vmcoreinfo = os_info_old_entry(OS_INFO_VMCOREINFO, &size); + if (vmcoreinfo) + return nt_size_name(size, name); - if (strcmp(nt_name, name) != 0) + vmcoreinfo = get_vmcoreinfo_old(&size); + if (!vmcoreinfo) return 0; - return nt_size_name(note.n_descsz, name); + kfree(vmcoreinfo); + return nt_size_name(size, name); } /* @@ -660,7 +650,15 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size) alloc_size = get_elfcorehdr_size(mem_chunk_cnt); - hdr = kzalloc_panic(alloc_size); + hdr = kzalloc(alloc_size, GFP_KERNEL); + + /* Without elfcorehdr /proc/vmcore cannot be created. Thus creating + * a dump with this crash kernel will fail. Panic now to allow other + * dump mechanisms to take over. + */ + if (!hdr) + panic("s390 kdump allocating elfcorehdr failed"); + /* Init elf header */ ptr = ehdr_init(hdr, mem_chunk_cnt); /* Init program headers */ |