From: Zachary Amsden <zamsden@redhat.com>
To: kvm@vger.kernel.org
Cc: Zachary Amsden <zamsden@redhat.com>, Avi Kivity <avi@redhat.com>,
Marcelo Tosatti <mtosatti@redhat.com>,
Glauber Costa <glommer@redhat.com>,
Thomas Gleixner <tglx@linutronix.de>,
John Stultz <johnstul@us.ibm.com>,
linux-kernel@vger.kernel.org
Subject: [KVM timekeeping 29/35] TSC overrun protection
Date: Thu, 19 Aug 2010 22:07:43 -1000 [thread overview]
Message-ID: <1282291669-25709-30-git-send-email-zamsden@redhat.com> (raw)
In-Reply-To: <1282291669-25709-1-git-send-email-zamsden@redhat.com>
When running on a TSC which runs at a higher rate than the guest
TSC, and not in KVM clock mode, we should not pass through the
TSC. Add logic to detect this and switch into trap mode.
There are a few problems with this; first, the condition is not
detected at creation time. This isn't currently an issue since the
clock will be set to the highest possible rate.
The second problem is that we don't have a way to exit this mode;
the underlying TSC will accelerate beyond our control, and so the
offset must be re-adjusted backwards if the overrun condition is
ever removed.
Even entry to this mode is problematic; some hardware errata or
other miscalibration may have exposed an accelerated TSC to the
guest, in which case, we have to preserve the 'bump' of accelerated
time to avoid having a backwards clock movement.
Another problem is that CPU frequency governors may be loaded
after KVM has already started, in which case our estimated CPU
frequency may be shown to be wrong.
These problems will be dealt with separately for clarity.
Signed-off-by: Zachary Amsden <zamsden@redhat.com>
---
arch/x86/include/asm/kvm_host.h | 1 +
arch/x86/kvm/x86.c | 34 ++++++++++++++++++++++++++++------
2 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 993d13d..9b2d231 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -345,6 +345,7 @@ struct kvm_vcpu_arch {
u64 last_tsc_write;
bool tsc_rebase;
bool tsc_trapping;
+ bool tsc_overrun;
bool nmi_pending;
bool nmi_injected;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 23d1d02..887e30f 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1015,13 +1015,19 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
u64 tsc = compute_guest_tsc(v, kernel_ns);
if (tsc > tsc_timestamp)
kvm_x86_ops->adjust_tsc_offset(v, tsc-tsc_timestamp);
- }
- local_irq_restore(flags);
- if (catchup) {
- if (this_tsc_khz < v->kvm->arch.virtual_tsc_khz)
+ local_irq_restore(flags);
+
+ /* Now, see if we need to switch into trap mode */
+ if (vcpu->tsc_overrun && !vcpu->tsc_trapping)
+ kvm_x86_ops->set_tsc_trap(v, 1);
+
+ /* If we're falling behind and not trapping, re-trigger */
+ if (!vcpu->tsc_trapping &&
+ this_tsc_khz < v->kvm->arch.virtual_tsc_khz)
vcpu->tsc_rebase = 1;
return 0;
}
+ local_irq_restore(flags);
/*
* Time as measured by the TSC may go backwards when resetting the base
@@ -1098,6 +1104,17 @@ static void kvm_update_tsc_trapping(struct kvm *kvm)
int trap, i;
struct kvm_vcpu *vcpu;
+ /*
+ * Subtle point; we don't consider TSC rate here as part of
+ * the decision to trap or not. The reason for it is that
+ * TSC rate changes happen asynchronously, and are thus racy.
+ * The only safe place to check for this is above, in
+ * kvm_guest_time_update, where we've read the HZ value and
+ * the indication from the asynchronous notifier that TSC
+ * is in an overrun condition. Even that is racy, however that
+ * code is guaranteed to be called again if the CPU frequency
+ * changes yet another time before entering hardware virt.
+ */
trap = check_tsc_unstable() && atomic_read(&kvm->online_vcpus) > 1;
kvm_for_each_vcpu(i, vcpu, kvm)
kvm_x86_ops->set_tsc_trap(vcpu, trap && !vcpu->arch.time_page);
@@ -1977,8 +1994,11 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
kvm_put_guest_fpu(vcpu);
vcpu->arch.last_host_tsc = native_read_tsc();
- /* For unstable TSC, force compensation and catchup on next CPU */
- if (check_tsc_unstable()) {
+ /*
+ * For unstable TSC, force compensation and catchup on next CPU
+ * Don't need to do this if there is an overrun, as we'll trap.
+ */
+ if (check_tsc_unstable() && !vcpu->arch.tsc_overrun) {
vcpu->arch.tsc_rebase = 1;
kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
}
@@ -4342,6 +4362,8 @@ static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long va
kvm_for_each_vcpu(i, vcpu, kvm) {
if (vcpu->cpu != freq->cpu)
continue;
+ if (freq->new > kvm->arch.virtual_tsc_khz)
+ vcpu->arch.tsc_overrun = 1;
kvm_request_clock_update(vcpu);
if (vcpu->cpu != smp_processor_id())
send_ipi = 1;
--
1.7.1
next prev parent reply other threads:[~2010-08-20 8:10 UTC|newest]
Thread overview: 90+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1282291669-25709-1-git-send-email-zamsden@redhat.com>
2010-08-20 8:07 ` [KVM timekeeping 01/35] Drop vm_init_tsc Zachary Amsden
2010-08-20 16:54 ` Glauber Costa
2010-08-20 8:07 ` [KVM timekeeping 02/35] Convert TSC writes to TSC offset writes Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 03/35] Move TSC offset writes to common code Zachary Amsden
2010-08-20 17:06 ` Glauber Costa
2010-08-24 0:51 ` Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 04/35] Fix SVM VMCB reset Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 05/35] Move TSC reset out of vmcb_init Zachary Amsden
2010-08-20 17:08 ` Glauber Costa
2010-08-24 0:52 ` Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 06/35] TSC reset compensation Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 07/35] Make cpu_tsc_khz updates use local CPU Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 08/35] Warn about unstable TSC Zachary Amsden
2010-08-20 17:28 ` Glauber Costa
2010-08-24 0:56 ` Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 09/35] Unify TSC logic Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 10/35] Fix deep C-state TSC desynchronization Zachary Amsden
2010-08-20 17:30 ` Glauber Costa
2010-09-14 9:10 ` Jan Kiszka
2010-09-14 9:27 ` Avi Kivity
2010-09-14 10:40 ` Jan Kiszka
2010-09-14 10:47 ` Avi Kivity
2010-09-14 19:32 ` Zachary Amsden
2010-09-14 22:26 ` Jan Kiszka
2010-09-14 23:40 ` Zachary Amsden
2010-09-15 5:34 ` Jan Kiszka
2010-09-15 7:55 ` Avi Kivity
2010-09-15 8:04 ` Jan Kiszka
2010-09-15 12:29 ` Glauber Costa
2010-09-15 4:07 ` Zachary Amsden
2010-09-15 8:09 ` Jan Kiszka
2010-09-15 12:32 ` Glauber Costa
2010-09-15 18:27 ` Jan Kiszka
2010-09-17 22:09 ` Zachary Amsden
2010-09-17 22:31 ` Zachary Amsden
2010-09-18 23:53 ` Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 11/35] Add helper functions for time computation Zachary Amsden
2010-08-20 17:34 ` Glauber Costa
2010-08-24 0:58 ` Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 12/35] Robust TSC compensation Zachary Amsden
2010-08-20 17:40 ` Glauber Costa
2010-08-24 1:01 ` Zachary Amsden
2010-08-24 21:33 ` Daniel Verkamp
2010-08-20 8:07 ` [KVM timekeeping 13/35] Perform hardware_enable in CPU_STARTING callback Zachary Amsden
2010-08-27 16:32 ` Jan Kiszka
2010-08-27 23:43 ` Zachary Amsden
2010-08-30 9:10 ` Jan Kiszka
2010-08-20 8:07 ` [KVM timekeeping 14/35] Add clock sync request to hardware enable Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 15/35] Move scale_delta into common header Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 16/35] Fix a possible backwards warp of kvmclock Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 17/35] Implement getnsboottime kernel API Zachary Amsden
2010-08-20 18:39 ` john stultz
2010-08-20 23:37 ` Zachary Amsden
2010-08-21 0:02 ` john stultz
2010-08-21 0:52 ` Zachary Amsden
2010-08-21 1:04 ` john stultz
2010-08-21 1:22 ` Zachary Amsden
2010-08-27 18:05 ` Jan Kiszka
2010-08-27 23:48 ` Zachary Amsden
2010-08-30 18:07 ` Jan Kiszka
2010-08-20 8:07 ` [KVM timekeeping 18/35] Use getnsboottime in KVM Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 19/35] Add timekeeping documentation Zachary Amsden
2010-08-20 17:50 ` Glauber Costa
2010-08-20 8:07 ` [KVM timekeeping 20/35] Make math work for other scales Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 21/35] Track max tsc_khz Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 22/35] Track tsc last write in vcpu Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 23/35] Set initial TSC rate conversion factors Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 24/35] Timer request function renaming Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 25/35] Add clock catchup mode Zachary Amsden
2010-08-25 17:27 ` Marcelo Tosatti
2010-08-25 20:48 ` Zachary Amsden
2010-08-25 22:01 ` Marcelo Tosatti
2010-08-25 23:38 ` Glauber Costa
2010-08-26 0:17 ` Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 26/35] Catchup slower TSC to guest rate Zachary Amsden
2010-09-07 3:44 ` Dong, Eddie
2010-09-07 22:14 ` Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 27/35] Add TSC trapping Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 28/35] Unstable TSC write compensation Zachary Amsden
2010-08-20 8:07 ` Zachary Amsden [this message]
2010-08-20 8:07 ` [KVM timekeeping 30/35] IOCTL for setting TSC rate Zachary Amsden
2010-08-20 17:56 ` Glauber Costa
2010-08-21 16:11 ` Arnd Bergmann
2010-08-20 8:07 ` [KVM timekeeping 31/35] Exit conditions for TSC trapping Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 32/35] Entry " Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 33/35] Indicate reliable TSC in kvmclock Zachary Amsden
2010-08-20 17:45 ` Glauber Costa
2010-08-24 1:14 ` Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 34/35] Remove dead code Zachary Amsden
2010-08-20 8:07 ` [KVM timekeeping 35/35] Add some debug stuff Zachary Amsden
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1282291669-25709-30-git-send-email-zamsden@redhat.com \
--to=zamsden@redhat.com \
--cc=avi@redhat.com \
--cc=glommer@redhat.com \
--cc=johnstul@us.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mtosatti@redhat.com \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®