All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Dongli Zhang <dongli.zhang@oracle.com>
Cc: kvm@vger.kernel.org, x86@kernel.org,
	linux-kernel@vger.kernel.org,  chao.gao@intel.com,
	pbonzini@redhat.com, tglx@linutronix.de, mingo@redhat.com,
	 bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com,
	joe.jin@oracle.com,  alejandro.j.jimenez@oracle.com
Subject: Re: [PATCH v2 1/1] KVM: VMX: configure SVI during runtime APICv activation
Date: Thu, 13 Nov 2025 13:13:52 -0800	[thread overview]
Message-ID: <aRZKEC4n9hpLVCRp@google.com> (raw)
In-Reply-To: <72da0532-908b-40c2-a4e4-7ef1895547c7@oracle.com>

On Wed, Nov 12, 2025, Dongli Zhang wrote:
> Hi Sean,
> 
> On 11/12/25 6:47 AM, Sean Christopherson wrote:
> > On Sun, Nov 09, 2025, Dongli Zhang wrote:
> > diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> > index 91b6f2f3edc2..653b8b713547 100644
> > --- a/arch/x86/kvm/vmx/vmx.c
> > +++ b/arch/x86/kvm/vmx/vmx.c
> > @@ -4430,6 +4430,14 @@ void vmx_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
> >                                                  kvm_vcpu_apicv_active(vcpu));
> >  
> >         vmx_update_msr_bitmap_x2apic(vcpu);
> > +
> > +       /*
> > +        * Refresh SVI if APICv is enabled, as any changes KVM made to vISR
> > +        * while APICv was disabled need to be reflected in SVI, e.g. so that
> > +        * the next accelerated EOI will clear the correct vector in vISR.
> > +        */
> > +       if (kvm_vcpu_apicv_active(vcpu))
> > +               kvm_apic_update_hwapic_isr(vcpu);
> >  }
> >  
> >  static u32 vmx_exec_control(struct vcpu_vmx *vmx)
> > @@ -6880,7 +6888,7 @@ void vmx_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr)
> >  
> >         /*
> >          * If L2 is active, defer the SVI update until vmcs01 is loaded, as SVI
> > -        * is only relevant for if and only if Virtual Interrupt Delivery is
> > +        * is only relevant for L2 if and only if Virtual Interrupt Delivery is
> >          * enabled in vmcs12, and if VID is enabled then L2 EOIs affect L2's
> >          * vAPIC, not L1's vAPIC.  KVM must update vmcs01 on the next nested
> >          * VM-Exit, otherwise L1 with run with a stale SVI.
> 
> 
> As a quick reply, the idea is to call kvm_apic_update_hwapic_isr() in
> vmx_refresh_apicv_exec_ctrl(), instead of __kvm_vcpu_update_apicv().
> 
> I think the below case doesn't work:
> 
> 1. APICv is activated when vCPU is in L2.
> 
> kvm_vcpu_update_apicv()
> -> __kvm_vcpu_update_apicv()
>    -> vmx_refresh_apicv_exec_ctrl()
> 
> vmx_refresh_apicv_exec_ctrl() returns after setting:
> vmx->nested.update_vmcs01_apicv_status = true.
> 
> 
> 2. On exit from L2 to L1, __nested_vmx_vmexit() requests for KVM_REQ_APICV_UPDATE.
> 
> __nested_vmx_vmexit()
> -> leave_guest_mode(vcpu)
> -> kvm_make_request(KVM_REQ_APICV_UPDATE, vcpu)
> 
> 
> 3. vCPU processes KVM_REQ_APICV_UPDATE again.
> 
> This time, __kvm_vcpu_update_apicv() returns without calling
> refresh_apicv_exec_ctrl(), because (apic->apicv_active == activate).
> 
> vmx_refresh_apicv_exec_ctrl() doesn't get any chance to be called.

Oof, that's nasty.

> In order to call kvm_apic_update_hwapic_isr() in vmx_refresh_apicv_exec_ctrl(),
> we may need to resolve the issue mentioned by Chao, for instance, with something
> like:
> 
> diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
> index bcea087b642f..1725c6a94f99 100644
> --- a/arch/x86/kvm/vmx/nested.c
> +++ b/arch/x86/kvm/vmx/nested.c
> @@ -19,6 +19,7 @@
>  #include "trace.h"
>  #include "vmx.h"
>  #include "smm.h"
> +#include "x86_ops.h"
> 
>  static bool __read_mostly enable_shadow_vmcs = 1;
>  module_param_named(enable_shadow_vmcs, enable_shadow_vmcs, bool, S_IRUGO);
> @@ -5216,7 +5217,7 @@ void __nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32
> vm_exit_reason,
> 
>         if (vmx->nested.update_vmcs01_apicv_status) {
>                 vmx->nested.update_vmcs01_apicv_status = false;
> -               kvm_make_request(KVM_REQ_APICV_UPDATE, vcpu);
> +               vmx_refresh_apicv_exec_ctrl(vcpu);
>         }

Hmm, what if we go the opposite direction and bundle the vISR update into
KVM_REQ_APICV_UPDATE?  Then we can drop nested.update_vmcs01_hwapic_isr, and
hopefully avoid similar ordering issues in the future.

diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 564f5af5ae86..7bf44a8111e5 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -5168,11 +5168,6 @@ void __nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason,
                kvm_make_request(KVM_REQ_APICV_UPDATE, vcpu);
        }
 
-       if (vmx->nested.update_vmcs01_hwapic_isr) {
-               vmx->nested.update_vmcs01_hwapic_isr = false;
-               kvm_apic_update_hwapic_isr(vcpu);
-       }
-
        if ((vm_exit_reason != -1) &&
            (enable_shadow_vmcs || nested_vmx_is_evmptr12_valid(vmx)))
                vmx->nested.need_vmcs12_to_shadow_sync = true;
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 6f374c815ce2..64edf47bed02 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6907,7 +6907,7 @@ void vmx_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr)
                 */
                WARN_ON_ONCE(vcpu->wants_to_run &&
                             nested_cpu_has_vid(get_vmcs12(vcpu)));
