From: Sean Christopherson <seanjc@google.com>
To: Naveen N Rao <naveen@kernel.org>
Cc: "Maciej S. Szmigiero" <mail@maciej.szmigiero.name>,
Paolo Bonzini <pbonzini@redhat.com>,
Maxim Levitsky <mlevitsk@redhat.com>,
Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>,
Alejandro Jimenez <alejandro.j.jimenez@oracle.com>,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/2] KVM: SVM: Sync TPR from LAPIC into VMCB::V_TPR when setting LAPIC regs
Date: Fri, 22 Aug 2025 13:54:35 -0700 [thread overview]
Message-ID: <aKjZC3peGKPj9NPq@google.com> (raw)
In-Reply-To: <zx4aiu65mmk72mo2kooj52q4k3vsp43znlrdadajivsw6ns7ou@7xtzfms3de66>
On Fri, Aug 22, 2025, Naveen N Rao wrote:
> On Thu, Aug 21, 2025 at 01:38:17PM -0700, Sean Christopherson wrote:
> > On Tue, Aug 19, 2025, Maciej S. Szmigiero wrote:
> > > + /*
> > > + * Sync TPR from LAPIC TASKPRI into V_TPR field of the VMCB.
> > > + *
> > > + * When AVIC is enabled the normal pre-VMRUN sync in sync_lapic_to_cr8()
> > > + * is inhibited so any set TPR LAPIC state would not get reflected
> > > + * in V_TPR.
> >
> > Hmm, I think that code is straight up wrong. There's no justification, just a
> > claim:
> >
> > commit 3bbf3565f48ce3999b5a12cde946f81bd4475312
> > Author: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
> > AuthorDate: Wed May 4 14:09:51 2016 -0500
> > Commit: Paolo Bonzini <pbonzini@redhat.com>
> > CommitDate: Wed May 18 18:04:31 2016 +0200
> >
> > svm: Do not intercept CR8 when enable AVIC
> >
> > When enable AVIC:
> > * Do not intercept CR8 since this should be handled by AVIC HW.
> > * Also, we don't need to sync cr8/V_TPR and APIC backing page. <======
> >
> > Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> > [Rename svm_in_nested_interrupt_shadow to svm_nested_virtualize_tpr. - Paolo]
> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> >
> > That claim assumes APIC[TPR] will _never_ be modified by anything other than
> > hardware.
>
> It also isn't clear to me why only sync_lapic_to_cr8() was gated when
> AVIC was enabled, while sync_cr8_to_lapic() continues to copy V_TRP to
> the backing page. If AVIC is enabled, then the AVIC hardware updates
> both the backing page and V_TPR on a guest write to TPR.
>
> > That's obviously false for state restore from userspace, and it's also
> > technically false at steady state, e.g. if KVM managed to trigger emulation of a
> > store to the APIC page, then KVM would bypass the automatic harware sync.
>
> Do you mean emulation due to AVIC being inhibited? I initially thought
> this could be a problem, but in this scenario, AVIC would be disabled on
> the next VMRUN, so we will end up sync'ing TPR from the lapic to V_TPR.
No, if emulation is triggered when AVIC isn't inhibited. E.g. a contrived but
entirely possible situation would be if MOVBE isn't supported in hardware, KVM
is emulating MOVBE for emulation, and the guest sets the TPR via MOVBE. The MOVBE
#UDs, KVM emulates in response to the #UD, and Bob's your uncle.
There are other scenarios where KVM would emulate, though they're even more
contrived.
> > There's also the comically ancient KVM_SET_VAPIC_ADDR, which AFAICT appears to
> > be largely dead code with respect to vTPR (nothing sets KVM_APIC_CHECK_VAPIC
> > except for the initial ioctl), but could again set APIC[TPR] without updating
> > V_TPR.
> >
> > So, rather than manually do the update during state restore, my vote
> > is to restore the sync logic. And if we want to optimize that code
> > (seems unnecessary), then we should hook all TPR writes.
>
> I guess you mean apic_set_tpr()?
Yep.
> We will need to hook into that in addition to updating
> avic_apicv_post_state_restore() since KVM_SET_LAPIC just does a memcpy of the
> register state.
Yeah, or explicitly call the hook, e.g. like kvm_apic_set_state() does for
hwapic_isr_update(). But I don't think we should add a hook unless someone
proves that unconditionally synchronizing before VMRUN affects performance.
> > diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> > index d9931c6c4bc6..1bfebe40854f 100644
> > --- a/arch/x86/kvm/svm/svm.c
> > +++ b/arch/x86/kvm/svm/svm.c
> > @@ -4046,8 +4046,7 @@ static inline void sync_lapic_to_cr8(struct kvm_vcpu *vcpu)
> > struct vcpu_svm *svm = to_svm(vcpu);
> > u64 cr8;
> >
> > - if (nested_svm_virtualize_tpr(vcpu) ||
> > - kvm_vcpu_apicv_active(vcpu))
> > + if (nested_svm_virtualize_tpr(vcpu))
> > return;
> >
> > cr8 = kvm_get_cr8(vcpu);
>
> I agree that this is a simpler fix, so would be good to do for backport
> ease.
>
> The code in sync_lapic_to_cr8 ends up being a function call to
> kvm_get_cr8() and ~6 instructions, which isn't that much. But if we can
> gate sync'ing V_TPR to the backing page in sync_cr8_to_lapic() as well,
> then it might be good to do so.
>
>
> - Naveen
>
next prev parent reply other threads:[~2025-08-22 20:54 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-19 13:32 [PATCH 0/2] KVM: SVM: Fix missing LAPIC TPR sync into VMCB::V_TPR with AVIC on Maciej S. Szmigiero
2025-08-19 13:32 ` [PATCH 1/2] KVM: SVM: Sync TPR from LAPIC into VMCB::V_TPR when setting LAPIC regs Maciej S. Szmigiero
2025-08-21 20:38 ` Sean Christopherson
2025-08-22 9:04 ` Naveen N Rao
2025-08-22 20:54 ` Sean Christopherson [this message]
2025-08-22 23:20 ` Maciej S. Szmigiero
2025-08-22 23:41 ` Sean Christopherson
2025-08-19 13:32 ` [PATCH 2/2] KVM: selftests: Test TPR / CR8 sync and interrupt masking Maciej S. Szmigiero
2025-08-21 8:18 ` [PATCH 0/2] KVM: SVM: Fix missing LAPIC TPR sync into VMCB::V_TPR with AVIC on Naveen N Rao
2025-08-21 11:42 ` Maciej S. Szmigiero
2025-08-21 14:59 ` Alejandro Jimenez
2025-08-21 21:11 ` 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=aKjZC3peGKPj9NPq@google.com \
--to=seanjc@google.com \
--cc=Suravee.Suthikulpanit@amd.com \
--cc=alejandro.j.jimenez@oracle.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mail@maciej.szmigiero.name \
--cc=mlevitsk@redhat.com \
--cc=naveen@kernel.org \
--cc=pbonzini@redhat.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 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.