[PATCH v2 07/18] kho: add callback for table pages
Pratyush Yadav
pratyush at kernel.org
Fri Jun 5 11:34:40 PDT 2026
From: "Pratyush Yadav (Google)" <pratyush at kernel.org>
The KHO memory preservation radix tree does not mark the table pages
themselves as preserved. This is done to avoid a circular dependency
where preserving a page can lead of allocating other preserved pages.
This means any walker looking for free ranges of memory outside of
scratch areas will ignore the table
Add a table callback that is invoked for each table page. The callback
is given the physical address of the table page.
This is useful for the upcoming mechanism that discovers blocks of
memory with no preserved pages and lets them be used for boot memory.
Another use case is for users of the radix tree other than KHO itself.
The radix tree does not preserve its own pages due to the circular
dependency described above. But external users of the radix tree would
need to preserve and restore their pages for the radix tree to survive
past early boot. They can use this callback to do so.
Signed-off-by: Pratyush Yadav (Google) <pratyush at kernel.org>
---
include/linux/kho_radix_tree.h | 3 +++
kernel/liveupdate/kexec_handover.c | 12 ++++++++++++
2 files changed, 15 insertions(+)
diff --git a/include/linux/kho_radix_tree.h b/include/linux/kho_radix_tree.h
index 426a9cc9bcde..ac7ba7e567e1 100644
--- a/include/linux/kho_radix_tree.h
+++ b/include/linux/kho_radix_tree.h
@@ -37,12 +37,15 @@ struct kho_radix_tree {
/**
* struct kho_radix_walk_cb - Callbacks for KHO radix tree walk.
* @leaf: Called on each present key in the radix tree.
+ * @node: Called on each node of the radix tree itself. Receives the
+ * physical address of the page containing the node.
*
* For each callback, a return value of 0 continues the walk and a non-zero
* return value is directly returned to the caller.
*/
struct kho_radix_walk_cb {
int (*leaf)(unsigned long key);
+ int (*node)(phys_addr_t phys);
};
#ifdef CONFIG_KEXEC_HANDOVER
diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
index dbe075348ce4..94f18fe42c4b 100644
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@ -285,6 +285,12 @@ static int kho_radix_walk_leaf(struct kho_radix_leaf *leaf, unsigned long key,
unsigned int i;
int err;
+ if (cb->node) {
+ err = cb->node(virt_to_phys(leaf));
+ if (err)
+ return err;
+ }
+
if (!cb->leaf)
return 0;
@@ -307,6 +313,12 @@ static int __kho_radix_walk_tree(struct kho_radix_node *root,
unsigned int shift;
int err;
+ if (cb->node) {
+ err = cb->node(virt_to_phys(root));
+ if (err)
+ return err;
+ }
+
for (i = 0; i < PAGE_SIZE / sizeof(phys_addr_t); i++) {
if (!root->table[i])
continue;
--
2.54.0.1032.g2f8565e1d1-goog
More information about the kexec
mailing list