aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/xen/time.c')
-rw-r--r--arch/x86/xen/time.c57
1 files changed, 53 insertions, 4 deletions
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index a86df42e46ad..1a5353a753fc 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -20,6 +20,7 @@
20#include <asm/xen/hypercall.h> 20#include <asm/xen/hypercall.h>
21 21
22#include <xen/events.h> 22#include <xen/events.h>
23#include <xen/features.h>
23#include <xen/interface/xen.h> 24#include <xen/interface/xen.h>
24#include <xen/interface/vcpu.h> 25#include <xen/interface/vcpu.h>
25 26
@@ -156,7 +157,7 @@ static void do_stolen_accounting(void)
156} 157}
157 158
158/* Get the TSC speed from Xen */ 159/* Get the TSC speed from Xen */
159unsigned long xen_tsc_khz(void) 160static unsigned long xen_tsc_khz(void)
160{ 161{
161 struct pvclock_vcpu_time_info *info = 162 struct pvclock_vcpu_time_info *info =
162 &HYPERVISOR_shared_info->vcpu_info[0].time; 163 &HYPERVISOR_shared_info->vcpu_info[0].time;
@@ -191,7 +192,7 @@ static void xen_read_wallclock(struct timespec *ts)
191 put_cpu_var(xen_vcpu); 192 put_cpu_var(xen_vcpu);
192} 193}
193 194
194unsigned long xen_get_wallclock(void) 195static unsigned long xen_get_wallclock(void)
195{ 196{
196 struct timespec ts; 197 struct timespec ts;
197 198
@@ -199,7 +200,7 @@ unsigned long xen_get_wallclock(void)
199 return ts.tv_sec; 200 return ts.tv_sec;
200} 201}
201 202
202int xen_set_wallclock(unsigned long now) 203static int xen_set_wallclock(unsigned long now)
203{ 204{
204 /* do nothing for domU */ 205 /* do nothing for domU */
205 return -1; 206 return -1;
@@ -434,7 +435,11 @@ void xen_timer_resume(void)
434 } 435 }
435} 436}
436 437
437__init void xen_time_init(void) 438static const struct pv_time_ops xen_time_ops __initdata = {
439 .sched_clock = xen_clocksource_read,
440};
441
442static __init void xen_time_init(void)
438{ 443{
439 int cpu = smp_processor_id(); 444 int cpu = smp_processor_id();
440 struct timespec tp; 445 struct timespec tp;
@@ -458,3 +463,47 @@ __init void xen_time_init(void)
458 xen_setup_timer(cpu); 463 xen_setup_timer(cpu);
459 xen_setup_cpu_clockevents(); 464 xen_setup_cpu_clockevents();
460} 465}
466
467__init void xen_init_time_ops(void)
468{
469 pv_time_ops = xen_time_ops;
470
471 x86_init.timers.timer_init = xen_time_init;
472 x86_init.timers.setup_percpu_clockev = x86_init_noop;
473 x86_cpuinit.setup_percpu_clockev = x86_init_noop;
474
475 x86_platform.calibrate_tsc = xen_tsc_khz;
476 x86_platform.get_wallclock = xen_get_wallclock;
477 x86_platform.set_wallclock = xen_set_wallclock;
478}
479
480#ifdef CONFIG_XEN_PVHVM
481static void xen_hvm_setup_cpu_clockevents(void)
482{
483 int cpu = smp_processor_id();
484 xen_setup_runstate_info(cpu);
485 xen_setup_timer(cpu);
486 xen_setup_cpu_clockevents();
487}
488
489__init void xen_hvm_init_time_ops(void)
490{
491 /* vector callback is needed otherwise we cannot receive interrupts
492 * on cpu > 0 */
493 if (!xen_have_vector_callback && num_present_cpus() > 1)
494 return;
495 if (!xen_feature(XENFEAT_hvm_safe_pvclock)) {
496 printk(KERN_INFO "Xen doesn't support pvclock on HVM,"
497 "disable pv timer\n");
498 return;
499 }
500
501 pv_time_ops = xen_time_ops;
502 x86_init.timers.setup_percpu_clockev = xen_time_init;
503 x86_cpuinit.setup_percpu_clockev = xen_hvm_setup_cpu_clockevents;
504
505 x86_platform.calibrate_tsc = xen_tsc_khz;
506 x86_platform.get_wallclock = xen_get_wallclock;
507 x86_platform.set_wallclock = xen_set_wallclock;
508}
509#endif