mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: David Ballesteros <davimaba.v@proton.me>
To: pbonzini@redhat.com, seanjc@google.com
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v4 3/3] KVM: Account mem_attr_array nodes to the caller's memcg
Date: Tue, 15 Sep 2026 17:53:57 +0000	[thread overview]
Message-ID: <20260915175335.138547-4-davimaba.v@proton.me> (raw)
In-Reply-To: <20260915175335.138547-1-davimaba.v@proton.me>

kvm_vm_set_mem_attributes() passes GFP_KERNEL_ACCOUNT when reserving xarray
entries, but the nodes are allocated by xas_alloc(), which hardcodes
GFP_NOWAIT and only adds __GFP_ACCOUNT when the xarray carries
XA_FLAGS_ACCOUNT.  mem_attr_array is initialized with plain xa_init(), so
the flag is never set and nodes taken from that fast path -- the
overwhelming majority -- are not charged to the caller; only the rare
__xas_nomem() slow path is, because it receives the caller's gfp.  Measured
on v6.18.48: a process in a cgroup limited to 256 MiB grew
radix_tree_node slab by ~512 MiB while its memory.current stayed near 0.
Per-tenant memcg limits therefore do not contain the growth.

Set XA_FLAGS_ACCOUNT so the intended accounting takes effect.

Note this is a change in reachability, not in contract.
KVM_SET_MEMORY_ATTRIBUTES could already return -ENOMEM, but only under
global memory pressure, since the fast path allocated with plain
GFP_NOWAIT.  With the nodes accounted, a tenant under a memory.max limit
can now hit it from a cgroup-local condition, i.e. conversions that
previously succeeded may fail.  That is intended and matches every other
GFP_KERNEL_ACCOUNT allocation in KVM; the alternative is letting the tenant
grow host memory that is never charged to it.  Userspace driving
conversions from guest KVM_HC_MAP_GPA_RANGE hypercalls surfaces the failure
on that path.

Runtime-verified on v6.18.48 (isolated VM, no KASAN): without the flag a
process in a 256 MiB cgroup materializes 512 MiB of radix_tree_node slab
with memory.current flat (the memcg is inert); with the flag the same
process is contained by the cgroup -- the memcg OOM killer selects the
attacker inside its own slice (CONSTRAINT_MEMCG) instead of exhausting
global memory.

Found by an AI-assisted security audit.

Not tagged for stable: unlike 1/3 and 2/3, which are pure corrections, this
one changes observable behaviour, and new -ENOMEM returns for
cgroup-limited tenants are a poor fit for stable's regression-risk bar.
Happy to send it to stable separately if maintainers disagree.

Fixes: 5a475554db1e ("KVM: Introduce per-page memory attributes")
Assisted-by: Claude-Code:claude-opus-5
Signed-off-by: David Ballesteros <davimaba.v@proton.me>
---
 virt/kvm/kvm_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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
@@ -1116,7 +1116,7 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
 	rcuwait_init(&kvm->mn_memslots_update_rcuwait);
 	xa_init(&kvm->vcpu_array);
 #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
-	xa_init(&kvm->mem_attr_array);
+	xa_init_flags(&kvm->mem_attr_array, XA_FLAGS_ACCOUNT);
 #endif

 	INIT_LIST_HEAD(&kvm->gpc_list);


  parent reply	other threads:[~2026-09-15 17:54 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-15 17:53 [PATCH v4 0/3] KVM: Fix and account mem_attr_array reservations abandoned on ENOMEM David Ballesteros
2026-09-15 17:53 ` [PATCH v4 1/3] KVM: Release memory-attribute " David Ballesteros
2026-09-15 17:53 ` [PATCH v4 2/3] KVM: Make kvm_range_has_memory_attributes() consistent about reservations David Ballesteros
2026-09-15 17:53 ` David Ballesteros [this message]
2026-09-24 21:51 ` [PATCH v4 0/3] KVM: Fix and account mem_attr_array reservations abandoned on ENOMEM Sean Christopherson
2026-09-27  6:13   ` David Ballesteros
2026-09-28 16:30     ` Sean Christopherson

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=20260915175335.138547-4-davimaba.v@proton.me \
    --to=davimaba.v@proton.me \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    /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

all inboxes | Powered by JetHome®