Setting the TSC deadline MSR that are initiated by the host (using ioctl's) may cause superfluous interrupt. This occurs in the following case: 1. A TSC deadline timer interrupt is pending. 2. TSC deadline was still not cleared (which happens during vcpu_run). 3. Userspace uses KVM_GET_MSRS/KVM_SET_MSRS to load the same deadline msr. To solve this situation, ignore host initiated TSC deadline writes that do not change the deadline value. Signed-off-by: Nadav Amit <namit@xxxxxxxxxxxxxxxxx> --- arch/x86/kvm/lapic.c | 7 ++++++- arch/x86/kvm/lapic.h | 3 ++- arch/x86/kvm/x86.c | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index b8345dd..0bcf2e1 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1346,14 +1346,19 @@ u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu) return apic->lapic_timer.tscdeadline; } -void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data) +void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, + struct msr_data *msr_info) { struct kvm_lapic *apic = vcpu->arch.apic; + u64 data = msr_info->data; if (!kvm_vcpu_has_lapic(vcpu) || apic_lvtt_oneshot(apic) || apic_lvtt_period(apic)) return; + if (msr_info->host_initiated && apic->lapic_timer.tscdeadline == data) + return; + hrtimer_cancel(&apic->lapic_timer.timer); /* Inject here so clearing tscdeadline won't override new value */ if (apic_has_pending_timer(vcpu)) diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 6a11845..5bfa3db 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -71,7 +71,8 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu, int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu); u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu); -void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data); +void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, + struct msr_data *msr_info); void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset); void kvm_apic_set_eoi_accelerated(struct kvm_vcpu *vcpu, int vector); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e903167..8c2745c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2093,7 +2093,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case APIC_BASE_MSR ... APIC_BASE_MSR + 0x3ff: return kvm_x2apic_msr_write(vcpu, msr, data); case MSR_IA32_TSCDEADLINE: - kvm_set_lapic_tscdeadline_msr(vcpu, data); + kvm_set_lapic_tscdeadline_msr(vcpu, msr_info); break; case MSR_IA32_TSC_ADJUST: if (guest_cpuid_has_tsc_adjust(vcpu)) { -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html