diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 4fd53761eb..813e7751bc 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -728,7 +728,7 @@ static void svm_set_rdtsc_exiting(struct vcpu *v, bool_t enable) 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; diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 07bceda49d..555f7c8624 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -37,6 +37,7 @@ #include #include #include /* for early_time_init */ +#include /* for cpu_has_tsc_ratio */ #include /* opt_clocksource: Force clocksource to one of: pit, hpet, acpi. */ @@ -1889,10 +1890,16 @@ void tsc_set_info(struct domain *d, 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() && + ((has_hvm_container_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);