----- pbonzini@xxxxxxxxxx wrote: > On 08/02/2018 13:09, Liran Alon wrote: > > ----- pbonzini@xxxxxxxxxx wrote: > >> On 08/02/2018 06:13, Chao Gao wrote: > > > > A possible patch to fix this is to change vmx_hwapic_irr_update() > such that > > if is_guest_mode(vcpu)==true, we should return max(max_irr, rvi) and > return > > that value into apic_has_interrupt_for_ppr(). > > Need to verify that it doesn't break other flows but I think it > makes sense. > > What do you think? > > Yeah, I think it makes sense though I'd need to look a lot more at > arch/x86/kvm/lapic.c and arch/x86/kvm/vmx.c to turn that into a > patch! > > Paolo After thinking about this a bit more, I don't like my previous suggestion. As we don't semantically want to change the value returned from kvm_apic_has_interrupt(). Instead, it makes more sense to change kvm_cpu_has_interrupt() to check for RVI>PPR in case is_guest_mode(vcpu)==true. Something like (partial theoretical patch): @@ -97,6 +97,14 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v) if (kvm_cpu_has_extint(v)) return 1; + /* + * When running L2, L1 controls vmcs02 RVI via vmcs12. + * Therefore, it is possible RVI indicates pending interrupt + * for vCPU while LAPIC IRR is empty. + */ + if (is_guest_mode(v) && + (kvm_x86_ops->hwapic_has_interrupt(v) != -1)) + return 1; + return kvm_apic_has_interrupt(v) != -1; /* LAPIC */ } Where: +static int vmx_get_rvi(void) +{ + return ((u8)vmcs_read16(GUEST_INTR_STATUS) & 0xff); +} +static int vmx_hwapic_has_interrupt(struct kvm_vcpu *vcpu) +{ + int vector = vmx_get_rvi(vcpu); + return kvm_apic_has_interrupt_for_vector(vector); +} +int kvm_apic_has_interrupt_for_vector(struct kvm_vcpu *vcpu, int vector) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + u32 ppr; + + if (!apic_enabled(apic)) + return -1; + + __apic_update_ppr(apic, &ppr); + return (((vector & 0xF0) > ppr) ? (vector) : (-1)); +} +EXPORT_SYMBOL_GPL(kvm_apic_has_interrupt_for_vector); Regards, -Liran