From: Sean Christopherson <seanjc@google.com>
To: Yosry Ahmed <yosry.ahmed@linux.dev>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
Kevin Cheng <chengkev@google.com>,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/3] KVM: nSVM: Rename recalc_intercepts() to clarify vmcb02 as the target
Date: Wed, 4 Feb 2026 09:45:52 -0800 [thread overview]
Message-ID: <aYOF0LNp173xAEsy@google.com> (raw)
In-Reply-To: <20260112182022.771276-3-yosry.ahmed@linux.dev>
On Mon, Jan 12, 2026, Yosry Ahmed wrote:
> recalc_intercepts() updates the intercept bits in vmcb02 based on vmcb01
> and (cached) vmcb12.
Ah, but it does more than that. More below.
> However, the name is too generic to make this
> clear, and is especially confusing while searching through the code as
> it shares the same name as the recalc_intercepts callback in
> kvm_x86_ops.
>
> Rename it to nested_vmcb02_recalc_intercepts() (similar to other
> nested_vmcb02_* scoped functions), to make it clear what it is doing.
>
> No functional change intended.
>
> Signed-off-by: Yosry Ahmed <yosry.ahmed@linux.dev>
> ---
> arch/x86/kvm/svm/nested.c | 4 ++--
> arch/x86/kvm/svm/sev.c | 2 +-
> arch/x86/kvm/svm/svm.c | 4 ++--
> arch/x86/kvm/svm/svm.h | 10 +++++-----
> 4 files changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
> index 2dda52221fd8..bacb2ac4c59e 100644
> --- a/arch/x86/kvm/svm/nested.c
> +++ b/arch/x86/kvm/svm/nested.c
> @@ -123,7 +123,7 @@ static bool nested_vmcb_needs_vls_intercept(struct vcpu_svm *svm)
> return false;
> }
>
> -void recalc_intercepts(struct vcpu_svm *svm)
> +void nested_vmcb02_recalc_intercepts(struct vcpu_svm *svm)
> {
> struct vmcb *vmcb01, *vmcb02;
> unsigned int i;
Drat, I should have responded to the previous patch. Lurking out of sight is a
pre-existing bug that effectively invalidates this entire rename.
The existing code is:
void recalc_intercepts(struct vcpu_svm *svm)
{
struct vmcb *vmcb01, *vmcb02;
unsigned int i;
vmcb_mark_dirty(svm->vmcb, VMCB_INTERCEPTS); <======= not vmcb01!!!!!
if (!is_guest_mode(&svm->vcpu))
return;
When L2 is active, svm->vmcb is vmcb02. Which, at first glance, _looks_ right,
but (the *horribly* named) recalc_intercepts() isn't _just_ recalculating
intercepts for L2, it's also responsible for marking the VMCB_INTERCEPTS dirty
(obviously).
But what isn't so obvious is that _all_ callers operate on vmcb01, because the
pattern is to modify vmcb01 intercepts, and then merge the new vmcb01 intercepts
with vmcb12, i.e. the "recalc intercepts" aspect is "part 2" of the overall
function.
Lost in all of this is that KVM forgets to mark vmcb01 dirty, and unless there's
a call buried somewhere deep, nested_svm_vmexit() isn't guaranteed to mark
VMCB_INTERCEPTS dirty, e.g. if PAUSE interception is disabled.
It's probably a benign bug in practice, as AMD CPUs don't appear to do anything
with the clean fields, but easy to fix.
As a bonus, fixing that bug yields for even better naming and code. After the
dust settles, we can end up with this in svm.h:
void nested_vmcb02_recalc_intercepts(struct vcpu_svm *svm);
static inline void svm_mark_intercepts_dirty(struct vcpu_svm *svm)
{
vmcb_mark_dirty(svm->vmcb01.ptr, VMCB_INTERCEPTS);
/*
* If L2 is active, recalculate the intercepts for vmcb02 to account
* for the changes made to vmcb01. All intercept configuration is done
* for vmcb01 and then propagated to vmcb02 to combine KVM's intercepts
* with L1's intercepts (from the vmcb12 snapshot).
*/
if (is_guest_mode(&svm->vcpu))
nested_vmcb02_recalc_intercepts(svm);
}
and this for nested_vmcb02_recalc_intercepts():
void nested_vmcb02_recalc_intercepts(struct vcpu_svm *svm)
{
struct vmcb_ctrl_area_cached *vmcb12_ctrl = &svm->nested.ctl;
struct vmcb *vmcb02 = svm->nested.vmcb02.ptr;
struct vmcb *vmcb01 = svm->vmcb01.ptr;
unsigned int i;
if (WARN_ON_ONCE(svm->vmcb != vmcb02))
return;
...
}
with the only other caller of nested_vmcb02_recalc_intercepts() being
nested_vmcb02_prepare_control().
next prev parent reply other threads:[~2026-02-04 17:45 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-12 18:20 [PATCH 0/3] nSVM: Minor cleanups for intercepts code Yosry Ahmed
2026-01-12 18:20 ` [PATCH 1/3] KVM: nSVM: Use intuitive local variables in recalc_intercepts() Yosry Ahmed
2026-02-04 17:29 ` Sean Christopherson
2026-02-04 17:43 ` Yosry Ahmed
2026-02-04 17:55 ` Sean Christopherson
2026-02-04 18:24 ` Yosry Ahmed
2026-01-12 18:20 ` [PATCH 2/3] KVM: nSVM: Rename recalc_intercepts() to clarify vmcb02 as the target Yosry Ahmed
2026-02-04 17:45 ` Sean Christopherson [this message]
2026-02-04 18:26 ` Yosry Ahmed
2026-01-12 18:20 ` [PATCH 3/3] KVM: nSVM: Use vmcb12_is_intercept() in nested_sync_control_from_vmcb02() Yosry Ahmed
2026-02-04 17:47 ` [PATCH 0/3] nSVM: Minor cleanups for intercepts code Sean Christopherson
2026-02-04 18:30 ` Yosry Ahmed
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=aYOF0LNp173xAEsy@google.com \
--to=seanjc@google.com \
--cc=chengkev@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=yosry.ahmed@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.