Skip to content

Commit

Permalink
kexec: x86: Use init_size in 32-bit case as well
Browse files Browse the repository at this point in the history
If the region of the memory is not enough for the decompressed
kernel, e.g., it follows by reserved memory, Bad Things may happen
as it's proven to be in practice on Intel Merrifield platform.

Include decompressed kernel size into the calculations for finding
the appropriate hole in memory to load kernel to.

Note, this has been already done for 64-bit case, this just
synchronises the approach for 32-bit case.

Signed-off-by: Andy Shevchenko <[email protected]>
Signed-off-by: Simon Horman <[email protected]>
  • Loading branch information
andy-shev authored and horms committed Nov 7, 2024
1 parent fb9302e commit ec3e4df
Showing 1 changed file with 9 additions and 8 deletions.
17 changes: 9 additions & 8 deletions kexec/arch/i386/kexec-bzImage.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ int do_bzImage_load(struct kexec_info *info,
struct entry32_regs regs32;
struct entry16_regs regs16;
unsigned int relocatable_kernel = 0;
unsigned long kernel32_load_addr;
char *modified_cmdline;
unsigned long cmdline_end;
unsigned long kernel32_load_addr, k_size;
unsigned long kern16_size_needed;
unsigned long heap_size = 0;

Expand Down Expand Up @@ -274,8 +274,10 @@ int do_bzImage_load(struct kexec_info *info,
}

/* The main kernel segment */
size = kernel_len - kern16_size;

k_size = kernel_len - kern16_size;
/* need to use run-time size for buffer searching */
dbgprintf("kernel init_size 0x%x\n", real_mode->init_size);
size = _ALIGN(real_mode->init_size, 4096);
if (real_mode->protocol_version >=0x0205 && relocatable_kernel) {
/* Relocatable bzImage */
unsigned long kern_align = real_mode->kernel_alignment;
Expand All @@ -285,14 +287,13 @@ int do_bzImage_load(struct kexec_info *info,
kernel32_max_addr = real_mode->initrd_addr_max;

kernel32_load_addr = add_buffer(info, kernel + kern16_size,
size, size, kern_align,
k_size, size, kern_align,
0x100000, kernel32_max_addr,
1);
}
else {
} else {
kernel32_load_addr = KERN32_BASE;
add_segment(info, kernel + kern16_size, size,
kernel32_load_addr, size);
add_segment(info, kernel + kern16_size, k_size,
kernel32_load_addr, k_size);
}

dbgprintf("Loaded 32bit kernel at 0x%lx\n", kernel32_load_addr);
Expand Down

0 comments on commit ec3e4df

Please sign in to comment.