Commit 1182d852 authored by Zachary Amsden's avatar Zachary Amsden Committed by Linus Torvalds
Browse files

[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: default avatarZachary Amsden <zach@vmware.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 6cb9a835
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -522,6 +522,7 @@ struct paravirt_ops paravirt_ops = {
	.read_tsc = native_read_tsc,
	.read_pmc = native_read_pmc,
	.get_scheduled_cycles = native_read_tsc,
	.get_cpu_khz = native_calculate_cpu_khz,
	.load_tr_desc = native_load_tr_desc,
	.set_ldt = native_set_ldt,
	.load_gdt = native_load_gdt,
+1 −1
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ unsigned long long sched_clock(void)
	return cycles_2_ns(this_offset);
}

static unsigned long calculate_cpu_khz(void)
unsigned long native_calculate_cpu_khz(void)
{
	unsigned long long start, end;
	unsigned long count;
+1 −0
Original line number Diff line number Diff line
@@ -874,6 +874,7 @@ static inline int __init activate_vmi(void)
		paravirt_ops.setup_secondary_clock = vmi_timer_setup_secondary_alarm;
#endif
		paravirt_ops.get_scheduled_cycles = vmi_get_sched_cycles;
 		paravirt_ops.get_cpu_khz = vmi_cpu_khz;
	}
	if (!disable_noidle)
		para_fill(safe_halt, Halt);
+9 −1
Original line number Diff line number Diff line
@@ -177,6 +177,15 @@ unsigned long long vmi_get_sched_cycles(void)
	return read_available_cycles();
}

unsigned long vmi_cpu_khz(void)
{
	unsigned long long khz;

	khz = vmi_timer_ops.get_cycle_frequency();
	(void)do_div(khz, 1000);
	return khz;
}

void __init vmi_time_init(void)
{
	unsigned long long cycles_per_sec, cycles_per_msec;
@@ -206,7 +215,6 @@ void __init vmi_time_init(void)
	(void)do_div(cycles_per_alarm, alarm_hz);
	cycles_per_msec = cycles_per_sec;
	(void)do_div(cycles_per_msec, 1000);
	cpu_khz = cycles_per_msec;

	printk(KERN_WARNING "VMI timer cycles/sec = %llu ; cycles/jiffy = %llu ;"
	       "cycles/alarm = %llu\n", cycles_per_sec, cycles_per_jiffy,
+2 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ struct paravirt_ops
	u64 (*read_tsc)(void);
	u64 (*read_pmc)(void);
 	u64 (*get_scheduled_cycles)(void);
	unsigned long (*get_cpu_khz)(void);

	void (*load_tr_desc)(void);
	void (*load_gdt)(const struct Xgt_desc_struct *);
@@ -275,6 +276,7 @@ static inline void halt(void)
#define rdtscll(val) (val = paravirt_ops.read_tsc())

#define get_scheduled_cycles(val) (val = paravirt_ops.get_scheduled_cycles())
#define calculate_cpu_khz() (paravirt_ops.get_cpu_khz())

#define write_tsc(val1,val2) wrmsr(0x10, val1, val2)

Loading