[PATCH] mm/memblock: only mark/clear KHO scratch memory when needed

Usama Arif posted 1 patch 5 days, 15 hours ago
mm/memblock.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
[PATCH] mm/memblock: only mark/clear KHO scratch memory when needed
Posted by Usama Arif 5 days, 15 hours ago
The scratch memory for kexec handover is used to bootstrap the
kexec'ed kernel. It is only needed when CONFIG_MEMBLOCK_KHO_SCRATCH
is enabled (selected by KHO) and if it is a KHO boot. Add checks
to prevent marking a KHO scratch region unless needed.

kexec_handover.h is now unconditionally included for is_kho_boot.

Fixes: a2daf83e10378 ("x86/e820: temporarily enable KHO scratch for memory below 1M")
Reported-by: Vlad Poenaru <thevlad@meta.com>
Signed-off-by: Usama Arif <usamaarif642@gmail.com>
---
 mm/memblock.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/mm/memblock.c b/mm/memblock.c
index e23e16618e9b3..5c85d575bb61c 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -20,8 +20,8 @@
 
 #ifdef CONFIG_KEXEC_HANDOVER
 #include <linux/libfdt.h>
-#include <linux/kexec_handover.h>
 #endif /* CONFIG_KEXEC_HANDOVER */
+#include <linux/kexec_handover.h>
 
 #include <asm/sections.h>
 #include <linux/io.h>
