From 263b0e480c9b0fda77a89f5d6375d8a39de5c166 Mon Sep 17 00:00:00 2001 From: Philipp Rudo Date: Mon, 6 Aug 2018 13:39:52 +0200 Subject: s390/kdump: Make elfcorehdr size calculation ABI compliant There are two ways to pass the vmcoreinfo to the crash kernel 1) via the os_info mechanism and 2) via the lowcore->vmcore_info field. In the Linux kernel only the second way is used. However, the first way is ABI for stand-alone kdump. So other OSes use it to pass additional debug info. Make the elfcorehdr size calculation aware of both possible ways. Fixes: 8cce437fbb5c ("s390/kdump: Fix elfcorehdr size calculation") Signed-off-by: Philipp Rudo Acked-by: Heiko Carstens Signed-off-by: Heiko Carstens --- arch/s390/kernel/crash_dump.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index c3620bafc374..4b2773e1ddfe 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -478,26 +478,20 @@ static void *nt_vmcoreinfo(void *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); } /* -- cgit v1.2.3 From 2d2e7075b87181ed0c675e4936e20bdadba02e1f Mon Sep 17 00:00:00 2001 From: Philipp Rudo Date: Mon, 13 Aug 2018 11:16:57 +0200 Subject: s390/kdump: Fix memleak in nt_vmcoreinfo The vmcoreinfo of a crashed system is potentially fragmented. Thus the crash kernel has an intermediate step where the vmcoreinfo is copied into a temporary, continuous buffer in the crash kernel memory. This temporary buffer is never freed. Free it now to prevent the memleak. While at it replace all occurrences of "VMCOREINFO" by its corresponding macro to prevent potential renaming issues. Signed-off-by: Philipp Rudo Acked-by: Heiko Carstens Signed-off-by: Heiko Carstens --- arch/s390/kernel/crash_dump.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index 4b2773e1ddfe..27d2b7093ea0 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -451,11 +451,13 @@ 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_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,15 +467,20 @@ 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) -- cgit v1.2.3 From 28b7465376b9f9633bb774e45c0421dc4db7f303 Mon Sep 17 00:00:00 2001 From: Philipp Rudo Date: Mon, 13 Aug 2018 12:45:06 +0200 Subject: s390/kdump: Remove kzalloc_panic For this function there are only two users, when 1) the elfcorehdr and 2) the vmcoreinfo is allocated. However a missing vmcoreinfo is not critical for kdump. So panicking when it cannot be allocated is not required. Remove kzalloc_panic and adjust its callers accordingly. Signed-off-by: Philipp Rudo Acked-by: Heiko Carstens Signed-off-by: Heiko Carstens --- arch/s390/kernel/crash_dump.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index 27d2b7093ea0..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"; @@ -453,7 +440,9 @@ static void *get_vmcoreinfo_old(unsigned long *size) return NULL; if (strcmp(nt_name, VMCOREINFO_NOTE_NAME) != 0) return NULL; - vmcoreinfo = kzalloc_panic(note.n_descsz); + vmcoreinfo = kzalloc(note.n_descsz, GFP_KERNEL); + if (!vmcoreinfo) + return NULL; if (copy_oldmem_kernel(vmcoreinfo, addr + 24, note.n_descsz)) { kfree(vmcoreinfo); return NULL; @@ -661,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 */ -- cgit v1.2.3 From 4ec84835900b6eceb5b49f9ffeec9a0916ba43d6 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 21 Aug 2018 13:37:57 +0200 Subject: s390: remove gcc version check (4.3 or newer) git commit cafa0010cd51 ("Raise the minimum required gcc version to 4.6") raised the minimum gcc version to 4.6. Therefore remove the s390 specific gcc 4.3 version check, which wasn't sufficient anyway. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/asm-offsets.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index 11aea745a2a6..66e830f1c7bf 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -17,14 +17,6 @@ #include #include -/* - * Make sure that the compiler is new enough. We want a compiler that - * is known to work with the "Q" assembler constraint. - */ -#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) -#error Your compiler is too old; please use version 4.3 or newer -#endif - int main(void) { /* task struct offsets */ -- cgit v1.2.3