* [PATCH v1 1/1] kexec: x86: Include pref_address when looking for a memory hole
@ 2024-11-13 15:44 Andy Shevchenko
2024-11-15 9:45 ` Simon Horman
0 siblings, 1 reply; 2+ messages in thread
From: Andy Shevchenko @ 2024-11-13 15:44 UTC (permalink / raw)
To: kexec; +Cc: horms, Andy Shevchenko
When the kernel is built relocatable, the starting address can be
anything above 1Mb on x86. However, the startup_*() entries consider
that the minumum address for the kernel for the decompression has to
be at least LOAD_PHYSICAL_ADDR which is turn the value that is provided
as pref_address in boot protocol. The boot protocol itself says:
This field, if nonzero, represents a preferred load address for the
kernel. A relocating bootloader should attempt to load at this
address if possible.
Besides that the code in the kernel (arch/x86/kernel/kexec-bzimage64.c)
has these lines (in bzImage64_load() function):
if (header->pref_address < MIN_KERNEL_LOAD_ADDR)
kbuf.buf_min = MIN_KERNEL_LOAD_ADDR;
else
kbuf.buf_min = header->pref_address;
All that said, do the same in kexec tools. Without this patch
the relocatable kernel may end up in the memory hole that is
not enough for in-place decompression and Bad Things will happen
as it's proven on Intel Merrifield, that has a reserved memory
block starting at 64Mb.
Note, it doesn't mean that kernel has no issues itself in this particular
stage, but at least we may work around some corner cases for kexec.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
kexec/arch/i386/kexec-bzImage.c | 6 +++++-
kexec/arch/x86_64/kexec-bzImage64.c | 10 +++++++++-
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/kexec/arch/i386/kexec-bzImage.c b/kexec/arch/i386/kexec-bzImage.c
index 3232cf54c1d9..fcf4254c71c9 100644
--- a/kexec/arch/i386/kexec-bzImage.c
+++ b/kexec/arch/i386/kexec-bzImage.c
@@ -281,14 +281,18 @@ int do_bzImage_load(struct kexec_info *info,
if (real_mode->protocol_version >=0x0205 && relocatable_kernel) {
/* Relocatable bzImage */
unsigned long kern_align = real_mode->kernel_alignment;
+ unsigned long kernel32_min_addr = KERN32_BASE;
unsigned long kernel32_max_addr = DEFAULT_BZIMAGE_ADDR_MAX;
+ if (kernel32_min_addr < real_mode->pref_address)
+ kernel32_min_addr = real_mode->pref_address;
+
if (kernel32_max_addr > real_mode->initrd_addr_max)
kernel32_max_addr = real_mode->initrd_addr_max;
kernel32_load_addr = add_buffer(info, kernel + kern16_size,
k_size, size, kern_align,
- 0x100000, kernel32_max_addr,
+ kernel32_min_addr, kernel32_max_addr,
1);
} else {
kernel32_load_addr = KERN32_BASE;
diff --git a/kexec/arch/x86_64/kexec-bzImage64.c b/kexec/arch/x86_64/kexec-bzImage64.c
index 210bc0af2643..29ed8c98619a 100644
--- a/kexec/arch/x86_64/kexec-bzImage64.c
+++ b/kexec/arch/x86_64/kexec-bzImage64.c
@@ -120,6 +120,8 @@ static int do_bzImage64_load(struct kexec_info *info,
char *modified_cmdline;
unsigned long cmdline_end;
unsigned long align, addr, k_size;
+ unsigned long kernel64_min_addr = KERN32_BASE;
+ unsigned long kernel64_max_addr = -1;
unsigned kern16_size_needed;
/*
@@ -204,8 +206,14 @@ static int do_bzImage64_load(struct kexec_info *info,
dbgprintf("kernel init_size 0x%x\n", real_mode->init_size);
size = _ALIGN(real_mode->init_size, 4096);
align = real_mode->kernel_alignment;
+
+ if (kernel64_min_addr < real_mode->pref_address)
+ kernel64_min_addr = real_mode->pref_address;
+
addr = add_buffer(info, kernel + kern16_size, k_size,
- size, align, 0x100000, -1, -1);
+ size, align,
+ kernel64_min_addr, kernel64_max_addr,
+ -1);
if (addr == ULONG_MAX)
die("can not load bzImage64");
dbgprintf("Loaded 64bit kernel at 0x%lx\n", addr);
--
2.43.0.rc1.1336.g36b5255a03ac
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v1 1/1] kexec: x86: Include pref_address when looking for a memory hole
2024-11-13 15:44 [PATCH v1 1/1] kexec: x86: Include pref_address when looking for a memory hole Andy Shevchenko
@ 2024-11-15 9:45 ` Simon Horman
0 siblings, 0 replies; 2+ messages in thread
From: Simon Horman @ 2024-11-15 9:45 UTC (permalink / raw)
To: Andy Shevchenko; +Cc: kexec
On Wed, Nov 13, 2024 at 05:44:37PM +0200, Andy Shevchenko wrote:
> When the kernel is built relocatable, the starting address can be
> anything above 1Mb on x86. However, the startup_*() entries consider
> that the minumum address for the kernel for the decompression has to
> be at least LOAD_PHYSICAL_ADDR which is turn the value that is provided
> as pref_address in boot protocol. The boot protocol itself says:
>
> This field, if nonzero, represents a preferred load address for the
> kernel. A relocating bootloader should attempt to load at this
> address if possible.
>
> Besides that the code in the kernel (arch/x86/kernel/kexec-bzimage64.c)
> has these lines (in bzImage64_load() function):
>
> if (header->pref_address < MIN_KERNEL_LOAD_ADDR)
> kbuf.buf_min = MIN_KERNEL_LOAD_ADDR;
> else
> kbuf.buf_min = header->pref_address;
>
> All that said, do the same in kexec tools. Without this patch
> the relocatable kernel may end up in the memory hole that is
> not enough for in-place decompression and Bad Things will happen
> as it's proven on Intel Merrifield, that has a reserved memory
> block starting at 64Mb.
>
> Note, it doesn't mean that kernel has no issues itself in this particular
> stage, but at least we may work around some corner cases for kexec.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Thanks Andy, applied.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2024-11-15 9:45 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-13 15:44 [PATCH v1 1/1] kexec: x86: Include pref_address when looking for a memory hole Andy Shevchenko
2024-11-15 9:45 ` Simon Horman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox