* [PATCH v3 1/3] KVM: VMX: Update EOI bitmaps even if APICv is (temporarily) inhibited
2026-10-27 22:30 [PATCH v3 0/3] KVM: x86: Drop deferred updates of EOI bitmaps Sean Christopherson
@ 2026-10-27 22:30 ` Sean Christopherson
2026-10-27 22:30 ` [PATCH v3 2/3] KVM: x86: Switch to vmcs01 to update EOI exiting bitmap on-demand if L2 is active Sean Christopherson
2026-10-27 22:30 ` [PATCH v3 3/3] KVM: x86: Consolidate invocations of kvm_x86_ops.load_eoi_exitmap() Sean Christopherson
2 siblings, 0 replies; 4+ messages in thread
From: Sean Christopherson @ 2026-10-27 22:30 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: kvm, linux-kernel, Sashiko Bot, Amirmohammad Eftekhar
As KVM does with IRTEs for device posted interrupts, update the EOI bitmaps
if APICv *can* be enabled for the vCPU, not just if APICv is *currently*
enabled and active. I.e. keep the bitmaps up-to-date at all times so that
KVM doesn't need to refresh the bitmaps if APICv is unhibited in the future.
In the worst case scenario, failure to update the EOI bitmaps means KVM
could miss an EOI and effectively break level-triggered IRQs, e.g. if a GSI
routing change occurred while APICv was inhibitied.
Reported-by: Sashiko Bot <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/sashiko-outbox-180887@kernel.org
Fixes: d62caabb41f3 ("kvm/x86: per-vcpu apicv deactivation support")
Cc: stable@vger.kernel.org
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/vmx/vmx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index b341af4c6057..d8e66d67138f 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -7079,7 +7079,7 @@ int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu)
void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
{
- if (!kvm_vcpu_apicv_active(vcpu))
+ if (!lapic_in_kernel(vcpu) || !enable_apicv)
return;
vmcs_write64(EOI_EXIT_BITMAP0, eoi_exit_bitmap[0]);
--
2.56.0.307.g5fe7bd680c-goog
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH v3 2/3] KVM: x86: Switch to vmcs01 to update EOI exiting bitmap on-demand if L2 is active
2026-10-27 22:30 [PATCH v3 0/3] KVM: x86: Drop deferred updates of EOI bitmaps Sean Christopherson
2026-10-27 22:30 ` [PATCH v3 1/3] KVM: VMX: Update EOI bitmaps even if APICv is (temporarily) inhibited Sean Christopherson
@ 2026-10-27 22:30 ` Sean Christopherson
2026-10-27 22:30 ` [PATCH v3 3/3] KVM: x86: Consolidate invocations of kvm_x86_ops.load_eoi_exitmap() Sean Christopherson
2 siblings, 0 replies; 4+ messages in thread
From: Sean Christopherson @ 2026-10-27 22:30 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: kvm, linux-kernel, Sashiko Bot, Amirmohammad Eftekhar
If KVM needs to update the EOI bitmap while L2 is running, temporarily load
vmcs01 and immediately refresh the bitmap in vmcs01 instead of deferring
the update until the next nested VM-Exit. I.e. give the EOI bitmap the
same treatment as the many other updates that were previously deferred.
Reported-by: Amirmohammad Eftekhar <amirmohammad.eftekhar@cispa.de>
Closes: https://lore.kernel.org/all/20261017093016.32348-2-amirmohammad.eftekhar@cispa.de
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/include/asm/kvm_host.h | 3 +--
arch/x86/kvm/regs.h | 6 ------
arch/x86/kvm/vmx/vmx.c | 2 ++
arch/x86/kvm/x86.c | 13 -------------
4 files changed, 3 insertions(+), 21 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 0378577d9d8b..92aae551bfae 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -113,7 +113,7 @@
#define KVM_REQ_HV_RESET KVM_ARCH_REQ(20)
#define KVM_REQ_HV_EXIT KVM_ARCH_REQ(21)
#define KVM_REQ_HV_STIMER KVM_ARCH_REQ(22)
-#define KVM_REQ_LOAD_EOI_EXITMAP KVM_ARCH_REQ(23)
+/*#define FREE!!! USE ME!!! KVM_ARCH_REQ(23) */
#define KVM_REQ_GET_NESTED_STATE_PAGES KVM_ARCH_REQ(24)
#define KVM_REQ_APICV_UPDATE \
KVM_ARCH_REQ_FLAGS(25, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
@@ -746,7 +746,6 @@ struct kvm_vcpu_arch {
u64 host_debugctl;
u64 apic_base;
struct kvm_lapic *apic; /* kernel irqchip context */
- bool load_eoi_exitmap_pending;
DECLARE_BITMAP(ioapic_handled_vectors, 256);
unsigned long apic_attention;
int32_t apic_arb_prio;
diff --git a/arch/x86/kvm/regs.h b/arch/x86/kvm/regs.h
index 97c17b120a57..04d047f46753 100644
--- a/arch/x86/kvm/regs.h
+++ b/arch/x86/kvm/regs.h
@@ -463,12 +463,6 @@ static inline void enter_guest_mode(struct kvm_vcpu *vcpu)
static inline void leave_guest_mode(struct kvm_vcpu *vcpu)
{
vcpu->arch.hflags &= ~HF_GUEST_MASK;
-
- if (vcpu->arch.load_eoi_exitmap_pending) {
- vcpu->arch.load_eoi_exitmap_pending = false;
- kvm_make_request(KVM_REQ_LOAD_EOI_EXITMAP, vcpu);
- }
-
vcpu->stat.guest_mode = 0;
}
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index d8e66d67138f..ba5575002538 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -7082,6 +7082,8 @@ void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
if (!lapic_in_kernel(vcpu) || !enable_apicv)
return;
+ guard(vmx_vmcs01)(vcpu);
+
vmcs_write64(EOI_EXIT_BITMAP0, eoi_exit_bitmap[0]);
vmcs_write64(EOI_EXIT_BITMAP1, eoi_exit_bitmap[1]);
vmcs_write64(EOI_EXIT_BITMAP2, eoi_exit_bitmap[2]);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 32563a91fba9..0028d57e964a 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8062,17 +8062,6 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors);
#endif
- if (is_guest_mode(vcpu))
- vcpu->arch.load_eoi_exitmap_pending = true;
- else
- kvm_make_request(KVM_REQ_LOAD_EOI_EXITMAP, vcpu);
-}
-
-static void vcpu_load_eoi_exitmap(struct kvm_vcpu *vcpu)
-{
- if (!kvm_apic_hw_enabled(vcpu->arch.apic))
- return;
-
#ifdef CONFIG_KVM_HYPERV
if (to_hv_vcpu(vcpu)) {
u64 eoi_exit_bitmap[4];
@@ -8240,8 +8229,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
}
if (kvm_check_request(KVM_REQ_SCAN_IOAPIC, vcpu))
vcpu_scan_ioapic(vcpu);
- if (kvm_check_request(KVM_REQ_LOAD_EOI_EXITMAP, vcpu))
- vcpu_load_eoi_exitmap(vcpu);
if (kvm_check_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu))
kvm_vcpu_reload_apic_access_page(vcpu);
#ifdef CONFIG_KVM_HYPERV
--
2.56.0.307.g5fe7bd680c-goog
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH v3 3/3] KVM: x86: Consolidate invocations of kvm_x86_ops.load_eoi_exitmap()
2026-10-27 22:30 [PATCH v3 0/3] KVM: x86: Drop deferred updates of EOI bitmaps Sean Christopherson
2026-10-27 22:30 ` [PATCH v3 1/3] KVM: VMX: Update EOI bitmaps even if APICv is (temporarily) inhibited Sean Christopherson
2026-10-27 22:30 ` [PATCH v3 2/3] KVM: x86: Switch to vmcs01 to update EOI exiting bitmap on-demand if L2 is active Sean Christopherson
@ 2026-10-27 22:30 ` Sean Christopherson
2 siblings, 0 replies; 4+ messages in thread
From: Sean Christopherson @ 2026-10-27 22:30 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: kvm, linux-kernel, Sashiko Bot, Amirmohammad Eftekhar
Rework KVM's handling of EOI exit bitmap updates to consolidate the calls
to vendor code so that it's easier to see that the Hyper-V path is doing
the exact same thing, just with extra input to account for the SynIC
vectors.
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/x86.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 0028d57e964a..483dac323c8e 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8047,6 +8047,9 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_inc_or_dec_irq_window_inhibit);
static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
{
+ unsigned long *eoi_exit_bitmap = vcpu->arch.ioapic_handled_vectors;
+ DECLARE_BITMAP(__eoi_exit_bitmap, 256) __maybe_unused;
+
if (!kvm_apic_present(vcpu))
return;
@@ -8064,17 +8067,14 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
#ifdef CONFIG_KVM_HYPERV
if (to_hv_vcpu(vcpu)) {
- u64 eoi_exit_bitmap[4];
-
- bitmap_or((ulong *)eoi_exit_bitmap,
+ bitmap_or(__eoi_exit_bitmap,
vcpu->arch.ioapic_handled_vectors,
to_hv_synic(vcpu)->vec_bitmap, 256);
- kvm_x86_call(load_eoi_exitmap)(vcpu, eoi_exit_bitmap);
- return;
+
+ eoi_exit_bitmap = __eoi_exit_bitmap;
}
#endif
- kvm_x86_call(load_eoi_exitmap)(
- vcpu, (u64 *)vcpu->arch.ioapic_handled_vectors);
+ kvm_x86_call(load_eoi_exitmap)(vcpu, (u64 *)eoi_exit_bitmap);
}
void kvm_arch_guest_memory_reclaimed(struct kvm *kvm)
--
2.56.0.307.g5fe7bd680c-goog
^ permalink raw reply [flat|nested] 4+ messages in thread