]> git.baikalelectronics.ru Git - kernel.git/commitdiff
s390/kexec: fix ipl report address for kdump
authorAlexander Egorenkov <egorenar@linux.ibm.com>
Mon, 14 Nov 2022 10:40:08 +0000 (11:40 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Jan 2023 10:42:01 +0000 (11:42 +0100)
commit c2337a40e04dde1692b5b0a46ecc59f89aaba8a1 upstream.

This commit addresses the following erroneous situation with file-based
kdump executed on a system with a valid IPL report.

On s390, a kdump kernel, its initrd and IPL report if present are loaded
into a special and reserved on boot memory region - crashkernel. When
a system crashes and kdump was activated before, the purgatory code
is entered first which swaps the crashkernel and [0 - crashkernel size]
memory regions. Only after that the kdump kernel is entered. For this
reason, the pointer to an IPL report in lowcore must point to the IPL report
after the swap and not to the address of the IPL report that was located in
crashkernel memory region before the swap. Failing to do so, makes the
kdump's decompressor try to read memory from the crashkernel memory region
which already contains the production's kernel memory.

The situation described above caused spontaneous kdump failures/hangs
on systems where the Secure IPL is activated because on such systems
an IPL report is always present. In that case kdump's decompressor tried
to parse an IPL report which frequently lead to illegal memory accesses
because an IPL report contains addresses to various data.

Cc: <stable@vger.kernel.org>
Fixes: c523d4744083 ("s390/kexec_file: Create ipl report and pass to next kernel")
Reviewed-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/s390/kernel/machine_kexec_file.c

index 53da174754d972cc90490b5bb1c22b6f45b8158a..bf0596749ebd3386daa8ab28e428181a404909f7 100644 (file)
@@ -185,8 +185,6 @@ static int kexec_file_add_ipl_report(struct kimage *image,
 
        data->memsz = ALIGN(data->memsz, PAGE_SIZE);
        buf.mem = data->memsz;
-       if (image->type == KEXEC_TYPE_CRASH)
-               buf.mem += crashk_res.start;
 
        ptr = (void *)ipl_cert_list_addr;
        end = ptr + ipl_cert_list_size;
@@ -223,6 +221,9 @@ static int kexec_file_add_ipl_report(struct kimage *image,
                data->kernel_buf + offsetof(struct lowcore, ipl_parmblock_ptr);
        *lc_ipl_parmblock_ptr = (__u32)buf.mem;
 
+       if (image->type == KEXEC_TYPE_CRASH)
+               buf.mem += crashk_res.start;
+
        ret = kexec_add_buffer(&buf);
 out:
        return ret;