mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Sean Christopherson <seanjc@google.com>,
	Paolo Bonzini <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Sashiko Bot" <sashiko-bot@kernel.org>,
	"Carlos López" <clopez@suse.de>
Subject: [PATCH] KVM: VMX: Re-pend KVM_REQ_APIC_PAGE_RELOAD if getting backing pfn fails
Date: Thu,  5 Nov 2026 10:17:42 -0800	[thread overview]
Message-ID: <20261105181742.3718448-1-seanjc@google.com> (raw)

Retry loading the APIC-access page if getting the backing pfn fails for
any reason and APICv is enabled, i.e. if the vCPU will consume the value
stored in vmcs.APIC_ACCESS_ADDR.  Dropping the failed reload would result
in KVM running the vCPU with a stale backing pfn and in all likelihood
break APIC emulation/virtualization.  E.g. if KVM's page tables are able
to map the page, then guest accesses would go to the new physical page
instead of being treated as APIC accesses.

Opportunistically WARN if the memslot lookup fails, as KVM fully controls
the memslot, and VMX doesn't support inhibiting the APIC-access page, i.e.
KVM VMX should never delete or invalidate the memslot while the VM is alive
and reachable.

Do *not* WARN if getting the pfn fails, because despite KVM controlling the
memslot and allocating the backing page, there is nothing special about the
underlying VMA.  I.e. userspace can munmap(), mprotect(), etc. the VMA and
thus prevent KVM from faulting in the page.  If that happens, it's firmly
userspace's responsibility to re-install a valid mapping, e.g. to prevent
the vCPU from getting stuck in an endless KVM_REQ_APIC_PAGE_RELOAD loop.

Fixes: e8fd5e9e9984 ("kvm: fix crash in kvm_vcpu_reload_apic_access_page")
Reported-by: Sashiko Bot <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/sashiko-outbox-191120@kernel.org
Cc: Carlos López <clopez@suse.de>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---

FWIW, I actually verified this is a real bug, and that the fix works, by
hacking KVM to map the APIC-access page at a hardcoded virtual address, and
then modifying the xapic_ipi_test to unmap() and mmap() that virtual address
(usually at a different pfn).  I didn't Cc stable@ because unmapping the
APIC-access page is all but guaranteed to be fatal, e.g. the VMM would have
to blindly retry on -EFAULT when trying to fault-in the page into the MMU
inevitably fails.

 arch/x86/kvm/vmx/vmx.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index b341af4c6057..13dcf9c12c83 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6923,8 +6923,10 @@ void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu)
 	 * APICv is enabled, but paranoia won't hurt in this case.
 	 */
 	slot = id_to_memslot(slots, APIC_ACCESS_PAGE_PRIVATE_MEMSLOT);
-	if (!slot || slot->flags & KVM_MEMSLOT_INVALID)
+	if (WARN_ON_ONCE(!slot || slot->flags & KVM_MEMSLOT_INVALID)) {
+		kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu);
 		return;
+	}
 
 	/*
 	 * Ensure that the mmu_notifier sequence count is read before KVM
@@ -6941,8 +6943,10 @@ void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu)
 	 * if APICv is permanently inhibited, i.e. the memslot won't reappear.
 	 */
 	pfn = __kvm_faultin_pfn(slot, gfn, FOLL_WRITE, &writable, &refcounted_page);
-	if (is_error_noslot_pfn(pfn))
+	if (is_error_noslot_pfn(pfn)) {
+		kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu);
 		return;
+	}
 
 	read_lock(&vcpu->kvm->mmu_lock);
 	if (mmu_invalidate_retry_gfn(kvm, mmu_seq, gfn))

base-commit: d21eef2084a9af87ac2a783bc7c2b175ba114e4e
-- 
2.56.0.567.gdb80ae8cd5-goog


                 reply	other threads:[~2026-11-05 18:17 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20261105181742.3718448-1-seanjc@google.com \
    --to=seanjc@google.com \
    --cc=clopez@suse.de \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=sashiko-bot@kernel.org \
    /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®