diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index f646c1ee7b..e0cb82d2a3 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -60,6 +60,7 @@ #include #include #include +#include /* for cpu_has_tsc_ratio */ #include #include #include @@ -310,13 +311,11 @@ void hvm_set_guest_tsc_fixed(struct vcpu *v, u64 guest_tsc, u64 at_tsc) tsc = hvm_get_guest_time_fixed(v, at_tsc); tsc = gtime_to_gtsc(v->domain, tsc); } - else if ( at_tsc ) - { - tsc = at_tsc; - } else { - tsc = rdtsc(); + tsc = at_tsc ?: rdtsc(); + if ( cpu_has_tsc_ratio ) + tsc = hvm_funcs.scale_tsc(v, tsc); } delta_tsc = guest_tsc - tsc; @@ -344,13 +343,11 @@ u64 hvm_get_guest_tsc_fixed(struct vcpu *v, uint64_t at_tsc) tsc = hvm_get_guest_time_fixed(v, at_tsc); tsc = gtime_to_gtsc(v->domain, tsc); } - else if ( at_tsc ) - { - tsc = at_tsc; - } else { - tsc = rdtsc(); + tsc = at_tsc ?: rdtsc(); + if ( cpu_has_tsc_ratio ) + tsc = hvm_funcs.scale_tsc(v, tsc); } return tsc + v->arch.hvm_vcpu.cache_tsc_offset; diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index a66d854480..a46bc98576 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -804,6 +804,13 @@ static uint64_t scale_tsc(uint64_t host_tsc, uint64_t ratio) return scaled_host_tsc; } +static uint64_t svm_scale_tsc(const struct vcpu *v, uint64_t tsc) +{ + ASSERT(cpu_has_tsc_ratio && !v->domain->arch.vtsc); + + return scale_tsc(tsc, vcpu_tsc_ratio(v)); +} + static uint64_t svm_get_tsc_offset(uint64_t host_tsc, uint64_t guest_tsc, uint64_t ratio) { @@ -2272,6 +2279,8 @@ static struct hvm_function_table __initdata svm_function_table = { .nhvm_vmcx_hap_enabled = nsvm_vmcb_hap_enabled, .nhvm_intr_blocked = nsvm_intr_blocked, .nhvm_hap_walk_L1_p2m = nsvm_hap_walk_L1_p2m, + + .scale_tsc = svm_scale_tsc, }; void svm_vmexit_handler(struct cpu_user_regs *regs) diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index b9d893d1e2..a87224b138 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -212,6 +212,8 @@ struct hvm_function_table { void (*altp2m_vcpu_update_vmfunc_ve)(struct vcpu *v); bool_t (*altp2m_vcpu_emulate_ve)(struct vcpu *v); int (*altp2m_vcpu_emulate_vmfunc)(struct cpu_user_regs *regs); + + uint64_t (*scale_tsc)(const struct vcpu *v, uint64_t tsc); }; extern struct hvm_function_table hvm_funcs;