summaryrefslogtreecommitdiff
path: root/xen.bug1026236.suse_vtsc_tolerance.patch
diff options
context:
space:
mode:
Diffstat (limited to 'xen.bug1026236.suse_vtsc_tolerance.patch')
-rw-r--r--xen.bug1026236.suse_vtsc_tolerance.patch58
1 files changed, 58 insertions, 0 deletions
diff --git a/xen.bug1026236.suse_vtsc_tolerance.patch b/xen.bug1026236.suse_vtsc_tolerance.patch
new file mode 100644
index 0000000..17c8b68
--- /dev/null
+++ b/xen.bug1026236.suse_vtsc_tolerance.patch
@@ -0,0 +1,58 @@
+suse_vtsc_tolerance=<val>
+Reference: bsc#1026236
+
+To avoid emulation of vTSC after live migration or save/restore allow
+different clock frequency up to the specified value. If the frequency
+is within the allowed range TSC access by the domU will be performed
+at native speed. Otherwise TSC access will be emulated. It is up to
+the hostadmin to decide how much tolerance all running domUs can
+actually handle. The default is zero tolerance.
+
+--- a/xen/arch/x86/time.c
++++ b/xen/arch/x86/time.c
+@@ -43,6 +43,9 @@
+ static char __initdata opt_clocksource[10];
+ string_param("clocksource", opt_clocksource);
+
++static unsigned int __read_mostly opt_suse_vtsc_tolerance;
++integer_param("suse_vtsc_tolerance", opt_suse_vtsc_tolerance);
++
+ unsigned long __read_mostly cpu_khz; /* CPU clock frequency in kHz. */
+ DEFINE_SPINLOCK(rtc_lock);
+ unsigned long pit0_ticks;
+@@ -2226,6 +2229,7 @@ int tsc_set_info(struct domain *d,
+
+ switch ( tsc_mode )
+ {
++ bool disable_vtsc;
+ case TSC_MODE_DEFAULT:
+ case TSC_MODE_ALWAYS_EMULATE:
+ d->arch.vtsc_offset = get_s_time() - elapsed_nsec;
+@@ -2239,8 +2243,26 @@ int tsc_set_info(struct domain *d,
+ * When a guest is created, gtsc_khz is passed in as zero, making
+ * d->arch.tsc_khz == cpu_khz. Thus no need to check incarnation.
+ */
++ disable_vtsc = d->arch.tsc_khz == cpu_khz;
++
++ if ( tsc_mode == TSC_MODE_DEFAULT && gtsc_khz &&
++ is_hvm_domain(d) && opt_suse_vtsc_tolerance )
++ {
++ long khz_diff;
++
++ khz_diff = ABS(((long)cpu_khz - gtsc_khz));
++ disable_vtsc = khz_diff <= opt_suse_vtsc_tolerance;
++
++ printk(XENLOG_G_INFO "d%d: host has %lu kHz,"
++ " domU expects %u kHz,"
++ " difference of %ld is %s tolerance of %u\n",
++ d->domain_id, cpu_khz, gtsc_khz, khz_diff,
++ disable_vtsc ? "within" : "outside",
++ opt_suse_vtsc_tolerance);
++ }
++
+ if ( tsc_mode == TSC_MODE_DEFAULT && host_tsc_is_safe() &&
+- (d->arch.tsc_khz == cpu_khz ||
++ (disable_vtsc ||
+ (is_hvm_domain(d) &&
+ hvm_get_tsc_scaling_ratio(d->arch.tsc_khz))) )
+ {