diff -r 8951c3b84e2a xen/arch/x86/time.c
--- a/xen/arch/x86/time.c	Fri Aug 01 09:54:54 2008 +0100
+++ b/xen/arch/x86/time.c	Sun Aug 03 10:34:11 2008 -0600
@@ -876,7 +876,8 @@ void do_settime(unsigned long secs, unsi
     rcu_read_unlock(&domlist_read_lock);
 }
 
-static void local_time_calibration(void *unused)
+static void local_time_calibration(s_time_t curr_master_stime,
+    s_time_t curr_local_stime, u64 curr_tsc)
 {
     struct cpu_time *t = &this_cpu(cpu_time);
 
@@ -884,11 +885,11 @@ static void local_time_calibration(void 
      * System timestamps, extrapolated from local and master oscillators,
      * taken during this calibration and the previous calibration.
      */
-    s_time_t prev_local_stime, curr_local_stime;
-    s_time_t prev_master_stime, curr_master_stime;
+    s_time_t prev_local_stime;
+    s_time_t prev_master_stime;
 
     /* TSC timestamps taken during this calibration and prev calibration. */
-    u64 prev_tsc, curr_tsc;
+    u64 prev_tsc;
 
     /*
      * System time and TSC ticks elapsed during the previous calibration
@@ -909,14 +910,6 @@ static void local_time_calibration(void 
     /* The overall calibration scale multiplier. */
     u32 calibration_mul_frac;
 
-    if ( platform_timer_is_tsc() )
-    {
-        make_tsctimer_record(); 
-        update_vcpu_system_time(current);
-        set_timer(&t->calibration_timer, NOW() + MILLISECS(10*1000));
-        return;
-    }
-
     prev_tsc          = t->local_tsc_stamp;
     prev_local_stime  = t->stime_local_stamp;
     prev_master_stime = t->stime_master_stamp;
@@ -925,12 +918,6 @@ static void local_time_calibration(void 
      * Disable IRQs to get 'instantaneous' current timestamps. We read platform
      * time first, as we may be delayed when acquiring platform_timer_lock.
      */
-    local_irq_disable();
-    curr_master_stime = read_platform_stime();
-    curr_local_stime  = get_s_time();
-    rdtscll(curr_tsc);
-    local_irq_enable();
-
 #if 0
     printk("PRE%d: tsc=%"PRIu64" stime=%"PRIu64" master=%"PRIu64"\n",
            smp_processor_id(), prev_tsc, prev_local_stime, prev_master_stime);
@@ -952,7 +939,7 @@ static void local_time_calibration(void 
      * We could be smarter here: resync platform timer with local timer?
      */
     if ( ((s64)stime_elapsed64 < (EPOCH / 2)) )
-        goto out;
+        return;
 
     /*
      * Calculate error-correction factor. This only slows down a fast local
@@ -1020,12 +1007,71 @@ static void local_time_calibration(void 
     local_irq_enable();
 
     update_vcpu_system_time(current);
+}
 
- out:
+static cpumask_t local_time_calibrate_cpumask = CPU_MASK_NONE;
+s_time_t curr_master_stime;
+
+static void slave_local_time_calibration(void *unused)
+{
+    unsigned int cpu = smp_processor_id();
+    u64 curr_tsc;
+    s_time_t curr_local_stime;
+
+    if ( platform_timer_is_tsc() )
+    {
+        make_tsctimer_record(); 
+        update_vcpu_system_time(current);
+        return;
+    }
+
+    local_irq_disable();
+    while ( !cpu_isset(cpu, local_time_calibrate_cpumask) )
+        cpu_relax();
+    curr_local_stime  = get_s_time();
+    rdtscll(curr_tsc);
+    cpu_clear(cpu, local_time_calibrate_cpumask);
+    local_irq_enable();
+
+    local_time_calibration(curr_master_stime, curr_local_stime, curr_tsc);
+}
+
+static void master_local_time_calibration(void *unused)
+{
+    unsigned int cpu = smp_processor_id();
+    static DEFINE_SPINLOCK(lock);
+    u64 curr_tsc;
+    s_time_t curr_local_stime;
+    struct cpu_time *t = &this_cpu(cpu_time);
+
+    if ( platform_timer_is_tsc() )
+    {
+        smp_call_function(slave_local_time_calibration, NULL, 0, 0);
+        make_tsctimer_record(); 
+        update_vcpu_system_time(current);
+        set_timer(&t->calibration_timer, NOW() + MILLISECS(10*1000));
+        return;
+    }
+
+    spin_lock(&lock);
+
+    smp_call_function(slave_local_time_calibration, NULL, 0, 0);
+
+    local_irq_disable();
+    curr_master_stime = read_platform_stime();
+    local_time_calibrate_cpumask = cpu_online_map;
+    curr_local_stime  = get_s_time();
+    rdtscll(curr_tsc);
+    cpu_clear(cpu, local_time_calibrate_cpumask);
+    local_irq_enable();
+
+    local_time_calibration(curr_master_stime, curr_local_stime, curr_tsc);
+
+    spin_unlock(&lock);
+
     set_timer(&t->calibration_timer, NEXT_EPOCH(curr_local_stime));
 
-    if ( smp_processor_id() == 0 )
-        platform_time_calibration();
+    platform_time_calibration();
 }
 
 void init_percpu_time(void)
@@ -1049,9 +1095,12 @@ void init_percpu_time(void)
     t->stime_local_stamp  = now;
 
  out:
-    init_timer(&t->calibration_timer, local_time_calibration,
+    if ( smp_processor_id() == 0 )
+    {
+        init_timer(&t->calibration_timer, master_local_time_calibration,
                NULL, smp_processor_id());
-    set_timer(&t->calibration_timer, NEXT_EPOCH(NOW()));
+        set_timer(&t->calibration_timer, NEXT_EPOCH(NOW()));
+    }
 }
 
 /* Late init function (after all CPUs are booted). */
