summaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
authorPhilipp Rudo2019-04-01 12:48:43 +0200
committerGreg Kroah-Hartman2019-05-31 15:46:13 +0200
commit216155aab5074c36a23a439a4dbd30ce20204bff (patch)
tree4b958c95a505e0519682f98b2952ef5f5b96c841 /arch/s390/kernel
parentscsi: qedi: Abort ep termination if offload not scheduled (diff)
downloadkernel-qcow2-linux-216155aab5074c36a23a439a4dbd30ce20204bff.tar.gz
kernel-qcow2-linux-216155aab5074c36a23a439a4dbd30ce20204bff.tar.xz
kernel-qcow2-linux-216155aab5074c36a23a439a4dbd30ce20204bff.zip
s390/kexec_file: Fix detection of text segment in ELF loader
[ Upstream commit 729829d775c9a5217abc784b2f16087d79c4eec8 ] To register data for the next kernel (command line, oldmem_base, etc.) the current kernel needs to find the ELF segment that contains head.S. This is currently done by checking ifor 'phdr->p_paddr == 0'. This works fine for the current kernel build but in theory the first few pages could be skipped. Make the detection more robust by checking if the entry point lies within the segment. Signed-off-by: Philipp Rudo <prudo@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/kexec_elf.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/s390/kernel/kexec_elf.c b/arch/s390/kernel/kexec_elf.c
index 5a286b012043..602e7cc26d11 100644
--- a/arch/s390/kernel/kexec_elf.c
+++ b/arch/s390/kernel/kexec_elf.c
@@ -19,10 +19,15 @@ static int kexec_file_add_elf_kernel(struct kimage *image,
struct kexec_buf buf;
const Elf_Ehdr *ehdr;
const Elf_Phdr *phdr;
+ Elf_Addr entry;
int i, ret;
ehdr = (Elf_Ehdr *)kernel;
buf.image = image;
+ if (image->type == KEXEC_TYPE_CRASH)
+ entry = STARTUP_KDUMP_OFFSET;
+ else
+ entry = ehdr->e_entry;
phdr = (void *)ehdr + ehdr->e_phoff;
for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
@@ -35,7 +40,7 @@ static int kexec_file_add_elf_kernel(struct kimage *image,
buf.mem = ALIGN(phdr->p_paddr, phdr->p_align);
buf.memsz = phdr->p_memsz;
- if (phdr->p_paddr == 0) {
+ if (entry - phdr->p_paddr < phdr->p_memsz) {
data->kernel_buf = buf.buffer;
data->memsz += STARTUP_NORMAL_OFFSET;