[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 04/13] x86/hvm: Setup TSC scaling ratio
This patch adds a field tsc_scaling_ratio in struct arch_vcpu to represent the TSC scaling ratio, and sets it up when tsc_set_info() is called for a vcpu or a vcpu is restored or reset. Signed-off-by: Haozhong Zhang <haozhong.zhang@xxxxxxxxx> --- xen/arch/x86/hvm/hvm.c | 34 ++++++++++++++++++++++++++++++++++ xen/arch/x86/hvm/svm/svm.c | 2 ++ xen/arch/x86/time.c | 10 +++++++++- xen/include/asm-x86/domain.h | 2 ++ xen/include/asm-x86/hvm/hvm.h | 2 ++ 5 files changed, 49 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 6afc344..63ce4de 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -297,6 +297,34 @@ int hvm_set_guest_pat(struct vcpu *v, u64 guest_pat) return 1; } +void hvm_setup_tsc_scaling(struct vcpu *v) +{ + u64 ratio, khz; + s8 shift; + + if ( !hvm_funcs.tsc_scaling_supported ) + return; + + khz = v->domain->arch.tsc_khz; + shift = (hvm_funcs.tsc_scaling_ratio_frac_bits <= 32) ? + hvm_funcs.tsc_scaling_ratio_frac_bits : 32; + ratio = khz << shift; + do_div(ratio, cpu_khz); + ratio <<= hvm_funcs.tsc_scaling_ratio_frac_bits - shift; + + if ( ratio == 0 || + ratio > hvm_funcs.max_tsc_scaling_ratio || + ratio & hvm_funcs.tsc_scaling_ratio_rsvd ) + { + printk(XENLOG_WARNING + "Invalid TSC scaling ratio - virtual tsc khz=%lu\n", + khz); + return; + } + + v->arch.tsc_scaling_ratio = ratio; +} + void hvm_set_guest_tsc_fixed(struct vcpu *v, u64 guest_tsc, u64 at_tsc) { uint64_t tsc; @@ -2023,6 +2051,9 @@ static int hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h) if ( hvm_funcs.load_cpu_ctxt(v, &ctxt) < 0 ) return -EINVAL; + if ( !v->domain->arch.vtsc && hvm_funcs.tsc_scaling_supported ) + hvm_setup_tsc_scaling(v); + v->arch.hvm_vcpu.msr_tsc_aux = ctxt.msr_tsc_aux; seg.limit = ctxt.idtr_limit; @@ -5458,6 +5489,9 @@ void hvm_vcpu_reset_state(struct vcpu *v, uint16_t cs, uint16_t ip) hvm_set_segment_register(v, x86_seg_gdtr, ®); hvm_set_segment_register(v, x86_seg_idtr, ®); + if ( !v->domain->arch.vtsc && hvm_funcs.tsc_scaling_supported ) + hvm_setup_tsc_scaling(v); + /* Sync AP's TSC with BSP's. */ v->arch.hvm_vcpu.cache_tsc_offset = v->domain->vcpu[0]->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 94b9618..a7465c6 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -1170,6 +1170,8 @@ static int svm_vcpu_initialise(struct vcpu *v) svm_guest_osvw_init(v); + v->arch.tsc_scaling_ratio = DEFAULT_TSC_RATIO; + return 0; } diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 92dd8a1..64f4e31 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -1956,6 +1956,8 @@ void tsc_set_info(struct domain *d, { case TSC_MODE_NEVER_EMULATE: d->arch.vtsc = 0; + if ( tsc_mode == TSC_MODE_NEVER_EMULATE ) + d->arch.tsc_khz = cpu_khz; break; } d->arch.vtsc = 1; @@ -1981,8 +1983,14 @@ void tsc_set_info(struct domain *d, if ( is_hvm_domain(d) ) { hvm_set_rdtsc_exiting(d, d->arch.vtsc); - if ( d->vcpu && d->vcpu[0] && incarnation == 0 ) + if ( d->vcpu && d->vcpu[0] ) { + if ( !d->arch.vtsc && hvm_funcs.tsc_scaling_supported ) + hvm_setup_tsc_scaling(d->vcpu[0]); + + if ( incarnation ) + return; + /* * set_tsc_offset() is called from hvm_vcpu_initialise() before * tsc_set_info(). New vtsc mode may require recomputing TSC diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index f0aeade..fffd519 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -533,6 +533,8 @@ struct arch_vcpu XEN_GUEST_HANDLE(vcpu_time_info_t) time_info_guest; struct arch_vm_event *vm_event; + + uint64_t tsc_scaling_ratio; }; smap_check_policy_t smap_policy_change(struct vcpu *v, diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index 7dddfa0..55e7f64 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -261,6 +261,8 @@ void hvm_set_guest_tsc_fixed(struct vcpu *v, u64 guest_tsc, u64 at_tsc); u64 hvm_get_guest_tsc_fixed(struct vcpu *v, u64 at_tsc); #define hvm_get_guest_tsc(v) hvm_get_guest_tsc_fixed(v, 0) +void hvm_setup_tsc_scaling(struct vcpu *v); + int hvm_set_mode(struct vcpu *v, int mode); void hvm_init_guest_time(struct domain *d); void hvm_set_guest_time(struct vcpu *v, u64 guest_time); -- 2.4.8 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |