diff options
| -rw-r--r-- | arch/x86/xen/enlighten.c | 14 | ||||
| -rw-r--r-- | arch/x86/xen/suspend.c | 6 | ||||
| -rw-r--r-- | arch/x86/xen/time.c | 58 | ||||
| -rw-r--r-- | arch/x86/xen/xen-ops.h | 7 | ||||
| -rw-r--r-- | include/xen/interface/features.h | 3 |
5 files changed, 66 insertions, 22 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 127c95c8d15e..a90172963884 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
| @@ -935,10 +935,6 @@ static const struct pv_init_ops xen_init_ops __initdata = { | |||
| 935 | .patch = xen_patch, | 935 | .patch = xen_patch, |
| 936 | }; | 936 | }; |
| 937 | 937 | ||
| 938 | static const struct pv_time_ops xen_time_ops __initdata = { | ||
| 939 | .sched_clock = xen_sched_clock, | ||
| 940 | }; | ||
| 941 | |||
| 942 | static const struct pv_cpu_ops xen_cpu_ops __initdata = { | 938 | static const struct pv_cpu_ops xen_cpu_ops __initdata = { |
| 943 | .cpuid = xen_cpuid, | 939 | .cpuid = xen_cpuid, |
| 944 | 940 | ||
| @@ -1076,7 +1072,6 @@ asmlinkage void __init xen_start_kernel(void) | |||
| 1076 | /* Install Xen paravirt ops */ | 1072 | /* Install Xen paravirt ops */ |
| 1077 | pv_info = xen_info; | 1073 | pv_info = xen_info; |
| 1078 | pv_init_ops = xen_init_ops; | 1074 | pv_init_ops = xen_init_ops; |
| 1079 | pv_time_ops = xen_time_ops; | ||
| 1080 | pv_cpu_ops = xen_cpu_ops; | 1075 | pv_cpu_ops = xen_cpu_ops; |
| 1081 | pv_apic_ops = xen_apic_ops; | 1076 | pv_apic_ops = xen_apic_ops; |
| 1082 | 1077 | ||
| @@ -1084,13 +1079,7 @@ asmlinkage void __init xen_start_kernel(void) | |||
| 1084 | x86_init.oem.arch_setup = xen_arch_setup; | 1079 | x86_init.oem.arch_setup = xen_arch_setup; |
| 1085 | x86_init.oem.banner = xen_banner; | 1080 | x86_init.oem.banner = xen_banner; |
| 1086 | 1081 | ||
| 1087 | x86_init.timers.timer_init = xen_time_init; | 1082 | xen_init_time_ops(); |
| 1088 | x86_init.timers.setup_percpu_clockev = x86_init_noop; | ||
| 1089 | x86_cpuinit.setup_percpu_clockev = x86_init_noop; | ||
| 1090 | |||
| 1091 | x86_platform.calibrate_tsc = xen_tsc_khz; | ||
| 1092 | x86_platform.get_wallclock = xen_get_wallclock; | ||
| 1093 | x86_platform.set_wallclock = xen_set_wallclock; | ||
| 1094 | 1083 | ||
| 1095 | /* | 1084 | /* |
| 1096 | * Set up some pagetable state before starting to set any ptes. | 1085 | * Set up some pagetable state before starting to set any ptes. |
| @@ -1327,6 +1316,7 @@ static void __init xen_hvm_guest_init(void) | |||
| 1327 | register_cpu_notifier(&xen_hvm_cpu_notifier); | 1316 | register_cpu_notifier(&xen_hvm_cpu_notifier); |
| 1328 | have_vcpu_info_placement = 0; | 1317 | have_vcpu_info_placement = 0; |
| 1329 | x86_init.irqs.intr_init = xen_init_IRQ; | 1318 | x86_init.irqs.intr_init = xen_init_IRQ; |
| 1319 | xen_hvm_init_time_ops(); | ||
| 1330 | } | 1320 | } |
| 1331 | 1321 | ||
| 1332 | static bool __init xen_hvm_platform(void) | 1322 | static bool __init xen_hvm_platform(void) |
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c index d07479c340f5..1d789d56877c 100644 --- a/arch/x86/xen/suspend.c +++ b/arch/x86/xen/suspend.c | |||
| @@ -28,8 +28,14 @@ void xen_pre_suspend(void) | |||
| 28 | 28 | ||
| 29 | void xen_hvm_post_suspend(int suspend_cancelled) | 29 | void xen_hvm_post_suspend(int suspend_cancelled) |
| 30 | { | 30 | { |
| 31 | int cpu; | ||
| 31 | xen_hvm_init_shared_info(); | 32 | xen_hvm_init_shared_info(); |
| 32 | xen_callback_vector(); | 33 | xen_callback_vector(); |
| 34 | if (xen_feature(XENFEAT_hvm_safe_pvclock)) { | ||
| 35 | for_each_online_cpu(cpu) { | ||
| 36 | xen_setup_runstate_info(cpu); | ||
| 37 | } | ||
| 38 | } | ||
| 33 | } | 39 | } |
| 34 | 40 | ||
| 35 | void xen_post_suspend(int suspend_cancelled) | 41 | void xen_post_suspend(int suspend_cancelled) |
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index b3c6c59ed302..4780e55886a5 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 | ||
| @@ -160,7 +161,7 @@ static void do_stolen_accounting(void) | |||
| 160 | * nanoseconds, which is nanoseconds the VCPU spent in RUNNING+BLOCKED | 161 | * nanoseconds, which is nanoseconds the VCPU spent in RUNNING+BLOCKED |
| 161 | * states. | 162 | * states. |
| 162 | */ | 163 | */ |
| 163 | unsigned long long xen_sched_clock(void) | 164 | static unsigned long long xen_sched_clock(void) |
| 164 | { | 165 | { |
| 165 | struct vcpu_runstate_info state; | 166 | struct vcpu_runstate_info state; |
| 166 | cycle_t now; | 167 | cycle_t now; |
| @@ -195,7 +196,7 @@ unsigned long long xen_sched_clock(void) | |||
| 195 | 196 | ||
| 196 | 197 | ||
| 197 | /* Get the TSC speed from Xen */ | 198 | /* Get the TSC speed from Xen */ |
| 198 | unsigned long xen_tsc_khz(void) | 199 | static unsigned long xen_tsc_khz(void) |
| 199 | { | 200 | { |
| 200 | struct pvclock_vcpu_time_info *info = | 201 | struct pvclock_vcpu_time_info *info = |
| 201 | &HYPERVISOR_shared_info->vcpu_info[0].time; | 202 | &HYPERVISOR_shared_info->vcpu_info[0].time; |
| @@ -230,7 +231,7 @@ static void xen_read_wallclock(struct timespec *ts) | |||
| 230 | put_cpu_var(xen_vcpu); | 231 | put_cpu_var(xen_vcpu); |
| 231 | } | 232 | } |
| 232 | 233 | ||
| 233 | unsigned long xen_get_wallclock(void) | 234 | static unsigned long xen_get_wallclock(void) |
| 234 | { | 235 | { |
| 235 | struct timespec ts; | 236 | struct timespec ts; |
| 236 | 237 | ||
| @@ -238,7 +239,7 @@ unsigned long xen_get_wallclock(void) | |||
| 238 | return ts.tv_sec; | 239 | return ts.tv_sec; |
| 239 | } | 240 | } |
| 240 | 241 | ||
| 241 | int xen_set_wallclock(unsigned long now) | 242 | static int xen_set_wallclock(unsigned long now) |
| 242 | { | 243 | { |
| 243 | /* do nothing for domU */ | 244 | /* do nothing for domU */ |
| 244 | return -1; | 245 | return -1; |
| @@ -473,7 +474,11 @@ void xen_timer_resume(void) | |||
| 473 | } | 474 | } |
| 474 | } | 475 | } |
| 475 | 476 | ||
| 476 | __init void xen_time_init(void) | 477 | static const struct pv_time_ops xen_time_ops __initdata = { |
| 478 | .sched_clock = xen_sched_clock, | ||
| 479 | }; | ||
| 480 | |||
| 481 | static __init void xen_time_init(void) | ||
| 477 | { | 482 | { |
| 478 | int cpu = smp_processor_id(); | 483 | int cpu = smp_processor_id(); |
| 479 | struct timespec tp; | 484 | struct timespec tp; |
| @@ -497,3 +502,46 @@ __init void xen_time_init(void) | |||
| 497 | xen_setup_timer(cpu); | 502 | xen_setup_timer(cpu); |
| 498 | xen_setup_cpu_clockevents(); | 503 | xen_setup_cpu_clockevents(); |
| 499 | } | 504 | } |
| 505 | |||
| 506 | __init void xen_init_time_ops(void) | ||
| 507 | { | ||
| 508 | pv_time_ops = xen_time_ops; | ||
| 509 | |||
| 510 | x86_init.timers.timer_init = xen_time_init; | ||
| 511 | x86_init.timers.setup_percpu_clockev = x86_init_noop; | ||
| 512 | x86_cpuinit.setup_percpu_clockev = x86_init_noop; | ||
| 513 | |||
| 514 | x86_platform.calibrate_tsc = xen_tsc_khz; | ||
| 515 | x86_platform.get_wallclock = xen_get_wallclock; | ||
| 516 | x86_platform.set_wallclock = xen_set_wallclock; | ||
| 517 | } | ||
| 518 | |||
| 519 | static void xen_hvm_setup_cpu_clockevents(void) | ||
| 520 | { | ||
| 521 | int cpu = smp_processor_id(); | ||
| 522 | xen_setup_runstate_info(cpu); | ||
| 523 | xen_setup_timer(cpu); | ||
| 524 | xen_setup_cpu_clockevents(); | ||
| 525 | } | ||
| 526 | |||
| 527 | __init void xen_hvm_init_time_ops(void) | ||
| 528 | { | ||
| 529 | /* vector callback is needed otherwise we cannot receive interrupts | ||
| 530 | * on cpu > 0 */ | ||
| 531 | if (!xen_have_vector_callback && num_present_cpus() > 1) | ||
| 532 | return; | ||
| 533 | if (!xen_feature(XENFEAT_hvm_safe_pvclock)) { | ||
| 534 | printk(KERN_INFO "Xen doesn't support pvclock on HVM," | ||
| 535 | "disable pv timer\n"); | ||
| 536 | return; | ||
| 537 | } | ||
| 538 | |||
| 539 | pv_time_ops = xen_time_ops; | ||
| 540 | x86_init.timers.setup_percpu_clockev = xen_time_init; | ||
| 541 | x86_cpuinit.setup_percpu_clockev = xen_hvm_setup_cpu_clockevents; | ||
| 542 | |||
| 543 | x86_platform.calibrate_tsc = xen_tsc_khz; | ||
| 544 | x86_platform.get_wallclock = xen_get_wallclock; | ||
| 545 | x86_platform.set_wallclock = xen_set_wallclock; | ||
| 546 | } | ||
| 547 | |||
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 01c9dd386522..089d18923d2b 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h | |||
| @@ -49,11 +49,8 @@ void xen_setup_runstate_info(int cpu); | |||
| 49 | void xen_teardown_timer(int cpu); | 49 | void xen_teardown_timer(int cpu); |
| 50 | cycle_t xen_clocksource_read(void); | 50 | cycle_t xen_clocksource_read(void); |
| 51 | void xen_setup_cpu_clockevents(void); | 51 | void xen_setup_cpu_clockevents(void); |
| 52 | unsigned long xen_tsc_khz(void); | 52 | void __init xen_init_time_ops(void); |
| 53 | void __init xen_time_init(void); | 53 | void __init xen_hvm_init_time_ops(void); |
| 54 | unsigned long xen_get_wallclock(void); | ||
| 55 | int xen_set_wallclock(unsigned long time); | ||
| 56 | unsigned long long xen_sched_clock(void); | ||
| 57 | 54 | ||
| 58 | irqreturn_t xen_debug_interrupt(int irq, void *dev_id); | 55 | irqreturn_t xen_debug_interrupt(int irq, void *dev_id); |
| 59 | 56 | ||
diff --git a/include/xen/interface/features.h b/include/xen/interface/features.h index 8ab08b91bf6f..70d2563ab166 100644 --- a/include/xen/interface/features.h +++ b/include/xen/interface/features.h | |||
| @@ -44,6 +44,9 @@ | |||
| 44 | /* x86: Does this Xen host support the HVM callback vector type? */ | 44 | /* x86: Does this Xen host support the HVM callback vector type? */ |
| 45 | #define XENFEAT_hvm_callback_vector 8 | 45 | #define XENFEAT_hvm_callback_vector 8 |
| 46 | 46 | ||
| 47 | /* x86: pvclock algorithm is safe to use on HVM */ | ||
| 48 | #define XENFEAT_hvm_safe_pvclock 9 | ||
| 49 | |||
| 47 | #define XENFEAT_NR_SUBMAPS 1 | 50 | #define XENFEAT_NR_SUBMAPS 1 |
| 48 | 51 | ||
| 49 | #endif /* __XEN_PUBLIC_FEATURES_H__ */ | 52 | #endif /* __XEN_PUBLIC_FEATURES_H__ */ |
