From: sashiko-bot@kernel.org
To: "David Woodhouse" <dwmw2@infradead.org>, kvm@vger.kernel.org
Cc: linux-rt-devel@lists.linux.dev, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 10/20] KVM: pfncache: Add guest-mode pinning (GUEST_USES_PFN successor)
Date: Thu, 05 Nov 2026 02:29:14 +0000 [thread overview]
Message-ID: <sashiko-outbox-198464@kernel.org> (raw)
In-Reply-To: <20261105020104.2507083-11-dwmw2@infradead.org>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] KVM: pfncache: gpc_kick_pinned_vcpu() re-posts vcpu_req on self-refresh
--
commit 9027e5fc5e4260b0089300dc0cf3173581bbcfed
Author: David Woodhouse <dwmw@amazon.co.uk>
KVM: pfncache: Add guest-mode pinning (GUEST_USES_PFN successor)
This commit adds guest-mode pinning support to gfn_to_pfn_cache so that
caches whose pfn is used directly from guest mode force the vCPU out of
guest mode and post a per-cache service request upon invalidation or
mutation.
> diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c
> index 1c98b7bdbf09c..5cb30525e577c 100644
> --- a/virt/kvm/pfncache.c
> +++ b/virt/kvm/pfncache.c
> @@ -25,7 +25,9 @@
> void gfn_to_pfn_cache_invalidate_start(struct kvm *kvm, unsigned long start,
> unsigned long end)
> {
> + DECLARE_BITMAP(vcpu_bitmap, KVM_MAX_VCPUS);
> struct gfn_to_pfn_cache *gpc;
> + bool evict_vcpus = false;
> bool cleared = false;
>
> spin_lock(&kvm->gpc_lock);
> @@ -127,10 +129,60 @@ void gfn_to_pfn_cache_invalidate_start(struct kvm *kvm, unsigned long start,
> */
> if (old & (GPC_VALID | GPC_INVALIDATING))
> cleared = true;
> +
> + /*
> + * If a vCPU has the pfn pinned for direct use from
> + * guest mode, it must be forced out of guest mode
> + * before the invalidation may complete. The pin bit
> + * was set with a cmpxchg only while GPC_VALID held,
> + * so this same read of 'old' cannot miss it. It is
> + * NOT cleared here: only the vCPU itself (on request
> + * service, before re-pinning) or a mutator's xchg
> + * (which inherits the kick duty) may clear it. A
> + * stale pin costs at most a spurious request bit:
> + * kvm_make_vcpus_request_mask() only IPIs and waits
> + * for targets actually in guest mode.
> + */
> + if (old & GPC_GUEST_USING) {
> + if (!evict_vcpus) {
> + evict_vcpus = true;
> + bitmap_zero(vcpu_bitmap, KVM_MAX_VCPUS);
> + }
> + __set_bit(gpc->vcpu->vcpu_idx, vcpu_bitmap);
> + /*
> + * Set this cache's own service request (what
> + * the vCPU must do before re-entering); the
> + * force-out below is common to all of them.
> + */
> + __kvm_make_request(gpc->vcpu_req, gpc->vcpu);
> + }
> }
> }
> spin_unlock(&kvm->gpc_lock);
[ ... ]
> @@ -224,6 +276,107 @@ bool kvm_gpc_check(struct gfn_to_pfn_cache *gpc, unsigned long len)
> return true;
> }
>
> +/*
> + * A mutator's xchg of the state word to zero may have consumed a live
> + * GPC_GUEST_USING pin. Clearing that bit obliges the clearer to do what
> + * the invalidation walk would have done: post the cache's service
> + * request and force the vCPU out of guest mode, waiting until it has
> + * left, before mutating or tearing down what the guest may be using.
> + *
> + * The service request is posted unconditionally: consuming a pin means
> + * whatever physical address the vCPU had latched (e.g. into a hardware
> + * control structure) is stale, and only the request handler makes that
> + * good. That holds even when the pinning vCPU is the caller itself —
> + * a vCPU refreshing its own pinned cache may re-map at a different pfn,
> + * and without the request nothing would rewrite the stale address
> + * before the next guest entry. Only the waited force-out is skipped in
> + * that case: a vCPU running a refresh is by definition not in guest
> + * mode. (The vCPU's own unpin is the one silent path, in
> + * kvm_gpc_unpin_for_guest(), because unpinning asserts the address is
> + * no longer latched anywhere.)
> + */
> +static void gpc_kick_pinned_vcpu(struct gfn_to_pfn_cache *gpc, int old_state)
> +{
> + DECLARE_BITMAP(vcpu_bitmap, KVM_MAX_VCPUS);
> +
> + if (!(old_state & GPC_GUEST_USING))
> + return;
> + if (WARN_ON_ONCE(!gpc->vcpu))
> + return;
> +
> + __kvm_make_request(gpc->vcpu_req, gpc->vcpu);
> +
> + if (kvm_get_running_vcpu() == gpc->vcpu)
> + return;
[Severity: Medium]
When gfn_to_pfn_cache_invalidate_start() invalidates a pinned cache, it
clears GPC_VALID, sets GPC_INVALIDATING, leaves GPC_GUEST_USING set in
gpc->state, and posts gpc->vcpu_req to gpc->vcpu:
do {
new = old & ~(GPC_VALID | GPC_BECOMING_VALID);
if (old & GPC_VALID)
new |= GPC_INVALIDATING;
} while (!atomic_try_cmpxchg(&gpc->state, &old, new));
When gpc->vcpu subsequently services gpc->vcpu_req on the next guest entry
attempt, kvm_check_request() clears gpc->vcpu_req and the request handler
calls kvm_gpc_refresh() (or kvm_gpc_activate()) before re-pinning with
kvm_gpc_pin_for_guest(), as described in kvm_gpc_init_for_vcpu().
Because GPC_VALID is clear, __kvm_gpc_refresh() does not take the fast path
and instead consumes the leftover GPC_GUEST_USING bit via atomic_xchg():
old_state = atomic_xchg(&gpc->state, GPC_INVALIDATING);
gpc_kick_pinned_vcpu(gpc, old_state);
Won't gpc_kick_pinned_vcpu() see GPC_GUEST_USING in old_state and
unconditionally re-post gpc->vcpu_req to gpc->vcpu right in the middle of
handling that very request, causing the subsequent guest entry to abort and
run the request handler a second time (or loop if the handler does not hit
the __kvm_gpc_refresh() fast path on the next pass)?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261105020104.2507083-1-dwmw2@infradead.org?part=10
next prev parent reply other threads:[~2026-11-05 2:29 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-05 2:00 [PATCH v2 00/20] KVM: Use atomic SRCU for gfn-to-pfn cache, reinstate guest mode for x86 nesting David Woodhouse
2026-11-05 2:00 ` [PATCH v2 01/20] KVM: x86/xen: Fill the hypercall page with a single guest write David Woodhouse
2026-11-05 2:00 ` [PATCH v2 02/20] KVM: x86/xen: Add KVM_XEN_VCPU_ATTR_TYPE_WRITE_HYPERCALL_PAGE David Woodhouse
2026-11-05 2:00 ` [PATCH v2 03/20] KVM: x86/xen: Extract delivery of event to vCPU into a separate helper David Woodhouse
2026-11-05 2:00 ` [PATCH v2 04/20] KVM: x86/xen: Explicitly tag "shared info" page as never being dirty tracked David Woodhouse
2026-11-05 2:00 ` [PATCH v2 05/20] KVM: x86/xen: Don't dirty track "vCPU info" page David Woodhouse
2026-11-05 2:00 ` [PATCH v2 06/20] KVM: x86: Request the guest TLB flush from record_steal_time() David Woodhouse
2026-11-10 20:19 ` Sean Christopherson
2026-11-10 21:14 ` David Woodhouse
2026-11-05 2:00 ` [PATCH v2 07/20] KVM: selftests: Actually deactivate the HVA-based shared_info cache in xen_shinfo_test David Woodhouse
2026-11-05 2:00 ` [PATCH v2 08/20] KVM: pfncache: Use atomic SRCU for readers instead of a rwlock David Woodhouse
2026-11-05 2:00 ` [PATCH v2 09/20] KVM: x86: Use gfn_to_pfn_cache for steal time / preempted status David Woodhouse
2026-11-05 2:00 ` [PATCH v2 10/20] KVM: pfncache: Add guest-mode pinning (GUEST_USES_PFN successor) David Woodhouse
2026-11-05 2:29 ` sashiko-bot [this message]
2026-11-05 2:00 ` [PATCH v2 11/20] KVM: nVMX: Implement cache for L1 MSR bitmap David Woodhouse
2026-11-05 2:00 ` [PATCH v2 12/20] KVM: nVMX: Use pinned pfncache for L1 APIC virtualization pages David Woodhouse
2026-11-05 2:33 ` sashiko-bot
2026-11-05 2:00 ` [PATCH v2 13/20] KVM: x86: Post KVM_REQ_GET_NESTED_STATE_PAGES on memslot updates David Woodhouse
2026-11-05 2:00 ` [PATCH v2 14/20] KVM: selftests: Add nested VMX APIC cache invalidation test David Woodhouse
2026-11-05 2:25 ` sashiko-bot
2026-11-05 2:00 ` [PATCH v2 15/20] KVM: nSVM: Use a gfn_to_pfn_cache for the vmcb12 page David Woodhouse
2026-11-05 2:00 ` [PATCH v2 16/20] KVM: nSVM: Cache L1's MSR permissions map pages David Woodhouse
2026-11-05 2:00 ` [PATCH v2 17/20] KVM: nSVM: Cache L1's IO " David Woodhouse
2026-11-05 2:01 ` [PATCH v2 18/20] KVM: selftests: Add nested transition benchmark David Woodhouse
2026-11-05 2:01 ` [PATCH v2 19/20] KVM: selftests: Add Xen evtchn vs memslot-update race test David Woodhouse
2026-11-05 2:01 ` [PATCH v2 20/20] KVM: selftests: Add Xen evtchn vs mmu_notifier race test for HVA caches David Woodhouse
2026-11-05 2:28 ` sashiko-bot
2026-11-10 19:52 ` [PATCH v2 00/20] KVM: Use atomic SRCU for gfn-to-pfn cache, reinstate guest mode for x86 nesting David Woodhouse
2026-11-10 20:14 ` Sean Christopherson
2026-11-11 18:38 ` David Woodhouse
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=sashiko-outbox-198464@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=dwmw2@infradead.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rt-devel@lists.linux.dev \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.