[PATCH] KVM: Release reserved xarray entries if reserving memory attributes fails
From: Zeng Chi
Date: Thu Aug 27 2026 - 07:06:57 EST
From: Zeng Chi <zengchi@xxxxxxxxxx>
kvm_vm_set_mem_attributes() reserves an xarray entry for every gfn in
the range before modifying any attributes, so that the actual updates
can't fail partway through. But if one of the reservations fails, e.g.
due to -ENOMEM, the entries that were already reserved are left behind,
as the error path bails without releasing them.
A reserved entry is XA_ZERO_ENTRY, not NULL. xa_load() hides the
difference, but kvm_range_has_memory_attributes() uses xas_find() to
check whether a range has no attributes at all, and xas_find() returns
zero entries as-is. As a result, a leaked reservation makes KVM think
the range has attributes set even though kvm_get_memory_attributes()
reports none. On x86, the next time mixed-attribute tracking is
recomputed for the range (memslot creation, or a later attribute change
that straddles the 2MiB page), hugepage_has_attrs() treats a fully
shared 2MiB range as having mixed attributes and refuses to map it with
a hugepage, until userspace happens to set attributes on the range
again.
Release the successfully reserved entries on failure. xa_release() is
a nop for entries that hold a real value, so it's safe to blindly
release all entries in [start, i).
Fixes: 5a475554db1e ("KVM: Introduce per-page memory attributes")
Signed-off-by: Zeng Chi <zengchi@xxxxxxxxxx>
---
virt/kvm/kvm_main.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 65eb26a0520d..20031a832c21 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2575,8 +2575,11 @@ static int kvm_vm_set_mem_attributes(struct kvm *kvm, gfn_t start, gfn_t end,
*/
for (i = start; i < end; i++) {
r = xa_reserve(&kvm->mem_attr_array, i, GFP_KERNEL_ACCOUNT);
- if (r)
+ if (r) {
+ while (i-- > start)
+ xa_release(&kvm->mem_attr_array, i);
goto out_unlock;
+ }
cond_resched();
}
--
2.25.1
No virus found
Checked by Hillstone Network AntiVirus