aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/time.c
diff options
context:
space:
mode:
authorKeir Fraser <keir@xen.org>2010-10-29 10:40:14 +0100
committerKeir Fraser <keir@xen.org>2010-10-29 10:40:14 +0100
commitfd1291a826e17108d7c7f20c887847daba451ef4 (patch)
tree963f0da4548bc87d110ff0a4982f1b14f913be29 /xen/arch/x86/time.c
parent9dbd1007376011d99e6af1dd703c2cc437e7fda0 (diff)
downloadxen-fd1291a826e17108d7c7f20c887847daba451ef4.tar.gz
xen-fd1291a826e17108d7c7f20c887847daba451ef4.tar.bz2
xen-fd1291a826e17108d7c7f20c887847daba451ef4.zip
X86: Prefer TSC-deadline timer in Xen
The new TSC Deadline Timer offers system software a low overhead per-logical-thread deadline timer in TSC units. The timer is implemented via a new architectural 64-bit register, IA32_TSC_DEADLINE_MSR. Reads and writes of this MSR occur in program order, but are non-serializing. The support for this feature is indicated by CPUID.01H:ECX.TSC_Deadline[bit 24] =3D 1 as documented in the Intel Architecture Software Developer's Manual. The LOCAL APIC on new processors has a mode where its underlying hardware timer can now be accessed via the non-serializing IA32_TSC_DEADLINE_MSR in TSC tick units. If this mode is present, prefer it over the traditional LAPIC timer mode. KERN_DEBUG dmesg will print "TSC deadline timer enabled" when TDT is used. Bootparam "tdt=off" is available to revert to LAPIC timer mode. This patch is based on original work by Len Brown for Linux kernel. cc: Len Brown <len.brown@intel.com> Signed-off-by: Wei Gang <gang.wei@intel.com> Signed-off-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/time.c')
-rw-r--r--xen/arch/x86/time.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
index 0564c398b7..ad37cb3075 100644
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -662,26 +662,28 @@ static void __init init_platform_timer(void)
freq_string(pts->frequency), pts->name);
}
-void cstate_restore_tsc(void)
+u64 stime2tsc(s_time_t stime)
{
struct cpu_time *t;
struct time_scale sys_to_tsc;
s_time_t stime_delta;
- u64 new_tsc;
-
- if ( boot_cpu_has(X86_FEATURE_NONSTOP_TSC) )
- return;
t = &this_cpu(cpu_time);
sys_to_tsc = scale_reciprocal(t->tsc_scale);
- stime_delta = read_platform_stime() - t->stime_master_stamp;
+ stime_delta = stime - t->stime_local_stamp;
if ( stime_delta < 0 )
stime_delta = 0;
- new_tsc = t->local_tsc_stamp + scale_delta(stime_delta, &sys_to_tsc);
+ return t->local_tsc_stamp + scale_delta(stime_delta, &sys_to_tsc);
+}
+
+void cstate_restore_tsc(void)
+{
+ if ( boot_cpu_has(X86_FEATURE_NONSTOP_TSC) )
+ return;
- write_tsc(new_tsc);
+ write_tsc(stime2tsc(read_platform_stime()));
}
/***************************************************************************