Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752868AbdLHIlA (ORCPT ); Fri, 8 Dec 2017 03:41:00 -0500 Received: from mail-ot0-f193.google.com ([74.125.82.193]:46908 "EHLO mail-ot0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752522AbdLHIk5 (ORCPT ); Fri, 8 Dec 2017 03:40:57 -0500 X-Google-Smtp-Source: AGs4zMYcWOMSmDv7f1wGAerzKFh56TBqu6rntmfFOQkDjfyaK958PLnaaZEtdkEW1wo4RNfQLMeuAA== From: Quan Xu X-Google-Original-From: Quan Xu To: pbonzini@redhat.com, rkrcmar@redhat.com Cc: yang.zhang.wz@gmail.com, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Ben Luo , Quan Xu Subject: [PATCH RFC 4/7] KVM: timer: program timer to a dedicated CPU Date: Fri, 8 Dec 2017 16:39:47 +0800 Message-Id: <1512722390-3654-5-git-send-email-quan.xu0@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1512722390-3654-1-git-send-email-quan.xu0@gmail.com> References: <1512722390-3654-1-git-send-email-quan.xu0@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2407 Lines: 67 From: Ben Luo KVM always registers timer on the CPU which vCPU was running on. Even though vCPU thread is rescheduled to another CPU, the timer will be migrated to the target CPU as well. When timer expired, timer interrupt could make guest-mode vCPU VM-exit on this CPU. Since the working kthread scans periodically, some of the timer events may be lost or delayed. We have to program these tsc- deadline timestamps to MSR_IA32_TSC_DEADLINE as normal, which will cause VM-exit and KVM will signal the working thread through IPI to program timer, instread of registering on current CPU. Signed-off-by: Yang Zhang Signed-off-by: Quan Xu Signed-off-by: Ben Luo --- arch/x86/kvm/lapic.c | 8 +++++++- arch/x86/kvm/x86.c | 7 ++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 20a23bb..5835a27 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -2072,7 +2072,13 @@ static enum hrtimer_restart apic_timer_fn(struct hrtimer *data) struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer); struct kvm_lapic *apic = container_of(ktimer, struct kvm_lapic, lapic_timer); - apic_timer_expired(apic); + + if (pv_timer_enabled(apic->vcpu)) { + kvm_apic_local_deliver(apic, APIC_LVTT); + if (apic_lvtt_tscdeadline(apic)) + apic->lapic_timer.tscdeadline = 0; + } else + apic_timer_expired(apic); if (lapic_is_periodic(apic)) { advance_periodic_target_expiration(apic); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 5668774..3cbb223 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -26,6 +26,7 @@ #include "tss.h" #include "kvm_cache_regs.h" #include "x86.h" +#include "lapic.h" #include "cpuid.h" #include "pmu.h" #include "hyperv.h" @@ -2196,7 +2197,11 @@ 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); + if (pv_timer_enabled(vcpu)) + smp_call_function_single(PVTIMER_SYNC_CPU, + kvm_apic_sync_pv_timer, vcpu, 0); + else + kvm_set_lapic_tscdeadline_msr(vcpu, data); break; case MSR_IA32_TSC_ADJUST: if (guest_cpuid_has(vcpu, X86_FEATURE_TSC_ADJUST)) { -- 1.7.1