Re: [REGRESSION] Kernel booted via kexec fails to resume from hibernation
From: Roberto Ricci
Date: Fri Apr 04 2025 - 16:39:35 EST
On 2025-04-04 12:50 +0700, msizanoen wrote:
> Here's an updated version of the patch that better handles pathological e820
> tables.
>
> On 4/4/25 11:56, msizanoen wrote:
> > Also, can you reproduce this issue with a target kernel (the kernel
> > being kexec-ed) that has one of the patches attached (select the correct
> > one according to your kernel version) applied, with either kexec_load or
> > kexec_file_load?
> > [snip]
>
> diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
> index 4893d30ce438..5d963df63b7a 100644
> --- a/arch/x86/kernel/e820.c
> +++ b/arch/x86/kernel/e820.c
> @@ -754,22 +754,21 @@ void __init e820__memory_setup_extended(u64 phys_addr, u32 data_len)
> void __init e820__register_nosave_regions(unsigned long limit_pfn)
> {
> int i;
> - unsigned long pfn = 0;
> + u64 last_addr = 0;
>
> for (i = 0; i < e820_table->nr_entries; i++) {
> struct e820_entry *entry = &e820_table->entries[i];
>
> - if (pfn < PFN_UP(entry->addr))
> - register_nosave_region(pfn, PFN_UP(entry->addr));
> -
> - pfn = PFN_DOWN(entry->addr + entry->size);
> -
> if (entry->type != E820_TYPE_RAM && entry->type != E820_TYPE_RESERVED_KERN)
> - register_nosave_region(PFN_UP(entry->addr), pfn);
> + continue;
>
> - if (pfn >= limit_pfn)
> - break;
> + if (last_addr < entry->addr)
> + register_nosave_region(PFN_UP(last_addr), PFN_DOWN(entry->addr));
> +
> + last_addr = entry->addr + entry->size;
> }
> +
> + register_nosave_region(PFN_UP(last_addr), limit_pfn);
> }
Your patch applied to v6.14 fixes the issue with kexec_file_load, but
kexec_load keeps not working.
> #ifdef CONFIG_ACPI
>
> diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
> index 57120f0749cc..656ed7abd28d 100644
> --- a/arch/x86/kernel/e820.c
> +++ b/arch/x86/kernel/e820.c
> @@ -753,22 +753,21 @@ void __init e820__memory_setup_extended(u64 phys_addr, u32 data_len)
> void __init e820__register_nosave_regions(unsigned long limit_pfn)
> {
> int i;
> - unsigned long pfn = 0;
> + u64 last_addr = 0;
>
> for (i = 0; i < e820_table->nr_entries; i++) {
> struct e820_entry *entry = &e820_table->entries[i];
>
> - if (pfn < PFN_UP(entry->addr))
> - register_nosave_region(pfn, PFN_UP(entry->addr));
> -
> - pfn = PFN_DOWN(entry->addr + entry->size);
> -
> if (entry->type != E820_TYPE_RAM)
> - register_nosave_region(PFN_UP(entry->addr), pfn);
> + continue;
>
> - if (pfn >= limit_pfn)
> - break;
> + if (last_addr < entry->addr)
> + register_nosave_region(PFN_UP(last_addr), PFN_DOWN(entry->addr));
> +
> + last_addr = entry->addr + entry->size;
> }
> +
> + register_nosave_region(PFN_UP(last_addr), limit_pfn);
> }
>
> #ifdef CONFIG_ACPI
On master, kexec_file_load already worked due to the patch series you
mentioned in earlier emails. The kexec_load issue isn't affected by your
patch.