Skip to content

Commit 209afc0

Browse files
Binbin Wubonzini
authored andcommitted
KVM: TDX: Enforce KVM_IRQCHIP_SPLIT for TDX guests
Enforce KVM_IRQCHIP_SPLIT for TDX guests to disallow in-kernel I/O APIC while in-kernel local APIC is needed. APICv is always enabled by TDX module and TDX Module doesn't allow the hypervisor to modify the EOI-bitmap, i.e. all EOIs are accelerated and never trigger exits. Level-triggered interrupts and other things depending on EOI VM-Exit can't be faithfully emulated in KVM. Also, the lazy check of pending APIC EOI for RTC edge-triggered interrupts, which was introduced as a workaround when EOI cannot be intercepted, doesn't work for TDX either because kvm_apic_pending_eoi() checks vIRR and vISR, but both values are invisible in KVM. If the guest induces generation of a level-triggered interrupt, the VMM is left with the choice of dropping the interrupt, sending it as-is, or converting it to an edge-triggered interrupt. Ditto for KVM. All of those options will make the guest unhappy. There's no architectural behavior KVM can provide that's better than sending the interrupt and hoping for the best. Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com> Message-ID: <20250222014757.897978-11-binbin.wu@linux.intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 4cdf243 commit 209afc0

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

arch/x86/kvm/vmx/tdx.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "mmu/spte.h"
1616
#include "common.h"
1717
#include "posted_intr.h"
18+
#include "irq.h"
1819
#include <trace/events/kvm.h>
1920
#include "trace.h"
2021

@@ -644,8 +645,12 @@ int tdx_vcpu_create(struct kvm_vcpu *vcpu)
644645
if (kvm_tdx->state != TD_STATE_INITIALIZED)
645646
return -EIO;
646647

647-
/* TDX module mandates APICv, which requires an in-kernel local APIC. */
648-
if (!lapic_in_kernel(vcpu))
648+
/*
649+
* TDX module mandates APICv, which requires an in-kernel local APIC.
650+
* Disallow an in-kernel I/O APIC, because level-triggered interrupts
651+
* and thus the I/O APIC as a whole can't be faithfully emulated in KVM.
652+
*/
653+
if (!irqchip_split(vcpu->kvm))
649654
return -EINVAL;
650655

651656
fpstate_set_confidential(&vcpu->arch.guest_fpu);

0 commit comments

Comments
 (0)