general1_intercepts &= ~GENERAL1_INTERCEPT_RDTSC;
general2_intercepts &= ~GENERAL2_INTERCEPT_RDTSCP;
- if ( enable && !cpu_has_tsc_ratio )
+ if ( enable )
{
general1_intercepts |= GENERAL1_INTERCEPT_RDTSC;
general2_intercepts |= GENERAL2_INTERCEPT_RDTSCP;
#include <asm/hpet.h>
#include <io_ports.h>
#include <asm/setup.h> /* for early_time_init */
+#include <asm/hvm/svm/svm.h> /* for cpu_has_tsc_ratio */
#include <public/arch-x86/cpuid.h>
/* opt_clocksource: Force clocksource to one of: pit, hpet, cyclone, acpi. */
d->arch.vtsc_offset = get_s_time() - elapsed_nsec;
d->arch.tsc_khz = gtsc_khz ? gtsc_khz : cpu_khz;
set_time_scale(&d->arch.vtsc_to_ns, d->arch.tsc_khz * 1000 );
- /* use native TSC if initial host has safe TSC, has not migrated
- * yet and tsc_khz == cpu_khz */
- if ( host_tsc_is_safe() && incarnation == 0 &&
- d->arch.tsc_khz == cpu_khz )
+ /*
+ * Use native TSC if the host has safe TSC and:
+ * HVM/PVH: host and guest frequencies are the same (either
+ * "naturally" or via TSC scaling)
+ * PV: guest has not migrated yet (and thus arch.tsc_khz == cpu_khz)
+ */
+ if ( host_tsc_is_safe() &&
+ ((is_hvm_domain(d) &&
+ (d->arch.tsc_khz == cpu_khz || cpu_has_tsc_ratio)) ||
+ incarnation == 0) )
d->arch.vtsc = 0;
else
d->arch.ns_to_vtsc = scale_reciprocal(d->arch.vtsc_to_ns);