diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2009-08-20 11:06:25 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2009-08-31 03:35:47 -0400 |
| commit | 2d826404f0bdcac2a4dd7e3c446b70d6a3b63b78 (patch) | |
| tree | 7db2dc0fbde3a25a89f1fc1514152567f612ccde | |
| parent | 47926214d8b2bef13b2be57c500194a804f16198 (diff) | |
x86: Move tsc_calibration to x86_init_ops
TSC calibration is modified by the vmware hypervisor and paravirt by
separate means. Moorestown wants to add its own calibration routine as
well. So make calibrate_tsc a proper x86_init_ops function and
override it by paravirt or by the early setup of the vmware
hypervisor.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
| -rw-r--r-- | arch/x86/include/asm/hypervisor.h | 2 | ||||
| -rw-r--r-- | arch/x86/include/asm/paravirt.h | 1 | ||||
| -rw-r--r-- | arch/x86/include/asm/timer.h | 5 | ||||
| -rw-r--r-- | arch/x86/include/asm/tsc.h | 3 | ||||
| -rw-r--r-- | arch/x86/include/asm/vmware.h | 2 | ||||
| -rw-r--r-- | arch/x86/include/asm/x86_init.h | 9 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/hypervisor.c | 14 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/vmware.c | 21 | ||||
| -rw-r--r-- | arch/x86/kernel/kvmclock.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/paravirt.c | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/setup.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/tsc.c | 13 | ||||
| -rw-r--r-- | arch/x86/kernel/vmi_32.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/vmiclock_32.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/x86_init.c | 5 | ||||
| -rw-r--r-- | arch/x86/lguest/boot.c | 2 | ||||
| -rw-r--r-- | arch/x86/xen/enlighten.c | 3 |
17 files changed, 48 insertions, 41 deletions
diff --git a/arch/x86/include/asm/hypervisor.h b/arch/x86/include/asm/hypervisor.h index 369f5c5d09a1..b78c0941e422 100644 --- a/arch/x86/include/asm/hypervisor.h +++ b/arch/x86/include/asm/hypervisor.h | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | #ifndef ASM_X86__HYPERVISOR_H | 20 | #ifndef ASM_X86__HYPERVISOR_H |
| 21 | #define ASM_X86__HYPERVISOR_H | 21 | #define ASM_X86__HYPERVISOR_H |
| 22 | 22 | ||
| 23 | extern unsigned long get_hypervisor_tsc_freq(void); | ||
| 24 | extern void init_hypervisor(struct cpuinfo_x86 *c); | 23 | extern void init_hypervisor(struct cpuinfo_x86 *c); |
| 24 | extern void init_hypervisor_platform(void); | ||
| 25 | 25 | ||
| 26 | #endif | 26 | #endif |
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 11a4ba7b209c..1e458a553303 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
| @@ -210,7 +210,6 @@ static inline unsigned long long paravirt_sched_clock(void) | |||
| 210 | { | 210 | { |
| 211 | return PVOP_CALL0(unsigned long long, pv_time_ops.sched_clock); | 211 | return PVOP_CALL0(unsigned long long, pv_time_ops.sched_clock); |
| 212 | } | 212 | } |
| 213 | #define calibrate_tsc() (pv_time_ops.get_tsc_khz()) | ||
| 214 | 213 | ||
| 215 | static inline unsigned long long paravirt_read_pmc(int counter) | 214 | static inline unsigned long long paravirt_read_pmc(int counter) |
| 216 | { | 215 | { |
diff --git a/arch/x86/include/asm/timer.h b/arch/x86/include/asm/timer.h index 65228ccc5f0d..5469630b27f5 100644 --- a/arch/x86/include/asm/timer.h +++ b/arch/x86/include/asm/timer.h | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | #define TICK_SIZE (tick_nsec / 1000) | 8 | #define TICK_SIZE (tick_nsec / 1000) |
| 9 | 9 | ||
| 10 | unsigned long long native_sched_clock(void); | 10 | unsigned long long native_sched_clock(void); |
| 11 | unsigned long native_calibrate_tsc(void); | ||
| 12 | extern int recalibrate_cpu_khz(void); | 11 | extern int recalibrate_cpu_khz(void); |
| 13 | 12 | ||
| 14 | #if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC) | 13 | #if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC) |
| @@ -19,10 +18,6 @@ extern int timer_ack; | |||
| 19 | 18 | ||
| 20 | extern int no_timer_check; | 19 | extern int no_timer_check; |
| 21 | 20 | ||
| 22 | #ifndef CONFIG_PARAVIRT | ||
| 23 | #define calibrate_tsc() native_calibrate_tsc() | ||
| 24 | #endif | ||
| 25 | |||
| 26 | /* Accelerators for sched_clock() | 21 | /* Accelerators for sched_clock() |
| 27 | * convert from cycles(64bits) => nanoseconds (64bits) | 22 | * convert from cycles(64bits) => nanoseconds (64bits) |
| 28 | * basic equation: | 23 | * basic equation: |
diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h index 38ae163cc91b..c0427295e8f5 100644 --- a/arch/x86/include/asm/tsc.h +++ b/arch/x86/include/asm/tsc.h | |||
| @@ -48,7 +48,8 @@ static __always_inline cycles_t vget_cycles(void) | |||
| 48 | extern void tsc_init(void); | 48 | extern void tsc_init(void); |
| 49 | extern void mark_tsc_unstable(char *reason); | 49 | extern void mark_tsc_unstable(char *reason); |
| 50 | extern int unsynchronized_tsc(void); | 50 | extern int unsynchronized_tsc(void); |
| 51 | int check_tsc_unstable(void); | 51 | extern int check_tsc_unstable(void); |
| 52 | extern unsigned long native_calibrate_tsc(void); | ||
| 52 | 53 | ||
| 53 | /* | 54 | /* |
| 54 | * Boot-time check whether the TSCs are synchronized across | 55 | * Boot-time check whether the TSCs are synchronized across |
diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h index c11b7e100d83..e49ed6d2fd4e 100644 --- a/arch/x86/include/asm/vmware.h +++ b/arch/x86/include/asm/vmware.h | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | #ifndef ASM_X86__VMWARE_H | 20 | #ifndef ASM_X86__VMWARE_H |
| 21 | #define ASM_X86__VMWARE_H | 21 | #define ASM_X86__VMWARE_H |
| 22 | 22 | ||
| 23 | extern unsigned long vmware_get_tsc_khz(void); | 23 | extern void vmware_platform_setup(void); |
| 24 | extern int vmware_platform(void); | 24 | extern int vmware_platform(void); |
| 25 | extern void vmware_set_feature_bits(struct cpuinfo_x86 *c); | 25 | extern void vmware_set_feature_bits(struct cpuinfo_x86 *c); |
| 26 | 26 | ||
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index f8bdd2271a04..20df51871713 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h | |||
| @@ -112,8 +112,17 @@ struct x86_cpuinit_ops { | |||
| 112 | void (*setup_percpu_clockev)(void); | 112 | void (*setup_percpu_clockev)(void); |
| 113 | }; | 113 | }; |
| 114 | 114 | ||
| 115 | /** | ||
| 116 | * struct x86_platform_ops - platform specific runtime functions | ||
| 117 | * @calibrate_tsc: calibrate TSC | ||
| 118 | */ | ||
| 119 | struct x86_platform_ops { | ||
| 120 | unsigned long (*calibrate_tsc)(void); | ||
| 121 | }; | ||
| 122 | |||
| 115 | extern struct x86_init_ops x86_init; | 123 | extern struct x86_init_ops x86_init; |
| 116 | extern struct x86_cpuinit_ops x86_cpuinit; | 124 | extern struct x86_cpuinit_ops x86_cpuinit; |
| 125 | extern struct x86_platform_ops x86_platform; | ||
| 117 | 126 | ||
| 118 | extern void x86_init_noop(void); | 127 | extern void x86_init_noop(void); |
| 119 | extern void x86_init_uint_noop(unsigned int unused); | 128 | extern void x86_init_uint_noop(unsigned int unused); |
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c index 93ba8eeb100a..08be922de33a 100644 --- a/arch/x86/kernel/cpu/hypervisor.c +++ b/arch/x86/kernel/cpu/hypervisor.c | |||
| @@ -34,13 +34,6 @@ detect_hypervisor_vendor(struct cpuinfo_x86 *c) | |||
| 34 | c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE; | 34 | c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE; |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | unsigned long get_hypervisor_tsc_freq(void) | ||
| 38 | { | ||
| 39 | if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE) | ||
| 40 | return vmware_get_tsc_khz(); | ||
| 41 | return 0; | ||
| 42 | } | ||
| 43 | |||
| 44 | static inline void __cpuinit | 37 | static inline void __cpuinit |
| 45 | hypervisor_set_feature_bits(struct cpuinfo_x86 *c) | 38 | hypervisor_set_feature_bits(struct cpuinfo_x86 *c) |
| 46 | { | 39 | { |
| @@ -55,3 +48,10 @@ void __cpuinit init_hypervisor(struct cpuinfo_x86 *c) | |||
| 55 | detect_hypervisor_vendor(c); | 48 | detect_hypervisor_vendor(c); |
| 56 | hypervisor_set_feature_bits(c); | 49 | hypervisor_set_feature_bits(c); |
| 57 | } | 50 | } |
| 51 | |||
| 52 | void __init init_hypervisor_platform(void) | ||
| 53 | { | ||
| 54 | init_hypervisor(&boot_cpu_data); | ||
| 55 | if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE) | ||
| 56 | vmware_platform_setup(); | ||
| 57 | } | ||
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index bc24f514ec93..0a46b4df5d80 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/dmi.h> | 24 | #include <linux/dmi.h> |
| 25 | #include <asm/div64.h> | 25 | #include <asm/div64.h> |
| 26 | #include <asm/vmware.h> | 26 | #include <asm/vmware.h> |
| 27 | #include <asm/x86_init.h> | ||
| 27 | 28 | ||
| 28 | #define CPUID_VMWARE_INFO_LEAF 0x40000000 | 29 | #define CPUID_VMWARE_INFO_LEAF 0x40000000 |
| 29 | #define VMWARE_HYPERVISOR_MAGIC 0x564D5868 | 30 | #define VMWARE_HYPERVISOR_MAGIC 0x564D5868 |
| @@ -47,21 +48,29 @@ static inline int __vmware_platform(void) | |||
| 47 | return eax != (uint32_t)-1 && ebx == VMWARE_HYPERVISOR_MAGIC; | 48 | return eax != (uint32_t)-1 && ebx == VMWARE_HYPERVISOR_MAGIC; |
| 48 | } | 49 | } |
| 49 | 50 | ||
| 50 | static unsigned long __vmware_get_tsc_khz(void) | 51 | static unsigned long vmware_get_tsc_khz(void) |
| 51 | { | 52 | { |
| 52 | uint64_t tsc_hz; | 53 | uint64_t tsc_hz; |
| 53 | uint32_t eax, ebx, ecx, edx; | 54 | uint32_t eax, ebx, ecx, edx; |
| 54 | 55 | ||
| 55 | VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); | 56 | VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); |
| 56 | 57 | ||
| 57 | if (ebx == UINT_MAX) | ||
| 58 | return 0; | ||
| 59 | tsc_hz = eax | (((uint64_t)ebx) << 32); | 58 | tsc_hz = eax | (((uint64_t)ebx) << 32); |
| 60 | do_div(tsc_hz, 1000); | 59 | do_div(tsc_hz, 1000); |
| 61 | BUG_ON(tsc_hz >> 32); | 60 | BUG_ON(tsc_hz >> 32); |
| 62 | return tsc_hz; | 61 | return tsc_hz; |
| 63 | } | 62 | } |
| 64 | 63 | ||
| 64 | void __init vmware_platform_setup(void) | ||
| 65 | { | ||
| 66 | uint32_t eax, ebx, ecx, edx; | ||
| 67 | |||
| 68 | VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); | ||
| 69 | |||
| 70 | if (ebx != UINT_MAX) | ||
| 71 | x86_platform.calibrate_tsc = vmware_get_tsc_khz; | ||
| 72 | } | ||
| 73 | |||
| 65 | /* | 74 | /* |
| 66 | * While checking the dmi string infomation, just checking the product | 75 | * While checking the dmi string infomation, just checking the product |
| 67 | * serial key should be enough, as this will always have a VMware | 76 | * serial key should be enough, as this will always have a VMware |
| @@ -87,12 +96,6 @@ int vmware_platform(void) | |||
| 87 | return 0; | 96 | return 0; |
| 88 | } | 97 | } |
| 89 | 98 | ||
| 90 | unsigned long vmware_get_tsc_khz(void) | ||
| 91 | { | ||
| 92 | BUG_ON(!vmware_platform()); | ||
| 93 | return __vmware_get_tsc_khz(); | ||
| 94 | } | ||
| 95 | |||
| 96 | /* | 99 | /* |
| 97 | * VMware hypervisor takes care of exporting a reliable TSC to the guest. | 100 | * VMware hypervisor takes care of exporting a reliable TSC to the guest. |
| 98 | * Still, due to timing difference when running on virtual cpus, the TSC can | 101 | * Still, due to timing difference when running on virtual cpus, the TSC can |
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 64e9b5f59d2d..75a21b61b863 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c | |||
| @@ -187,7 +187,7 @@ void __init kvmclock_init(void) | |||
| 187 | pv_time_ops.get_wallclock = kvm_get_wallclock; | 187 | pv_time_ops.get_wallclock = kvm_get_wallclock; |
| 188 | pv_time_ops.set_wallclock = kvm_set_wallclock; | 188 | pv_time_ops.set_wallclock = kvm_set_wallclock; |
| 189 | pv_time_ops.sched_clock = kvm_clock_read; | 189 | pv_time_ops.sched_clock = kvm_clock_read; |
| 190 | pv_time_ops.get_tsc_khz = kvm_get_tsc_khz; | 190 | x86_platform.calibrate_tsc = kvm_get_tsc_khz; |
| 191 | #ifdef CONFIG_X86_LOCAL_APIC | 191 | #ifdef CONFIG_X86_LOCAL_APIC |
| 192 | x86_cpuinit.setup_percpu_clockev = | 192 | x86_cpuinit.setup_percpu_clockev = |
| 193 | kvm_setup_secondary_clock; | 193 | kvm_setup_secondary_clock; |
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 9c0e644a76dc..7cbf898d839b 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
| @@ -309,7 +309,6 @@ struct pv_time_ops pv_time_ops = { | |||
| 309 | .get_wallclock = native_get_wallclock, | 309 | .get_wallclock = native_get_wallclock, |
| 310 | .set_wallclock = native_set_wallclock, | 310 | .set_wallclock = native_set_wallclock, |
| 311 | .sched_clock = native_sched_clock, | 311 | .sched_clock = native_sched_clock, |
| 312 | .get_tsc_khz = native_calibrate_tsc, | ||
| 313 | }; | 312 | }; |
| 314 | 313 | ||
| 315 | struct pv_irq_ops pv_irq_ops = { | 314 | struct pv_irq_ops pv_irq_ops = { |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index bb207a47c631..2d93026af7cd 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
| @@ -818,7 +818,7 @@ void __init setup_arch(char **cmdline_p) | |||
| 818 | * VMware detection requires dmi to be available, so this | 818 | * VMware detection requires dmi to be available, so this |
| 819 | * needs to be done after dmi_scan_machine, for the BP. | 819 | * needs to be done after dmi_scan_machine, for the BP. |
| 820 | */ | 820 | */ |
| 821 | init_hypervisor(&boot_cpu_data); | 821 | init_hypervisor_platform(); |
| 822 | 822 | ||
| 823 | x86_init.resources.probe_roms(); | 823 | x86_init.resources.probe_roms(); |
| 824 | 824 | ||
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 97a0bcbad100..9917632a8b49 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <asm/delay.h> | 18 | #include <asm/delay.h> |
| 19 | #include <asm/hypervisor.h> | 19 | #include <asm/hypervisor.h> |
| 20 | #include <asm/nmi.h> | 20 | #include <asm/nmi.h> |
| 21 | #include <asm/x86_init.h> | ||
| 21 | 22 | ||
| 22 | unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */ | 23 | unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */ |
| 23 | EXPORT_SYMBOL(cpu_khz); | 24 | EXPORT_SYMBOL(cpu_khz); |
| @@ -401,15 +402,9 @@ unsigned long native_calibrate_tsc(void) | |||
| 401 | { | 402 | { |
| 402 | u64 tsc1, tsc2, delta, ref1, ref2; | 403 | u64 tsc1, tsc2, delta, ref1, ref2; |
| 403 | unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX; | 404 | unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX; |
| 404 | unsigned long flags, latch, ms, fast_calibrate, hv_tsc_khz; | 405 | unsigned long flags, latch, ms, fast_calibrate; |
| 405 | int hpet = is_hpet_enabled(), i, loopmin; | 406 | int hpet = is_hpet_enabled(), i, loopmin; |
| 406 | 407 | ||
| 407 | hv_tsc_khz = get_hypervisor_tsc_freq(); | ||
| 408 | if (hv_tsc_khz) { | ||
| 409 | printk(KERN_INFO "TSC: Frequency read from the hypervisor\n"); | ||
| 410 | return hv_tsc_khz; | ||
| 411 | } | ||
| 412 | |||
| 413 | local_irq_save(flags); | 408 | local_irq_save(flags); |
| 414 | fast_calibrate = quick_pit_calibrate(); | 409 | fast_calibrate = quick_pit_calibrate(); |
| 415 | local_irq_restore(flags); | 410 | local_irq_restore(flags); |
| @@ -567,7 +562,7 @@ int recalibrate_cpu_khz(void) | |||
| 567 | unsigned long cpu_khz_old = cpu_khz; | 562 | unsigned long cpu_khz_old = cpu_khz; |
| 568 | 563 | ||
| 569 | if (cpu_has_tsc) { | 564 | if (cpu_has_tsc) { |
| 570 | tsc_khz = calibrate_tsc(); | 565 | tsc_khz = x86_platform.calibrate_tsc(); |
| 571 | cpu_khz = tsc_khz; | 566 | cpu_khz = tsc_khz; |
| 572 | cpu_data(0).loops_per_jiffy = | 567 | cpu_data(0).loops_per_jiffy = |
| 573 | cpufreq_scale(cpu_data(0).loops_per_jiffy, | 568 | cpufreq_scale(cpu_data(0).loops_per_jiffy, |
| @@ -917,7 +912,7 @@ void __init tsc_init(void) | |||
| 917 | if (!cpu_has_tsc) | 912 | if (!cpu_has_tsc) |
| 918 | return; | 913 | return; |
| 919 | 914 | ||
| 920 | tsc_khz = calibrate_tsc(); | 915 | tsc_khz = x86_platform.calibrate_tsc(); |
| 921 | cpu_khz = tsc_khz; | 916 | cpu_khz = tsc_khz; |
| 922 | 917 | ||
| 923 | if (!tsc_khz) { | 918 | if (!tsc_khz) { |
diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c index cd7d0fbbf66e..052ae81ee08b 100644 --- a/arch/x86/kernel/vmi_32.c +++ b/arch/x86/kernel/vmi_32.c | |||
| @@ -825,7 +825,7 @@ static inline int __init activate_vmi(void) | |||
| 825 | x86_cpuinit.setup_percpu_clockev = vmi_time_ap_init; | 825 | x86_cpuinit.setup_percpu_clockev = vmi_time_ap_init; |
| 826 | #endif | 826 | #endif |
| 827 | pv_time_ops.sched_clock = vmi_sched_clock; | 827 | pv_time_ops.sched_clock = vmi_sched_clock; |
| 828 | pv_time_ops.get_tsc_khz = vmi_tsc_khz; | 828 | x86_platform.calibrate_tsc = vmi_tsc_khz; |
| 829 | 829 | ||
| 830 | /* We have true wallclock functions; disable CMOS clock sync */ | 830 | /* We have true wallclock functions; disable CMOS clock sync */ |
| 831 | no_sync_cmos_clock = 1; | 831 | no_sync_cmos_clock = 1; |
diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c index 2b3eb82efeeb..611b9e2360d3 100644 --- a/arch/x86/kernel/vmiclock_32.c +++ b/arch/x86/kernel/vmiclock_32.c | |||
| @@ -68,7 +68,7 @@ unsigned long long vmi_sched_clock(void) | |||
| 68 | return cycles_2_ns(vmi_timer_ops.get_cycle_counter(VMI_CYCLES_AVAILABLE)); | 68 | return cycles_2_ns(vmi_timer_ops.get_cycle_counter(VMI_CYCLES_AVAILABLE)); |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | /* paravirt_ops.get_tsc_khz = vmi_tsc_khz */ | 71 | /* x86_platform.calibrate_tsc = vmi_tsc_khz */ |
| 72 | unsigned long vmi_tsc_khz(void) | 72 | unsigned long vmi_tsc_khz(void) |
| 73 | { | 73 | { |
| 74 | unsigned long long khz; | 74 | unsigned long long khz; |
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c index 4790b92714a6..13081b921914 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <asm/e820.h> | 13 | #include <asm/e820.h> |
| 14 | #include <asm/time.h> | 14 | #include <asm/time.h> |
| 15 | #include <asm/irq.h> | 15 | #include <asm/irq.h> |
| 16 | #include <asm/tsc.h> | ||
| 16 | 17 | ||
| 17 | void __cpuinit x86_init_noop(void) { } | 18 | void __cpuinit x86_init_noop(void) { } |
| 18 | void __init x86_init_uint_noop(unsigned int unused) { } | 19 | void __init x86_init_uint_noop(unsigned int unused) { } |
| @@ -67,3 +68,7 @@ struct __initdata x86_init_ops x86_init = { | |||
| 67 | __cpuinitdata struct x86_cpuinit_ops x86_cpuinit = { | 68 | __cpuinitdata struct x86_cpuinit_ops x86_cpuinit = { |
| 68 | .setup_percpu_clockev = setup_secondary_APIC_clock, | 69 | .setup_percpu_clockev = setup_secondary_APIC_clock, |
| 69 | }; | 70 | }; |
| 71 | |||
| 72 | struct x86_platform_ops x86_platform = { | ||
| 73 | .calibrate_tsc = native_calibrate_tsc, | ||
| 74 | }; | ||
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 6caa8c0c793b..fabe745513d9 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
| @@ -1320,11 +1320,11 @@ __init void lguest_init(void) | |||
| 1320 | 1320 | ||
| 1321 | /* Time operations */ | 1321 | /* Time operations */ |
| 1322 | pv_time_ops.get_wallclock = lguest_get_wallclock; | 1322 | pv_time_ops.get_wallclock = lguest_get_wallclock; |
| 1323 | pv_time_ops.get_tsc_khz = lguest_tsc_khz; | ||
| 1324 | 1323 | ||
| 1325 | x86_init.resources.memory_setup = lguest_memory_setup; | 1324 | x86_init.resources.memory_setup = lguest_memory_setup; |
| 1326 | x86_init.irqs.intr_init = lguest_init_IRQ; | 1325 | x86_init.irqs.intr_init = lguest_init_IRQ; |
| 1327 | x86_init.timers.timer_init = lguest_time_init; | 1326 | x86_init.timers.timer_init = lguest_time_init; |
| 1327 | x86_platform.calibrate_tsc = lguest_tsc_khz; | ||
| 1328 | 1328 | ||
| 1329 | /* | 1329 | /* |
| 1330 | * Now is a good time to look at the implementations of these functions | 1330 | * Now is a good time to look at the implementations of these functions |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 84826b842b54..ee8cac77c8a4 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
| @@ -844,7 +844,6 @@ static const struct pv_init_ops xen_init_ops __initdata = { | |||
| 844 | static const struct pv_time_ops xen_time_ops __initdata = { | 844 | static const struct pv_time_ops xen_time_ops __initdata = { |
| 845 | .set_wallclock = xen_set_wallclock, | 845 | .set_wallclock = xen_set_wallclock, |
| 846 | .get_wallclock = xen_get_wallclock, | 846 | .get_wallclock = xen_get_wallclock, |
| 847 | .get_tsc_khz = xen_tsc_khz, | ||
| 848 | .sched_clock = xen_sched_clock, | 847 | .sched_clock = xen_sched_clock, |
| 849 | }; | 848 | }; |
| 850 | 849 | ||
| @@ -980,6 +979,8 @@ asmlinkage void __init xen_start_kernel(void) | |||
| 980 | x86_init.timers.setup_percpu_clockev = x86_init_noop; | 979 | x86_init.timers.setup_percpu_clockev = x86_init_noop; |
| 981 | x86_cpuinit.setup_percpu_clockev = x86_init_noop; | 980 | x86_cpuinit.setup_percpu_clockev = x86_init_noop; |
| 982 | 981 | ||
| 982 | x86_platform.calibrate_tsc = xen_tsc_khz; | ||
| 983 | |||
| 983 | #ifdef CONFIG_X86_64 | 984 | #ifdef CONFIG_X86_64 |
| 984 | /* | 985 | /* |
| 985 | * Setup percpu state. We only need to do this for 64-bit | 986 | * Setup percpu state. We only need to do this for 64-bit |
