The current KHO restoration logic assumes all multi-page blocks are
split into independent 4KB pages. Break out a helper to prepare for
supporting high-order non-compound pages.

Extract kho_init_unsplit_pages() to handle the refcount pattern
where only the head page is refcounted. Use the helper for folio
restoration that requires a similar refcount logic.

Signed-off-by: Pranjal Shrivastava <[email protected]>
---
 kernel/liveupdate/kexec_handover.c | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/kernel/liveupdate/kexec_handover.c 
b/kernel/liveupdate/kexec_handover.c
index 4834a809985a..07f6f453cd69 100644
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@ -357,6 +357,24 @@ int kho_radix_walk_tree(struct kho_radix_tree *tree,
 }
 EXPORT_SYMBOL_GPL(kho_radix_walk_tree);
 
+/* For physically contiguous pages. */
+static void kho_init_unsplit_pages(struct page *page, unsigned int order)
+{
+       unsigned long nr_pages = (1UL << order);
+
+       /* Head page gets refcount of 1. */
+       set_page_count(page, 1);
+       /* Clear head page's codetag to avoid accounting mismatch. */
+       clear_page_tag_ref(page);
+
+       /* For high-order blocks, tail pages get a page count of zero. */
+       for (unsigned long i = 1; i < nr_pages; i++) {
+               set_page_count(page + i, 0);
+               /* Clear each page's codetag to avoid accounting mismatch. */
+               clear_page_tag_ref(page + i);
+       }
+}
+
 /* For physically contiguous 0-order pages. */
 static void kho_init_pages(struct page *page, unsigned long nr_pages)
 {
@@ -369,16 +387,7 @@ static void kho_init_pages(struct page *page, unsigned 
long nr_pages)
 
 static void kho_init_folio(struct page *page, unsigned int order)
 {
-       unsigned long nr_pages = (1 << order);
-
-       /* Head page gets refcount of 1. */
-       set_page_count(page, 1);
-       /* Clear head page's codetag to avoid accounting mismatch. */
-       clear_page_tag_ref(page);
-
-       /* For higher order folios, tail pages get a page count of zero. */
-       for (unsigned long i = 1; i < nr_pages; i++)
-               set_page_count(page + i, 0);
+       kho_init_unsplit_pages(page, order);
 
        if (order > 0)
                prep_compound_page(page, order);
-- 
2.55.0.141.g00534a21ce-goog


Reply via email to