From: sashiko-bot@kernel.org
To: "David Ballesteros" <davimaba.v@proton.me>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH 1/2] KVM: Bound per-VM GFN materialization in KVM_SET_MEMORY_ATTRIBUTES
Date: Fri, 11 Sep 2026 19:05:28 +0000 [thread overview]
Message-ID: <20260911190529.2E9AA1F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260911184819.101123-2-davimaba.v@proton.me>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [High] Recounting materialized entries on every mutation is an O(N) operation that causes severe CPU exhaustion.
- [High] The arbitrary 128 GiB limit (KVM_MEM_ATTR_MAX_GFNS) introduces a severe functional regression for large confidential VMs.
- [Medium] Iterating the XArray using xas_for_each() without holding rcu_read_lock() triggers lockdep warnings.
Pre-existing issues:
- [High] The KVM_MEM_ATTR_MAX_GFNS limit check is bypassed when clearing attributes, failing to fix the memory exhaustion DoS.
--
commit 200db6833ee43dd9cdcad914e3c4e7942e9f7e5a
Author: David Ballesteros <davimaba.v@proton.me>
KVM: Bound per-VM GFN materialization in KVM_SET_MEMORY_ATTRIBUTES
This commit attempts to fix a memory exhaustion denial of service by
capping the maximum number of materialized memory attribute GFNs per VM.
It introduces a counter for materialized entries and restricts updates
exceeding a hardcoded limit.
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -573,6 +573,13 @@ static inline int kvm_vcpu_exiting_guest_mode(struct kvm_vcpu *vcpu)
> #define KVM_MEM_MAX_NR_PAGES ((1UL << 31) - 1)
> +/*
> + * Hardening bound: maximum number of GFNs with a materialized entry in
> + * mem_attr_array per VM (~300 MiB of xa_nodes at 2^25). Without it,
> + * KVM_SET_MEMORY_ATTRIBUTES grows the array without limit (~9.3 bytes of
> + * kernel memory per GFN) on GFNs with no backing memory.
> + */
> +#define KVM_MEM_ATTR_MAX_GFNS (1UL << 25)
[Severity: High]
Does this limit cause legitimate large enterprise confidential VMs to fail?
A limit of 1UL << 25 pages equates to exactly 128 GiB of memory on systems
using a 4 KiB page size. Since AMD SEV-SNP and Intel TDX VMs routinely require
hundreds of gigabytes or even terabytes of private memory, capping the
allowed private memory to 128 GiB per VM seems like a functional regression
that will break existing large setups with -ENOSPC.
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -2544,6 +2545,33 @@ static bool kvm_pre_set_memory_attributes(struct kvm *kvm,
> [ ... ]
> +static unsigned long kvm_count_mem_attr_entries(struct kvm *kvm)
> +{
> + XA_STATE(xas, &kvm->mem_attr_array, 0);
> + unsigned long count = 0;
> + void *entry;
> +
> + xas_for_each(&xas, entry, ULONG_MAX) {
[Severity: Medium]
Will this xas_for_each() loop trigger lockdep warnings when PROVE_RCU is
enabled?
The caller holds the slots_lock, but iterating the XArray using this
macro implicitly dereferences node pointers. XArray requires either
rcu_read_lock() or the internal xa_lock to satisfy its lockdep invariants
during traversal, neither of which appear to be held here.
> @@ -2579,6 +2608,23 @@ static int kvm_vm_set_mem_attributes(struct kvm *kvm, gfn_t start, gfn_t end,
> [ ... ]
> + if (attributes &&
> + kvm->mem_attr_gfn_count + (end - start) > KVM_MEM_ATTR_MAX_GFNS) {
> + r = -ENOSPC;
> + goto out_unlock;
> + }
[Severity: High]
This is a pre-existing issue, but does bypassing the limit check when clearing
attributes re-expose the vulnerability?
Because this check requires attributes to be non-zero, a caller can set a
single attribute at index 0, and then call KVM_SET_MEMORY_ATTRIBUTES with
attributes set to 0 for an enormous range. The kvm_range_has_memory_attributes()
function will evaluate to false due to the index 0 entry, and this limit check
will be bypassed.
> [ ... ]
> for (i = start; i < end; i++) {
> r = xa_reserve(&kvm->mem_attr_array, i, GFP_KERNEL_ACCOUNT);
> if (r)
> goto out_unlock;
...which causes this subsequent loop to unconditionally reserve XArray nodes for
billions of GFNs until the host hits ENOMEM, exiting without freeing the leaked
reservations.
> [ ... ]
> out_unlock:
> + /*
> + * Resynchronize with the actual state only when the array may have
> + * changed: on ENOMEM partway through the reserve loop, partially
> + * reserved GFNs are retained and must be counted, and a successful
> + * set or clear changes the population. Non-mutating exits skip the
> + * walk so idempotent requests stay O(1).
> + */
> + if (mutated)
> + kvm->mem_attr_gfn_count = kvm_count_mem_attr_entries(kvm);
> mutex_unlock(&kvm->slots_lock);
[Severity: High]
Does this trigger a severe CPU denial of service during standard memory updates?
When a guest issues a series of 1-page memory attribute updates, this mutated
flag will be true for each successful update. Calling kvm_count_mem_attr_entries()
then iterates over up to 33.5 million populated entries in the XArray while holding
the slots_lock.
Performing an O(N) iteration that takes tens of milliseconds on every successful
mutation yields an O(N^2) complexity that ties up the CPU and monopolizes the
slots_lock for long periods, blocking memslot and dirty logging operations.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260911184819.101123-1-davimaba.v@proton.me?part=1
next prev parent reply other threads:[~2026-09-11 19:05 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-11 18:48 [PATCH 0/2] KVM: unbounded per-VM kernel memory growth via KVM_SET_MEMORY_ATTRIBUTES David Ballesteros
2026-09-11 18:48 ` [PATCH 1/2] KVM: Bound per-VM GFN materialization in KVM_SET_MEMORY_ATTRIBUTES David Ballesteros
2026-09-11 19:05 ` sashiko-bot [this message]
2026-09-11 18:48 ` [PATCH 2/2] KVM: Account mem_attr_array nodes to the caller's memcg David Ballesteros
2026-09-11 19:02 ` sashiko-bot
2026-09-11 20:32 ` [PATCH v2 0/2] KVM: unbounded per-VM kernel memory growth via KVM_SET_MEMORY_ATTRIBUTES David Ballesteros
2026-09-11 21:19 ` David Ballesteros
2026-09-11 22:13 ` [PATCH v3 " David Ballesteros
2026-09-11 22:13 ` [PATCH v3 1/2] KVM: Bound per-VM GFN materialization in KVM_SET_MEMORY_ATTRIBUTES David Ballesteros
2026-09-11 22:32 ` sashiko-bot
2026-09-11 22:13 ` [PATCH v2 2/2] KVM: Account mem_attr_array nodes to the caller's memcg David Ballesteros
2026-09-11 20:32 ` [PATCH v2 1/2] KVM: Bound per-VM GFN materialization in KVM_SET_MEMORY_ATTRIBUTES David Ballesteros
2026-09-11 20:45 ` sashiko-bot
2026-09-11 20:32 ` [PATCH v2 2/2] KVM: Account mem_attr_array nodes to the caller's memcg David Ballesteros
2026-09-11 20:44 ` sashiko-bot
2026-09-12 8:48 ` [syzbot ci] Re: KVM: unbounded per-VM kernel memory growth via KVM_SET_MEMORY_ATTRIBUTES syzbot ci
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=20260911190529.2E9AA1F000FF@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=davimaba.v@proton.me \
--cc=kvm@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