aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZachary Amsden <zach@vmware.com>2007-03-05 03:30:36 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-05 10:57:52 -0500
commit1182d8528b620c23d043bccbbef092b42062960a (patch)
tree3df690a1a731811f8fecda06cb785a5a7b06d4d0
parent6cb9a8350aee789100a365794272ed20cc8f2401 (diff)
[PATCH] vmi: cpu cycles fix
In order to share the common code in tsc.c which does CPU Khz calibration, we need to make an accurate value of CPU speed available to the tsc.c code. This value loses a lot of precision in a VM because of the timing differences with real hardware, but we need it to be as precise as possible so the guest can make accurate time calculations with the cycle counters. Signed-off-by: Zachary Amsden <zach@vmware.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/i386/kernel/paravirt.c1
-rw-r--r--arch/i386/kernel/tsc.c2
-rw-r--r--arch/i386/kernel/vmi.c1
-rw-r--r--arch/i386/kernel/vmitime.c10
-rw-r--r--include/asm-i386/paravirt.h2
-rw-r--r--include/asm-i386/timer.h2
-rw-r--r--include/asm-i386/vmi_time.h1
7 files changed, 17 insertions, 2 deletions
diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c
index 31bbe70d1e02..8352394d5efb 100644
--- a/arch/i386/kernel/paravirt.c
+++ b/arch/i386/kernel/paravirt.c
@@ -522,6 +522,7 @@ struct paravirt_ops paravirt_ops = {
522 .read_tsc = native_read_tsc, 522 .read_tsc = native_read_tsc,
523 .read_pmc = native_read_pmc, 523 .read_pmc = native_read_pmc,
524 .get_scheduled_cycles = native_read_tsc, 524 .get_scheduled_cycles = native_read_tsc,
525 .get_cpu_khz = native_calculate_cpu_khz,
525 .load_tr_desc = native_load_tr_desc, 526 .load_tr_desc = native_load_tr_desc,
526 .set_ldt = native_set_ldt, 527 .set_ldt = native_set_ldt,
527 .load_gdt = native_load_gdt, 528 .load_gdt = native_load_gdt,
diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c
index c9c9d54c91f6..59222a04234b 100644
--- a/arch/i386/kernel/tsc.c
+++ b/arch/i386/kernel/tsc.c
@@ -117,7 +117,7 @@ unsigned long long sched_clock(void)
117 return cycles_2_ns(this_offset); 117 return cycles_2_ns(this_offset);
118} 118}
119 119
120static unsigned long calculate_cpu_khz(void) 120unsigned long native_calculate_cpu_khz(void)
121{ 121{
122 unsigned long long start, end; 122 unsigned long long start, end;
123 unsigned long count; 123 unsigned long count;
diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c
index 556b9a6b7365..acdfe69fb7ad 100644
--- a/arch/i386/kernel/vmi.c
+++ b/arch/i386/kernel/vmi.c
@@ -874,6 +874,7 @@ static inline int __init activate_vmi(void)
874 paravirt_ops.setup_secondary_clock = vmi_timer_setup_secondary_alarm; 874 paravirt_ops.setup_secondary_clock = vmi_timer_setup_secondary_alarm;
875#endif 875#endif
876 paravirt_ops.get_scheduled_cycles = vmi_get_sched_cycles; 876 paravirt_ops.get_scheduled_cycles = vmi_get_sched_cycles;
877 paravirt_ops.get_cpu_khz = vmi_cpu_khz;
877 } 878 }
878 if (!disable_noidle) 879 if (!disable_noidle)
879 para_fill(safe_halt, Halt); 880 para_fill(safe_halt, Halt);
diff --git a/arch/i386/kernel/vmitime.c b/arch/i386/kernel/vmitime.c
index f2aa8fab8c02..4bb218e2eb14 100644
--- a/arch/i386/kernel/vmitime.c
+++ b/arch/i386/kernel/vmitime.c
@@ -177,6 +177,15 @@ unsigned long long vmi_get_sched_cycles(void)
177 return read_available_cycles(); 177 return read_available_cycles();
178} 178}
179 179
180unsigned long vmi_cpu_khz(void)
181{
182 unsigned long long khz;
183
184 khz = vmi_timer_ops.get_cycle_frequency();
185 (void)do_div(khz, 1000);
186 return khz;
187}
188
180void __init vmi_time_init(void) 189void __init vmi_time_init(void)
181{ 190{
182 unsigned long long cycles_per_sec, cycles_per_msec; 191 unsigned long long cycles_per_sec, cycles_per_msec;
@@ -206,7 +215,6 @@ void __init vmi_time_init(void)
206 (void)do_div(cycles_per_alarm, alarm_hz); 215 (void)do_div(cycles_per_alarm, alarm_hz);
207 cycles_per_msec = cycles_per_sec; 216 cycles_per_msec = cycles_per_sec;
208 (void)do_div(cycles_per_msec, 1000); 217 (void)do_div(cycles_per_msec, 1000);
209 cpu_khz = cycles_per_msec;
210 218
211 printk(KERN_WARNING "VMI timer cycles/sec = %llu ; cycles/jiffy = %llu ;" 219 printk(KERN_WARNING "VMI timer cycles/sec = %llu ; cycles/jiffy = %llu ;"
212 "cycles/alarm = %llu\n", cycles_per_sec, cycles_per_jiffy, 220 "cycles/alarm = %llu\n", cycles_per_sec, cycles_per_jiffy,
diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h
index a13230254f4f..a35c81480654 100644
--- a/include/asm-i386/paravirt.h
+++ b/include/asm-i386/paravirt.h
@@ -95,6 +95,7 @@ struct paravirt_ops
95 u64 (*read_tsc)(void); 95 u64 (*read_tsc)(void);
96 u64 (*read_pmc)(void); 96 u64 (*read_pmc)(void);
97 u64 (*get_scheduled_cycles)(void); 97 u64 (*get_scheduled_cycles)(void);
98 unsigned long (*get_cpu_khz)(void);
98 99
99 void (*load_tr_desc)(void); 100 void (*load_tr_desc)(void);
100 void (*load_gdt)(const struct Xgt_desc_struct *); 101 void (*load_gdt)(const struct Xgt_desc_struct *);
@@ -275,6 +276,7 @@ static inline void halt(void)
275#define rdtscll(val) (val = paravirt_ops.read_tsc()) 276#define rdtscll(val) (val = paravirt_ops.read_tsc())
276 277
277#define get_scheduled_cycles(val) (val = paravirt_ops.get_scheduled_cycles()) 278#define get_scheduled_cycles(val) (val = paravirt_ops.get_scheduled_cycles())
279#define calculate_cpu_khz() (paravirt_ops.get_cpu_khz())
278 280
279#define write_tsc(val1,val2) wrmsr(0x10, val1, val2) 281#define write_tsc(val1,val2) wrmsr(0x10, val1, val2)
280 282
diff --git a/include/asm-i386/timer.h b/include/asm-i386/timer.h
index d1f7b4f575b4..12dd67bf760f 100644
--- a/include/asm-i386/timer.h
+++ b/include/asm-i386/timer.h
@@ -7,6 +7,7 @@
7 7
8void setup_pit_timer(void); 8void setup_pit_timer(void);
9unsigned long long native_sched_clock(void); 9unsigned long long native_sched_clock(void);
10unsigned long native_calculate_cpu_khz(void);
10 11
11/* Modifiers for buggy PIT handling */ 12/* Modifiers for buggy PIT handling */
12extern int pit_latch_buggy; 13extern int pit_latch_buggy;
@@ -17,6 +18,7 @@ extern int recalibrate_cpu_khz(void);
17 18
18#ifndef CONFIG_PARAVIRT 19#ifndef CONFIG_PARAVIRT
19#define get_scheduled_cycles(val) rdtscll(val) 20#define get_scheduled_cycles(val) rdtscll(val)
21#define calculate_cpu_khz() native_calculate_cpu_khz()
20#endif 22#endif
21 23
22#endif 24#endif
diff --git a/include/asm-i386/vmi_time.h b/include/asm-i386/vmi_time.h
index f59c35d37352..1f971eb7f71e 100644
--- a/include/asm-i386/vmi_time.h
+++ b/include/asm-i386/vmi_time.h
@@ -50,6 +50,7 @@ extern void __init vmi_time_init(void);
50extern unsigned long vmi_get_wallclock(void); 50extern unsigned long vmi_get_wallclock(void);
51extern int vmi_set_wallclock(unsigned long now); 51extern int vmi_set_wallclock(unsigned long now);
52extern unsigned long long vmi_get_sched_cycles(void); 52extern unsigned long long vmi_get_sched_cycles(void);
53extern unsigned long vmi_cpu_khz(void);
53 54
54#ifdef CONFIG_X86_LOCAL_APIC 55#ifdef CONFIG_X86_LOCAL_APIC
55extern void __init vmi_timer_setup_boot_alarm(void); 56extern void __init vmi_timer_setup_boot_alarm(void);