diff options
Diffstat (limited to 'arch/x86/xen/time.c')
-rw-r--r-- | arch/x86/xen/time.c | 57 |
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 */ |
159 | unsigned long xen_tsc_khz(void) | 160 | static 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 | ||
194 | unsigned long xen_get_wallclock(void) | 195 | static 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 | ||
202 | int xen_set_wallclock(unsigned long now) | 203 | static 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) | 438 | static const struct pv_time_ops xen_time_ops __initdata = { |
439 | .sched_clock = xen_clocksource_read, | ||
440 | }; | ||
441 | |||
442 | static __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 | ||
481 | static 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 | ||