Commit 91959a31a399 for kernel

commit 91959a31a3990073b55b506af044eda09c359fb4
Merge: df51bdc5e80d bc0f793c5c41
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Sun Aug 23 09:17:38 2026 -0700

    Merge tag 'liveupdate-v7.3-rc1-20260823' of git://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux

    Pull more liveupdate updates from Mike Rapoport:
     "Make boot time huge page allocation work nicely with kexec handover.

      Today allocation of gigantic pages in HugeTLB cannot work reliably
      with kexec handover (KHO):

       - HugeTLB allocates gigantic pages using memblock and autoscaling of
         KHO scratch accounts for these allocations. When gigantic pages
         occupy half of the memory of more, KHO fails to allocate its
         scratch memory.

       - After kexec handover, memblock allocations exclusively use KHO
         scratch that is not supposed to contain preserved memory. This
         essentially blocks preservation of HugeTLB with gigantic pages.

      Extend early memory pools available for KHO kernel with areas that are
      guaranteed not to contain preserved memory"

    * tag 'liveupdate-v7.3-rc1-20260823' of git://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux: (21 commits)
      kho: exclude hugetlb memory from scratch size calculation
      memblock: add memblock_reserved_hugetlb_size()
      memblock: make HugeTLB bootmem allocation work with KHO
      memblock: always include KHO headers
      kho: extend scratch
      mm/mm_init: don't rely on memblock to get KHO scratch migratetype
      kho: initialize preserved memory map radix tree earlier
      kho: initialize kho_scratch pointer earlier in boot
      kho: expose kho_scratch_overlap() to kexec_handover.h
      kho: add kho_radix_init_tree()
      kho: allow destroying KHO radix tree
      kho: allow early-boot usage of the KHO radix tree
      kho: add data argument to radix walk callback
      kho: add callback for table pages
      kho: add a struct for radix callbacks
      kho: move all memory retrieval logic to kho_mem_retrieve()
      kho: store incoming radix tree in kho_in
      kho: disallow wide keys in radix tree
      kho: make radix max key width more obvious
      kho: generalize radix tree APIs
      ...

diff --cc kernel/liveupdate/kexec_handover.c
index 9260e601c61d,9c31613341b9..7c4d86daf86d
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@@ -500,9 -603,13 +614,13 @@@ static int __init kho_preserved_memory_
  {
  	union kho_page_info info;
  	struct page *page;
+ 	unsigned int order;
+ 	phys_addr_t phys;
  	u64 sz;

+ 	phys = kho_decode_radix_key(key, &order);
+
 -	sz = 1 << (order + PAGE_SHIFT);
 +	sz = 1UL << (order + PAGE_SHIFT);
  	page = kho_get_preserved_page(phys, order);

  	/* Reserve the memory preserved in KHO in memblock */
@@@ -667,9 -789,25 +800,25 @@@ static phys_addr_t __init scratch_size_
  		size = scratch_size_pernode;
  	}

 -	return round_up(size, CMA_MIN_ALIGNMENT_BYTES);
 +	return round_up(size, SCRATCH_ALIGNMENT_BYTES);
  }

+ bool kho_scratch_overlap(phys_addr_t phys, size_t size)
+ {
+ 	phys_addr_t scratch_start, scratch_end;
+ 	unsigned int i;
+
+ 	for (i = 0; i < kho_scratch_cnt; i++) {
+ 		scratch_start = kho_scratch[i].addr;
+ 		scratch_end = kho_scratch[i].addr + kho_scratch[i].size;
+
+ 		if (phys < scratch_end && (phys + size) > scratch_start)
+ 			return true;
+ 	}
+
+ 	return false;
+ }
+
  /**
   * kho_reserve_scratch - Reserve a contiguous chunk of memory for kexec
   *
diff --cc tools/testing/memblock/internal.h
index 4168e646af09,e86bb9000b22..f1974e009013
--- a/tools/testing/memblock/internal.h
+++ b/tools/testing/memblock/internal.h
@@@ -44,6 -60,15 +44,11 @@@ static inline bool __is_kernel(unsigne
  #define for_each_valid_pfn(pfn, start_pfn, end_pfn)                     \
         for ((pfn) = (start_pfn); (pfn) < (end_pfn); (pfn)++)

 -static inline void init_deferred_page(unsigned long pfn, int nid)
 -{
 -}
 -
  #define __SetPageReserved(p)	((void)(p))

+ static inline bool kho_scratch_overlap(phys_addr_t phys, size_t size)
+ {
+ 	return false;
+ }
+
  #endif