[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 27/31] kvm: i386: allow TSC to differ by NTP correction bounds wit
From: |
Paolo Bonzini |
Subject: |
[PULL 27/31] kvm: i386: allow TSC to differ by NTP correction bounds without TSC scaling |
Date: |
Wed, 24 Jun 2020 06:50:44 -0400 |
From: Marcelo Tosatti <mtosatti@redhat.com>
The Linux TSC calibration procedure is subject to small variations
(its common to see +-1 kHz difference between reboots on a given CPU, for
example).
So migrating a guest between two hosts with identical processor can fail, in
case
of a small variation in calibrated TSC between them.
Allow a conservative 250ppm error between host TSC and VM TSC frequencies,
rather than requiring an exact match. NTP daemon in the guest can
correct this difference.
Also change migration to accept this bound.
KVM_SET_TSC_KHZ depends on a kernel interface change. Without this change,
the behaviour remains the same: in case of a different frequency
between host and VM, KVM_SET_TSC_KHZ will fail and QEMU will exit.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Message-Id: <20200616165805.GA324612@fuller.cnet>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/kvm.c | 46 +++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 41 insertions(+), 5 deletions(-)
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index b3c13cb898..6adbff3d74 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -740,26 +740,62 @@ static bool hyperv_enabled(X86CPU *cpu)
cpu->hyperv_features || cpu->hyperv_passthrough);
}
+/*
+ * Check whether target_freq is within conservative
+ * ntp correctable bounds (250ppm) of freq
+ */
+static inline bool freq_within_bounds(int freq, int target_freq)
+{
+ int max_freq = freq + (freq * 250 / 1000000);
+ int min_freq = freq - (freq * 250 / 1000000);
+
+ if (target_freq >= min_freq && target_freq <= max_freq) {
+ return true;
+ }
+
+ return false;
+}
+
static int kvm_arch_set_tsc_khz(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
- int r;
+ int r, cur_freq;
+ bool set_ioctl = false;
if (!env->tsc_khz) {
return 0;
}
- r = kvm_check_extension(cs->kvm_state, KVM_CAP_TSC_CONTROL) ?
+ cur_freq = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
+ kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) : -ENOTSUP;
+
+ /*
+ * If TSC scaling is supported, attempt to set TSC frequency.
+ */
+ if (kvm_check_extension(cs->kvm_state, KVM_CAP_TSC_CONTROL)) {
+ set_ioctl = true;
+ }
+
+ /*
+ * If desired TSC frequency is within bounds of NTP correction,
+ * attempt to set TSC frequency.
+ */
+ if (cur_freq != -ENOTSUP && freq_within_bounds(cur_freq, env->tsc_khz)) {
+ set_ioctl = true;
+ }
+
+ r = set_ioctl ?
kvm_vcpu_ioctl(cs, KVM_SET_TSC_KHZ, env->tsc_khz) :
-ENOTSUP;
+
if (r < 0) {
/* When KVM_SET_TSC_KHZ fails, it's an error only if the current
* TSC frequency doesn't match the one we want.
*/
- int cur_freq = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ)
?
- kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :
- -ENOTSUP;
+ cur_freq = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
+ kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :
+ -ENOTSUP;
if (cur_freq <= 0 || cur_freq != env->tsc_khz) {
warn_report("TSC frequency mismatch between "
"VM (%" PRId64 " kHz) and host (%d kHz), "
--
2.26.2
- [PULL 15/31] softfloat: merge floatx80_mod and floatx80_rem, (continued)
- [PULL 15/31] softfloat: merge floatx80_mod and floatx80_rem, Paolo Bonzini, 2020/06/24
- [PULL 16/31] softfloat: fix floatx80 remainder pseudo-denormal check for zero, Paolo Bonzini, 2020/06/24
- [PULL 18/31] softfloat: do not set denominator high bit for floatx80 remainder, Paolo Bonzini, 2020/06/24
- [PULL 12/31] Makefile: Install qemu-[qmp/ga]-ref.* into the directory "interop", Paolo Bonzini, 2020/06/24
- [PULL 14/31] target/i386: reimplement f2xm1 using floatx80 operations, Paolo Bonzini, 2020/06/24
- [PULL 20/31] target/i386: reimplement fprem, fprem1 using floatx80 operations, Paolo Bonzini, 2020/06/24
- [PULL 19/31] softfloat: return low bits of quotient from floatx80_modrem, Paolo Bonzini, 2020/06/24
- [PULL 24/31] target/i386: Add notes for versioned CPU models, Paolo Bonzini, 2020/06/24
- [PULL 17/31] softfloat: do not return pseudo-denormal from floatx80 remainder, Paolo Bonzini, 2020/06/24
- [PULL 23/31] target/i386: reimplement fpatan using floatx80 operations, Paolo Bonzini, 2020/06/24
- [PULL 27/31] kvm: i386: allow TSC to differ by NTP correction bounds without TSC scaling,
Paolo Bonzini <=
- [PULL 21/31] target/i386: reimplement fyl2xp1 using floatx80 operations, Paolo Bonzini, 2020/06/24
- [PULL 25/31] osdep: Make MIN/MAX evaluate arguments only once, Paolo Bonzini, 2020/06/24
- [PULL 22/31] target/i386: reimplement fyl2x using floatx80 operations, Paolo Bonzini, 2020/06/24
- [PULL 30/31] ibex_uart: fix XOR-as-pow, Paolo Bonzini, 2020/06/24
- [PULL 28/31] hyperv: vmbus: Remove the 2nd IRQ, Paolo Bonzini, 2020/06/24
- [PULL 29/31] vmport: move compat properties to hw_compat_5_0, Paolo Bonzini, 2020/06/24
- [PULL 31/31] i386: Mask SVM features if nested SVM is disabled, Paolo Bonzini, 2020/06/24