-               to_vmx(vcpu)->nested.update_vmcs01_hwapic_isr = true;
+               to_vmx(vcpu)->nested.update_vmcs01_apicv_status = true;
                return;
        }
 
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index bc3ed3145d7e..17bd43d6faaf 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -135,7 +135,6 @@ struct nested_vmx {
        bool reload_vmcs01_apic_access_page;
        bool update_vmcs01_cpu_dirty_logging;
        bool update_vmcs01_apicv_status;
-       bool update_vmcs01_hwapic_isr;
 
        /*
         * Enlightened VMCS has been enabled. It does not mean that L1 has to
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9c2e28028c2b..445bf22ee519 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -11218,8 +11218,10 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
                if (kvm_check_request(KVM_REQ_HV_STIMER, vcpu))
                        kvm_hv_process_stimers(vcpu);
 #endif
-               if (kvm_check_request(KVM_REQ_APICV_UPDATE, vcpu))
+               if (kvm_check_request(KVM_REQ_APICV_UPDATE, vcpu)) {
                        kvm_vcpu_update_apicv(vcpu);
+                       kvm_apic_update_hwapic_isr(vcpu);
+               }
                if (kvm_check_request(KVM_REQ_APF_READY, vcpu))
                        kvm_check_async_pf_completion(vcpu);

  reply	other threads:[~2025-11-13 21:13 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-10  6:32 [PATCH v2 1/1] KVM: VMX: configure SVI during runtime APICv activation Dongli Zhang
2025-11-10  7:08 ` Chao Gao
2025-11-12 14:47 ` Sean Christopherson
2025-11-13  3:06   ` Dongli Zhang
2025-11-13 21:13     ` Sean Christopherson [this message]
2025-11-18  3:36       ` Dongli Zhang
2025-12-05  2:15         ` Sean Christopherson
2025-12-05 18:12           ` Dongli Zhang
2025-12-05 18:27             ` 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=aRZKEC4n9hpLVCRp@google.com \
    --to=seanjc@google.com \
    --cc=alejandro.j.jimenez@oracle.com \
    --cc=bp@alien8.de \
    --cc=chao.gao@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=dongli.zhang@oracle.com \
    --cc=hpa@zytor.com \
    --cc=joe.jin@oracle.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=x86@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 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.