@@ -1126,8 +1126,11 @@ int __init_memblock memblock_reserved_mark_noinit(phys_addr_t base, phys_addr_t
  */
 __init int memblock_mark_kho_scratch(phys_addr_t base, phys_addr_t size)
 {
-	return memblock_setclr_flag(&memblock.memory, base, size, 1,
-				    MEMBLOCK_KHO_SCRATCH);
+	if (IS_ENABLED(CONFIG_MEMBLOCK_KHO_SCRATCH) && is_kho_boot())
+		return memblock_setclr_flag(&memblock.memory, base, size, 1,
+					    MEMBLOCK_KHO_SCRATCH);
+	else
+		return 0;
 }
 
 /**
@@ -1140,8 +1143,11 @@ __init int memblock_mark_kho_scratch(phys_addr_t base, phys_addr_t size)
  */
 __init int memblock_clear_kho_scratch(phys_addr_t base, phys_addr_t size)
 {
-	return memblock_setclr_flag(&memblock.memory, base, size, 0,
-				    MEMBLOCK_KHO_SCRATCH);
+	if (IS_ENABLED(CONFIG_MEMBLOCK_KHO_SCRATCH) && is_kho_boot())
+		return memblock_setclr_flag(&memblock.memory, base, size, 0,
+					    MEMBLOCK_KHO_SCRATCH);
+	else
+		return 0;
 }
 
 static bool should_skip_region(struct memblock_type *type,
-- 
2.47.3
Re: [PATCH] mm/memblock: only mark/clear KHO scratch memory when needed
Posted by Mike Rapoport 4 days, 18 hours ago
On Wed, Nov 26, 2025 at 07:20:51AM +0000, Usama Arif wrote:
> The scratch memory for kexec handover is used to bootstrap the
> kexec'ed kernel. It is only needed when CONFIG_MEMBLOCK_KHO_SCRATCH
> is enabled (selected by KHO) and if it is a KHO boot. Add checks
> to prevent marking a KHO scratch region unless needed.
> 
> kexec_handover.h is now unconditionally included for is_kho_boot.
> 
> Fixes: a2daf83e10378 ("x86/e820: temporarily enable KHO scratch for memory below 1M")
> Reported-by: Vlad Poenaru <thevlad@meta.com>
> Signed-off-by: Usama Arif <usamaarif642@gmail.com>
> ---
>  mm/memblock.c | 16 +++++++++++-----
>  1 file changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/mm/memblock.c b/mm/memblock.c
> index e23e16618e9b3..5c85d575bb61c 100644
> --- a/mm/memblock.c
> +++ b/mm/memblock.c
> @@ -20,8 +20,8 @@
>  
>  #ifdef CONFIG_KEXEC_HANDOVER
>  #include <linux/libfdt.h>
> -#include <linux/kexec_handover.h>
>  #endif /* CONFIG_KEXEC_HANDOVER */
> +#include <linux/kexec_handover.h>
>  
>  #include <asm/sections.h>
>  #include <linux/io.h>
> @@ -1126,8 +1126,11 @@ int __init_memblock memblock_reserved_mark_noinit(phys_addr_t base, phys_addr_t
>   */
>  __init int memblock_mark_kho_scratch(phys_addr_t base, phys_addr_t size)
>  {
> -	return memblock_setclr_flag(&memblock.memory, base, size, 1,
> -				    MEMBLOCK_KHO_SCRATCH);
> +	if (IS_ENABLED(CONFIG_MEMBLOCK_KHO_SCRATCH) && is_kho_boot())
> +		return memblock_setclr_flag(&memblock.memory, base, size, 1,
> +					    MEMBLOCK_KHO_SCRATCH);
> +	else

else is not needed.

> +		return 0;
>  }
>  
>  /**
> @@ -1140,8 +1143,11 @@ __init int memblock_mark_kho_scratch(phys_addr_t base, phys_addr_t size)
>   */
>  __init int memblock_clear_kho_scratch(phys_addr_t base, phys_addr_t size)
>  {
> -	return memblock_setclr_flag(&memblock.memory, base, size, 0,
> -				    MEMBLOCK_KHO_SCRATCH);
> +	if (IS_ENABLED(CONFIG_MEMBLOCK_KHO_SCRATCH) && is_kho_boot())
> +		return memblock_setclr_flag(&memblock.memory, base, size, 0,
> +					    MEMBLOCK_KHO_SCRATCH);
> +	else

Ditto.

> +		return 0;
>  }
>  
>  static bool should_skip_region(struct memblock_type *type,
> -- 
> 2.47.3
> 

-- 
Sincerely yours,
Mike.
Re: [PATCH] mm/memblock: only mark/clear KHO scratch memory when needed
Posted by Kiryl Shutsemau 5 days, 12 hours ago
On Wed, Nov 26, 2025 at 07:20:51AM +0000, Usama Arif wrote:
> @@ -1126,8 +1126,11 @@ int __init_memblock memblock_reserved_mark_noinit(phys_addr_t base, phys_addr_t
>   */
>  __init int memblock_mark_kho_scratch(phys_addr_t base, phys_addr_t size)
>  {
> -	return memblock_setclr_flag(&memblock.memory, base, size, 1,
> -				    MEMBLOCK_KHO_SCRATCH);
> +	if (IS_ENABLED(CONFIG_MEMBLOCK_KHO_SCRATCH) && is_kho_boot())

It makes me wounder why CONFIG_MEMBLOCK_KHO_SCRATCH exists? It seems to
be a proxy for CONFIG_KEXEC_HANDOVER which is the only option that
selects it and does it always.

Can we make s/CONFIG_MEMBLOCK_KHO_SCRATCH/CONFIG_KEXEC_HANDOVER/ and
remove IS_ENABLED() from this check? Just is_kho_boot() is enough.


-- 
  Kiryl Shutsemau / Kirill A. Shutemov
Re: [PATCH] mm/memblock: only mark/clear KHO scratch memory when needed
Posted by Usama Arif 5 days, 11 hours ago

On 26/11/2025 10:40, Kiryl Shutsemau wrote:
> On Wed, Nov 26, 2025 at 07:20:51AM +0000, Usama Arif wrote:
>> @@ -1126,8 +1126,11 @@ int __init_memblock memblock_reserved_mark_noinit(phys_addr_t base, phys_addr_t
>>   */
>>  __init int memblock_mark_kho_scratch(phys_addr_t base, phys_addr_t size)
>>  {
>> -	return memblock_setclr_flag(&memblock.memory, base, size, 1,
>> -				    MEMBLOCK_KHO_SCRATCH);
>> +	if (IS_ENABLED(CONFIG_MEMBLOCK_KHO_SCRATCH) && is_kho_boot())
> 
> It makes me wounder why CONFIG_MEMBLOCK_KHO_SCRATCH exists? It seems to
> be a proxy for CONFIG_KEXEC_HANDOVER which is the only option that
> selects it and does it always.
> 
> Can we make s/CONFIG_MEMBLOCK_KHO_SCRATCH/CONFIG_KEXEC_HANDOVER/ and
> remove IS_ENABLED() from this check? Just is_kho_boot() is enough.
> 
> 

Thats a very good point! I imagine it might have been for maybe debug purposes?

Looking at the code, CONFIG_MEMBLOCK_KHO_SCRATCH shouldnt be needed. I guess
this might be a good time to clean it up. If Mike is happy for it to be replaced
with CONFIG_KEXEC_HANDOVER (and removed where needed), happy to send that
for review instead of this.

Thanks
Usama
Re: [PATCH] mm/memblock: only mark/clear KHO scratch memory when needed
Posted by Mike Rapoport 4 days, 18 hours ago
On Wed, Nov 26, 2025 at 11:43:21AM +0000, Usama Arif wrote:
> 
> On 26/11/2025 10:40, Kiryl Shutsemau wrote:
> > On Wed, Nov 26, 2025 at 07:20:51AM +0000, Usama Arif wrote:
> >> @@ -1126,8 +1126,11 @@ int __init_memblock memblock_reserved_mark_noinit(phys_addr_t base, phys_addr_t
> >>   */
> >>  __init int memblock_mark_kho_scratch(phys_addr_t base, phys_addr_t size)
> >>  {
> >> -	return memblock_setclr_flag(&memblock.memory, base, size, 1,
> >> -				    MEMBLOCK_KHO_SCRATCH);
> >> +	if (IS_ENABLED(CONFIG_MEMBLOCK_KHO_SCRATCH) && is_kho_boot())
> > 
> > It makes me wounder why CONFIG_MEMBLOCK_KHO_SCRATCH exists? It seems to
> > be a proxy for CONFIG_KEXEC_HANDOVER which is the only option that
> > selects it and does it always.
> > 
> > Can we make s/CONFIG_MEMBLOCK_KHO_SCRATCH/CONFIG_KEXEC_HANDOVER/ and
> > remove IS_ENABLED() from this check? Just is_kho_boot() is enough.
> > 
> > 
> 
> Thats a very good point! I imagine it might have been for maybe debug purposes?
> 
> Looking at the code, CONFIG_MEMBLOCK_KHO_SCRATCH shouldnt be needed. I guess
> this might be a good time to clean it up. If Mike is happy for it to be replaced
> with CONFIG_KEXEC_HANDOVER (and removed where needed), happy to send that
> for review instead of this.

Yeah, let's kill CONFIG_MEMBLOCK_KHO_SCRATCH and use CONFIG_KEXEC_HANDOVER
where needed.
IS_ENABLED() is not needed in the check because with
CONFIG_MEMBLOCK_KHO_SCRATCH=n both mark_kho_scratch() and
clear_kho_scratch() are empty stubs, so it's enough to check is_kho_boot().

> Thanks
> Usama

-- 
Sincerely yours,
Mike.