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 2/3] KVM: Make kvm_range_has_memory_attributes() consistent about reservations
Date: Tue, 15 Sep 2026 17:53:52 +0000	[thread overview]
Message-ID: <20260915175335.138547-3-davimaba.v@proton.me> (raw)
In-Reply-To: <20260915175335.138547-1-davimaba.v@proton.me>

Make the !attrs fast path of kvm_range_has_memory_attributes() skip bare
reservations, so that all three of the function's query paths agree on
what an XA_ZERO_ENTRY means.

A reservation carries no attributes, and two of the three paths already
treat it as absent: the end == start + 1 path reads it through
kvm_get_memory_attributes(), which maps it to NULL via xa_load(), and the
general loop skips it via xas_retry().  Only the !attrs fast path calls
xas_find() directly, which returns the reservation as a present entry, so
it reports a range that is in fact all-shared as not-all-shared.  Through
hugepage_has_attrs(), that marks a straddling hugepage mixed for a range
whose attributes are uniform.

This is a consistency fix rather than a fix for a reachable bug, and is
not tagged for stable.  Every caller of kvm_range_has_memory_attributes()
holds kvm->slots_lock -- the idempotency check in
kvm_vm_set_mem_attributes(), hugepage_has_attrs() from both
kvm_arch_post_set_memory_attributes() and
kvm_mmu_init_memslot_memory_attributes(), and __kvm_gmem_populate() --
and slots_lock excludes the only writer, so with patch 1/3 applied no
caller can observe a reservation.  The function should not have to depend
on that to answer consistently.

Note this patch depends on 1/3 and must not be applied without it.  Today a
clear over a range that holds only reservations does not take the
idempotency early-out in kvm_vm_set_mem_attributes(), because the fast path
reports the range as not-all-clear; the clear therefore proceeds and its
xa_store(NULL) loop erases the reservations as a side effect.  Teaching the
fast path to skip reservations makes that early-out fire and removes the
accidental cleanup, so the patch that stops the reservations from being
abandoned in the first place has to come first.

Found by an AI-assisted security audit.

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 | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 45e7844..4e5e497 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2446,8 +2446,17 @@ bool kvm_range_has_memory_attributes(struct kvm *kvm, gfn_t start, gfn_t end,
 		return (kvm_get_memory_attributes(kvm, start) & mask) == attrs;

 	guard(rcu)();
-	if (!attrs)
-		return !xas_find(&xas, end - 1);
+	if (!attrs) {
+		/*
+		 * Skip reservations: a bare XA_ZERO_ENTRY carries no
+		 * attributes, but xas_find() returns it raw.
+		 */
+		do {
+			entry = xas_find(&xas, end - 1);
+		} while (xas_retry(&xas, entry));
+
+		return !entry;
+	}

 	for (index = start; index < end; index++) {
 		do {


  parent reply	other threads:[~2026-09-15 17:53 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 ` David Ballesteros [this message]
2026-09-15 17:53 ` [PATCH v4 3/3] KVM: Account mem_attr_array nodes to the caller's memcg David Ballesteros
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-3-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®