From: sashiko-bot@kernel.org
To: "Jork Loeser" <jloeser@linux.microsoft.com>
Cc: linux-hyperv@vger.kernel.org
Subject: Re: [RFC PATCH 13/20] kho: add radix tree freeze and del_key() error reporting
Date: Thu, 28 May 2026 01:34:14 +0000 [thread overview]
Message-ID: <20260528013414.67CF91F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260528004204.1484584-14-jloeser@linux.microsoft.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] `kho_radix_tree_freeze()` locks the tree mutex without verifying if the tree has been initialized.
- [Medium] `kho_radix_del_key()` does not accurately report `-ENOENT` if the key is missing but its leaf node exists.
- [Low] The docstring for `kho_radix_tree` instructs developers to pass a physical address to initialize the tree, which will lead to a crash.
- [Low] The error path in `kho_init()` frees the radix tree root using `free_page()`, breaking the allocator abstraction.
--
commit da7ab3d5519dc40884c4213f1650e1238149beb0
Author: Jork Loeser <jloeser@linux.microsoft.com>
kho: add radix tree freeze and del_key() error reporting
This commit adds kho_radix_tree_freeze() to prevent modifications to a KHO
radix tree. It also updates kho_radix_del_key() to return an integer so it
can report errors like -EBUSY and -ENOENT.
> diff --git a/include/linux/kho_radix_tree.h b/include/linux/kho_radix_tree.h
> index c0840ecb230c8..4fe2238e1e30a 100644
> --- a/include/linux/kho_radix_tree.h
> +++ b/include/linux/kho_radix_tree.h
> @@ -21,10 +21,10 @@
> * scheme. Each key is an unsigned long that combines a page's physical
> * address and its order.
> *
> - * Client code is responsible for allocating the root node of the tree,
> - * initializing the mutex lock, and managing its lifecycle. It must use the
> - * tree data structures defined in the KHO ABI,
> - * `include/linux/kho/abi/kexec_handover.h`.
> + * Client code must initialize the tree using kho_radix_tree_init(). Pass
> + * a physical address to restore a tree preserved across kexec, or 0 to
[Severity: Low]
Is this documentation accurate? The tree traversal functions treat
tree->root as a virtual address pointer. If a caller passes a raw physical
address without using phys_to_virt(), would it cause a page fault upon the
first dereference?
> + * allocate a fresh empty tree. The tree uses data structures defined in
> + * the KHO ABI, `include/linux/kho/abi/kexec_handover.h`.
> */
[ ... ]
> diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
> index 797ec285b698c..2e2b4e73f00d3 100644
> --- a/kernel/liveupdate/kexec_handover.c
> +++ b/kernel/liveupdate/kexec_handover.c
> @@ -79,9 +79,6 @@ struct kho_out {
>
> static struct kho_out kho_out = {
> .lock = __MUTEX_INITIALIZER(kho_out.lock),
> - .radix_tree = {
> - .lock = __MUTEX_INITIALIZER(kho_out.radix_tree.lock),
> - },
> };
[ ... ]
> @@ -180,6 +177,28 @@ static void __ref kho_radix_free_node(struct kho_radix_node *node)
> memblock_free(node, PAGE_SIZE);
> }
>
> +/**
> + * kho_radix_tree_freeze - Freeze the tree, preventing further modifications.
> + * @tree: The KHO radix tree to freeze.
> + *
> + * After freezing, kho_radix_add_key() and kho_radix_del_key() will return
> + * -EBUSY. The check is performed under the tree's mutex, so there is no
> + * race between a concurrent add/del and the freeze.
> + *
> + * Return: 0 on success, -EBUSY if the tree is already frozen.
> + */
> +int kho_radix_tree_freeze(struct kho_radix_tree *tree)
> +{
> + guard(mutex)(&tree->lock);
[Severity: High]
Could this cause a crash if called on an uninitialized tree?
Because the static __MUTEX_INITIALIZER was removed from
kho_out.radix_tree.lock in this patch, the mutex is zero-initialized before
kho_radix_init_tree() is called.
Unlike kho_radix_add_key() and kho_radix_del_key(), which safely check
if (WARN_ON_ONCE(!tree->root)) before taking the mutex, this function
directly attempts to lock it.
> +
> + if (tree->frozen)
> + return -EBUSY;
> +
> + tree->frozen = true;
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(kho_radix_tree_freeze);
[ ... ]
> @@ -300,6 +328,8 @@ void kho_radix_del_key(struct kho_radix_tree *tree, unsigned long key)
> leaf = (struct kho_radix_leaf *)node;
> idx = kho_radix_get_bitmap_index(key);
> __clear_bit(idx, leaf->bitmap);
> +
> + return 0;
> }
[Severity: Medium]
Will this correctly report -ENOENT if the key is missing but the leaf
node exists?
The commit message states kho_radix_del_key() was updated to report -ENOENT
when a key is not present. However, if other keys share the same leaf node
and the target key's bit is already 0, __clear_bit() does nothing and this
silently returns 0.
Should this use test_and_clear_bit() and return -ENOENT if the bit was not
previously set?
> EXPORT_SYMBOL_GPL(kho_radix_del_key);
[ ... ]
> @@ -1807,7 +1836,7 @@ static __init int kho_init(void)
> err_free_fdt:
> kho_unpreserve_free(kho_out.fdt);
> err_free_kho_radix_tree_root:
> - kfree(tree->root);
> + free_page((unsigned long)tree->root);
[Severity: Low]
Is it safe to use free_page() directly here instead of calling
kho_radix_free_node()?
Since kho_radix_init_tree() allocates the node internally via
kho_radix_alloc_node(), calling free_page() directly bypasses the fallback
safety checks in kho_radix_free_node(), which handles memblock_free() when
the slab is unavailable.
> tree->root = NULL;
> err_free_scratch:
> kho_out.fdt = NULL;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260528004204.1484584-1-jloeser@linux.microsoft.com?part=13
next prev parent reply other threads:[~2026-05-28 1:34 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-28 0:41 [RFC PATCH 00/20] mshv: enable kexec with Hyper-V donated pages and partitions Jork Loeser
2026-05-28 0:41 ` [RFC PATCH 01/20] kho: generalize radix tree APIs Jork Loeser
2026-05-28 1:22 ` sashiko-bot
2026-05-28 0:41 ` [RFC PATCH 02/20] kho: store incoming radix tree in kho_in Jork Loeser
2026-05-28 1:08 ` sashiko-bot
2026-05-28 0:41 ` [RFC PATCH 03/20] kho: add a struct for radix callbacks Jork Loeser
2026-05-28 0:41 ` [RFC PATCH 04/20] kho: add callback for table pages Jork Loeser
2026-05-28 1:33 ` sashiko-bot
2026-05-28 0:41 ` [RFC PATCH 05/20] kho: add data argument to radix walk callback Jork Loeser
2026-05-28 1:11 ` sashiko-bot
2026-05-28 0:41 ` [RFC PATCH 06/20] kho: allow early-boot usage of the KHO radix tree Jork Loeser
2026-05-28 1:40 ` sashiko-bot
2026-05-28 0:41 ` [RFC PATCH 07/20] kho: allow destroying " Jork Loeser
2026-05-28 0:41 ` [RFC PATCH 08/20] kho: add kho_radix_init_tree() Jork Loeser
2026-05-28 1:21 ` sashiko-bot
2026-05-28 0:41 ` [RFC PATCH 09/20] memblock: introduce MEMBLOCK_KHO_SCRATCH_EXT Jork Loeser
2026-05-28 0:41 ` [RFC PATCH 10/20] kho: extended scratch Jork Loeser
2026-05-28 1:21 ` sashiko-bot
2026-05-28 0:41 ` [RFC PATCH 11/20] kho: return virtual address of mem_map Jork Loeser
2026-05-28 1:27 ` sashiko-bot
2026-05-28 0:41 ` [RFC PATCH 12/20] mm/hugetlb: make bootmem allocation work with KHO Jork Loeser
2026-05-28 1:06 ` sashiko-bot
2026-05-28 0:41 ` [RFC PATCH 13/20] kho: add radix tree freeze and del_key() error reporting Jork Loeser
2026-05-28 1:34 ` sashiko-bot [this message]
2026-05-28 0:41 ` [RFC PATCH 14/20] kho: Add crash-kernel-safe radix tree presence check Jork Loeser
2026-05-28 1:27 ` sashiko-bot
2026-05-28 0:41 ` [RFC PATCH 15/20] mshv: Use page tracker to manage MSHV-owned pages and preserve with KHO Jork Loeser
2026-05-28 1:41 ` sashiko-bot
2026-05-28 0:41 ` [RFC PATCH 16/20] mshv: Add debugfs interface to page tracker Jork Loeser
2026-05-28 1:48 ` sashiko-bot
2026-05-28 0:41 ` [RFC PATCH 17/20] hyperv: Reserve crash MSR P2 for page preservation root PA Jork Loeser
2026-05-28 1:34 ` sashiko-bot
2026-05-28 0:42 ` [RFC PATCH 18/20] mshv: Exclude Hyper-V donated pages from crash dump collection Jork Loeser
2026-05-28 2:13 ` sashiko-bot
2026-05-28 0:42 ` [RFC PATCH 19/20] kexec: export kexec_in_progress for modules Jork Loeser
2026-05-28 0:42 ` [RFC PATCH 20/20] mshv: freeze and vacuum partitions across kexec Jork Loeser
2026-05-28 2:11 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260528013414.67CF91F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=jloeser@linux.microsoft.com \
--cc=linux-hyperv@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox