If APICv is activated while L2 is running and triggers an SVI update,
temporarily load vmcs01 and immediately update SVI instead of deferring
the update until the next nested VM-Exit. This will eventually allow
killing off kvm_apic_update_hwapic_isr(), and all of nVMX's deferred
APICv updates.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/vmx/nested.c | 5 -----
arch/x86/kvm/vmx/vmx.c | 19 +++++++------------
arch/x86/kvm/vmx/vmx.h | 1 -
3 files changed, 7 insertions(+), 18 deletions(-)
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 8efab1cf833f..c2c96e4fe20e 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -5160,11 +5160,6 @@ void __nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason,
vmx_refresh_apicv_exec_ctrl(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 3ee86665d8de..74a815cddd37 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6963,21 +6963,16 @@ void vmx_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr)
u16 status;
u8 old;
- /*
- * 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
- * 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.
- */
- if (is_guest_mode(vcpu)) {
- to_vmx(vcpu)->nested.update_vmcs01_hwapic_isr = true;
- return;
- }
-
if (max_isr == -1)
max_isr = 0;
+ /*
+ * Always update SVI in vmcs01, as SVI 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.
+ */
+ guard(vmx_vmcs01)(vcpu);
+
status = vmcs_read16(GUEST_INTR_STATUS);
old = status >> 8;
if (max_isr != old) {
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index 36f48c4b39c0..53969e49d9d1 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -134,7 +134,6 @@ struct nested_vmx {
bool change_vmcs01_virtual_apic_mode;
bool reload_vmcs01_apic_access_page;
bool update_vmcs01_apicv_status;
- bool update_vmcs01_hwapic_isr;
/*
* Enlightened VMCS has been enabled. It does not mean that L1 has to
--
2.52.0.223.gf5cc29aaa4-goog