xen/57a1e603-x86-time-adjust-local-system-time-initialization.patch
Charles Arnold a89d75605e - bsc#970135 - new virtualization project clock test randomly fails
on Xen
  576001df-x86-time-use-local-stamp-in-TSC-calibration-fast-path.patch
  5769106e-x86-generate-assembler-equates-for-synthesized.patch
  57a1e603-x86-time-adjust-local-system-time-initialization.patch
  57a1e64c-x86-time-introduce-and-use-rdtsc_ordered.patch
  57a2f6ac-x86-time-calibrate-TSC-against-platform-timer.patch
- bsc#991934 - xen hypervisor crash in csched_acct
  57973099-have-schedulers-revise-initial-placement.patch
  579730e6-remove-buggy-initial-placement-algorithm.patch
- bsc#988675 - VUL-0: CVE-2016-6258: xen: x86: Privilege escalation
  in PV guests (XSA-182)
  57976073-x86-remove-unsafe-bits-from-mod_lN_entry-fastpath.patch
- bsc#988676 - VUL-0: CVE-2016-6259: xen: x86: Missing SMAP
  whitelisting in 32-bit exception / event delivery (XSA-183)
  57976078-x86-avoid-SMAP-violation-in-compat_create_bounce_frame.patch
- Upstream patches from Jan
  57a30261-x86-support-newer-Intel-CPU-models.patch

- bsc#985503 - vif-route broken
  vif-route.patch

OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=445
2016-08-04 19:26:11 +00:00

124 lines
3.6 KiB
Diff

References: bsc#970135
# Commit bb49fd3092a84ce151f5528794c0e612eeb4961a
# Date 2016-08-03 14:39:31 +0200
# Author Jan Beulich <jbeulich@suse.com>
# Committer Jan Beulich <jbeulich@suse.com>
x86/time: adjust local system time initialization
Using the bare return value from read_platform_stime() is not suitable
when local_time_calibration() is going to use its fast path: Divergence
of several dozen microseconds between NOW() return values on different
CPUs results when platform and local time don't stay in close sync.
Latch local and platform time on the CPU initiating AP bringup, such
that the AP can use these values to seed its stime_local_stamp with as
little of an error as possible. The boot CPU, otoh, can simply
calculate the correct initial value (other CPUs could do so too with
even greater accuracy than the approach being introduced, but that can
work only if all CPUs' TSCs start ticking at the same time, which
generally can't be assumed to be the case on multi-socket systems).
This slightly defers init_percpu_time() (moved ahead by commit
dd2658f966 ["x86/time: initialise time earlier during
start_secondary()"]) in order to reduce as much as possible the gap
between populating the stamps and consuming them.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Dario Faggioli <dario.faggioli@citrix.com>
Tested-by: Joao Martins <joao.m.martins@oracle.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -328,12 +328,12 @@ void start_secondary(void *unused)
percpu_traps_init();
- init_percpu_time();
-
cpu_init();
smp_callin();
+ init_percpu_time();
+
setup_secondary_APIC_clock();
/*
@@ -996,6 +996,8 @@ int __cpu_up(unsigned int cpu)
if ( (ret = do_boot_cpu(apicid, cpu)) != 0 )
return ret;
+ time_latch_stamps();
+
set_cpu_state(CPU_STATE_ONLINE);
while ( !cpu_online(cpu) )
{
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -1328,21 +1328,52 @@ static void time_calibration(void *unuse
&r, 1);
}
+static struct {
+ s_time_t local_stime, master_stime;
+} ap_bringup_ref;
+
+void time_latch_stamps(void)
+{
+ unsigned long flags;
+ u64 tsc;
+
+ local_irq_save(flags);
+ ap_bringup_ref.master_stime = read_platform_stime();
+ tsc = rdtsc();
+ local_irq_restore(flags);
+
+ ap_bringup_ref.local_stime = get_s_time_fixed(tsc);
+}
+
void init_percpu_time(void)
{
struct cpu_time *t = &this_cpu(cpu_time);
unsigned long flags;
+ u64 tsc;
s_time_t now;
/* Initial estimate for TSC rate. */
t->tsc_scale = per_cpu(cpu_time, 0).tsc_scale;
local_irq_save(flags);
- t->local_tsc_stamp = rdtsc();
now = read_platform_stime();
+ tsc = rdtsc();
local_irq_restore(flags);
t->stime_master_stamp = now;
+ /*
+ * To avoid a discontinuity (TSC and platform clock can't be expected
+ * to be in perfect sync), initialization here needs to match up with
+ * local_time_calibration()'s decision whether to use its fast path.
+ */
+ if ( boot_cpu_has(X86_FEATURE_CONSTANT_TSC) )
+ {
+ if ( system_state < SYS_STATE_smp_boot )
+ now = get_s_time_fixed(tsc);
+ else
+ now += ap_bringup_ref.local_stime - ap_bringup_ref.master_stime;
+ }
+ t->local_tsc_stamp = tsc;
t->stime_local_stamp = now;
}
--- a/xen/include/asm-x86/time.h
+++ b/xen/include/asm-x86/time.h
@@ -40,6 +40,7 @@ int time_suspend(void);
int time_resume(void);
void init_percpu_time(void);
+void time_latch_stamps(void);
struct ioreq;
int hwdom_pit_access(struct ioreq *ioreq);