#include <linux/device.h>
 #include <linux/sysdev.h>
 #include <linux/bcd.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
 #include <linux/kallsyms.h>
 #include <linux/acpi.h>
 #ifdef CONFIG_ACPI
 extern void i8254_timer_resume(void);
 extern int using_apic_timer;
 
-static char *time_init_gtod(void);
+static char *timename = NULL;
 
 DEFINE_SPINLOCK(rtc_lock);
 EXPORT_SYMBOL(rtc_lock);
        timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL
 };
 
-void __init time_init(void)
+static int __cpuinit
+time_cpu_notifier(struct notifier_block *nb, unsigned long action, void *hcpu)
 {
-       char *timename;
-       char *gtod;
+       unsigned cpu = (unsigned long) hcpu;
+       if (action == CPU_ONLINE &&
+               cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP)) {
+               unsigned p;
+               p = smp_processor_id() | (cpu_to_node(smp_processor_id())<<12);
+               write_rdtscp_aux(p);
+       }
+       return NOTIFY_DONE;
+}
 
+void __init time_init(void)
+{
        if (nohpet)
                vxtime.hpet_address = 0;
 
        }
 
        vxtime.mode = VXTIME_TSC;
-       gtod = time_init_gtod();
-
-       printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n",
-              vxtime_hz / 1000000, vxtime_hz % 1000000, timename, gtod);
-       printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
-               cpu_khz / 1000, cpu_khz % 1000);
        vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz;
        vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz;
        vxtime.last_tsc = get_cycles_sync();
        setup_irq(0, &irq0);
 
        set_cyc2ns_scale(cpu_khz);
+
+       hotcpu_notifier(time_cpu_notifier, 0);
+       time_cpu_notifier(NULL, CPU_ONLINE, (void *)(long)smp_processor_id());
+
+#ifndef CONFIG_SMP
+       time_init_gtod();
+#endif
 }
 
 /*
 /*
  * Decide what mode gettimeofday should use.
  */
-__init static char *time_init_gtod(void)
+void time_init_gtod(void)
 {
        char *timetype;
 
        if (unsynchronized_tsc())
                notsc = 1;
+
        if (vxtime.hpet_address && notsc) {
                timetype = hpet_use_timer ? "HPET" : "PIT/HPET";
                if (hpet_use_timer)
                timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC";
                vxtime.mode = VXTIME_TSC;
        }
-       return timetype;
+
+       printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n",
+              vxtime_hz / 1000000, vxtime_hz % 1000000, timename, timetype);
+       printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
+               cpu_khz / 1000, cpu_khz % 1000);
+       vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz;
+       vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz;
+       vxtime.last_tsc = get_cycles_sync();
+
+       set_cyc2ns_scale(cpu_khz);
 }
 
 __setup("report_lost_ticks", time_setup);