Having TSC as platform timer requires being explicitly set. This is because
TSC can only be safely used if CPU hotplug isn't performed on the system. On
some platforms, the "maxcpus" option may need to be used to further adjust
-the number of allowed CPUs.
+the number of allowed CPUs. When running on platforms that can guarantee a
+monotonic TSC across sockets you may want to adjust the "tsc" command line
+parameter to "stable:socket".
### cmci-threshold
> `= <integer>`
> `= <integer>`
### tsc
-> `= unstable | skewed`
+> `= unstable | skewed | stable:socket`
### ucode
> `= [<integer> | scan]`
/************************************************************
* PLATFORM TIMER 4: TSC
*/
+static unsigned int __initdata tsc_flags;
+
+/* TSC is reliable across sockets */
+#define TSC_RELIABLE_SOCKET (1 << 0)
/*
* Called in verify_tsc_reliability() under reliable TSC conditions
ret = 0;
}
- if ( nr_sockets > 1 )
+ if ( nr_sockets > 1 && !(tsc_flags & TSC_RELIABLE_SOCKET) )
{
printk(XENLOG_WARNING "TSC: Not invariant across sockets\n");
ret = 0;
/*
* tsc=unstable: Override all tests; assume TSC is unreliable.
* tsc=skewed: Assume TSCs are individually reliable, but skewed across CPUs.
+ * tsc=stable:socket: Assume TSCs are reliable across sockets.
*/
static void __init tsc_parse(const char *s)
{
setup_clear_cpu_cap(X86_FEATURE_TSC_RELIABLE);
}
else if ( !strcmp(s, "skewed") )
- {
setup_clear_cpu_cap(X86_FEATURE_TSC_RELIABLE);
- }
+ else if ( !strcmp(s, "stable:socket") )
+ tsc_flags |= TSC_RELIABLE_SOCKET;
}
custom_param("tsc", tsc_parse);