On 2/22/2025 9:47 AM, Binbin Wu wrote: > From: Isaku Yamahata <isaku.yamahata@xxxxxxxxx> > > Implement non-NMI interrupt injection for TDX via posted interrupt. > > As CPU state is protected and APICv is enabled for the TDX guest, TDX > supports non-NMI interrupt injection only by posted interrupt. Posted > interrupt descriptors (PIDs) are allocated in shared memory, KVM can > update them directly. If target vCPU is in non-root mode, send posted > interrupt notification to the vCPU and hardware will sync PIR to vIRR > atomically. Otherwise, kick it to pick up the interrupt from PID. To > post pending interrupts in the PID, KVM can generate a self-IPI with > notification vector prior to TD entry. > > Since the guest status of TD vCPU is protected, assume interrupt is > always allowed. Ignore the code path for event injection mechanism or > LAPIC emulation for TDX. > > Signed-off-by: Isaku Yamahata <isaku.yamahata@xxxxxxxxx> > Co-developed-by: Binbin Wu <binbin.wu@xxxxxxxxxxxxxxx> > Signed-off-by: Binbin Wu <binbin.wu@xxxxxxxxxxxxxxx> > Reviewed-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> > --- > TDX interrupts v3: > - Fix whitespace (Chao) > - Add trace_kvm_apicv_accept_irq() in tdx_deliver_interrupt() to match > VMX. (Chao) > > TDX interrupts v2: > - Rebased due to moving pi_desc to vcpu_vt. > > TDX interrupts v1: > - Renamed from "KVM: TDX: Implement interrupt injection" > to "KVM: TDX: Implement non-NMI interrupt injection" > - Rewrite changelog. > - Add a blank line. (Binbin) > - Split posted interrupt delivery code movement to a separate patch. > - Split kvm_wait_lapic_expire() out to a separate patch. (Chao) > - Use __pi_set_sn() to resolve upstream conflicts. > - Use kvm_x86_call() > --- > arch/x86/kvm/vmx/main.c | 94 ++++++++++++++++++++++++++++++---- > arch/x86/kvm/vmx/posted_intr.c | 2 +- > arch/x86/kvm/vmx/posted_intr.h | 2 + > arch/x86/kvm/vmx/tdx.c | 24 ++++++++- > arch/x86/kvm/vmx/vmx.c | 8 --- > arch/x86/kvm/vmx/x86_ops.h | 6 +++ > 6 files changed, 117 insertions(+), 19 deletions(-) > > diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c > index 42a62be9a035..312433635bee 100644 > --- a/arch/x86/kvm/vmx/main.c > +++ b/arch/x86/kvm/vmx/main.c > @@ -191,6 +191,34 @@ static int vt_handle_exit(struct kvm_vcpu *vcpu, > return vmx_handle_exit(vcpu, fastpath); > } > > +static void vt_apicv_pre_state_restore(struct kvm_vcpu *vcpu) > +{ > + struct pi_desc *pi = vcpu_to_pi_desc(vcpu); > + > + pi_clear_on(pi); > + memset(pi->pir, 0, sizeof(pi->pir)); > +} > + [..] > @@ -379,11 +455,11 @@ struct kvm_x86_ops vt_x86_ops __initdata = { > .set_apic_access_page_addr = vmx_set_apic_access_page_addr, > .refresh_apicv_exec_ctrl = vmx_refresh_apicv_exec_ctrl, > .load_eoi_exitmap = vmx_load_eoi_exitmap, > - .apicv_pre_state_restore = vmx_apicv_pre_state_restore, > + .apicv_pre_state_restore = vt_apicv_pre_state_restore, [..] > > diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c > index 2d4185df1581..d4868e3bd9a2 100644 > --- a/arch/x86/kvm/vmx/vmx.c > +++ b/arch/x86/kvm/vmx/vmx.c > @@ -6908,14 +6908,6 @@ void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) > vmcs_write64(EOI_EXIT_BITMAP3, eoi_exit_bitmap[3]); > } > > -void vmx_apicv_pre_state_restore(struct kvm_vcpu *vcpu) > -{ > - struct vcpu_vt *vt = to_vt(vcpu); > - > - pi_clear_on(&vt->pi_desc); > - memset(vt->pi_desc.pir, 0, sizeof(vt->pi_desc.pir)); > -} > - We can remove the declaration of vmx_apicv_pre_state_restore() in x86_ops.h after this change.