]> xenbits.xensource.com Git - people/liuw/xen.git/commitdiff
x86/hvm: replace architecture TSC scaling by a common function
authorHaozhong Zhang <haozhong.zhang@intel.com>
Tue, 1 Mar 2016 13:37:53 +0000 (14:37 +0100)
committerWei Liu <wei.liu2@citrix.com>
Tue, 15 Mar 2016 16:32:32 +0000 (16:32 +0000)
This patch implements a common function hvm_scale_tsc() to scale TSC by
using TSC scaling information collected by architecture code.

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
Acked-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> for SVM bits
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/time.c
xen/include/asm-x86/hvm/hvm.h

index 38586da480bc3ac172b7ad6ab46d6bfba36bd21a..1a261eb300ea21a440faadb44693962d10f8ff9c 100644 (file)
@@ -334,6 +334,23 @@ u64 hvm_get_tsc_scaling_ratio(u32 gtsc_khz)
     return ratio > max_ratio ? 0 : ratio;
 }
 
+u64 hvm_scale_tsc(const struct domain *d, u64 tsc)
+{
+    u64 ratio = d->arch.hvm_domain.tsc_scaling_ratio;
+    u64 dummy;
+
+    if ( ratio == hvm_default_tsc_scaling_ratio )
+        return tsc;
+
+    /* tsc = (tsc * ratio) >> hvm_funcs.tsc_scaling.ratio_frac_bits */
+    asm ( "mulq %[ratio]; shrdq %[frac],%%rdx,%[tsc]"
+          : [tsc] "+a" (tsc), "=&d" (dummy)
+          : [frac] "c" (hvm_funcs.tsc_scaling.ratio_frac_bits),
+            [ratio] "rm" (ratio) );
+
+    return tsc;
+}
+
 void hvm_set_guest_tsc_fixed(struct vcpu *v, u64 guest_tsc, u64 at_tsc)
 {
     uint64_t tsc;
@@ -348,7 +365,7 @@ void hvm_set_guest_tsc_fixed(struct vcpu *v, u64 guest_tsc, u64 at_tsc)
     {
         tsc = at_tsc ?: rdtsc();
         if ( hvm_tsc_scaling_supported )
-            tsc = hvm_funcs.tsc_scaling.scale_tsc(v, tsc);
+            tsc = hvm_scale_tsc(v->domain, tsc);
     }
 
     delta_tsc = guest_tsc - tsc;
@@ -380,7 +397,7 @@ u64 hvm_get_guest_tsc_fixed(struct vcpu *v, uint64_t at_tsc)
     {
         tsc = at_tsc ?: rdtsc();
         if ( hvm_tsc_scaling_supported )
-            tsc = hvm_funcs.tsc_scaling.scale_tsc(v, tsc);
+            tsc = hvm_scale_tsc(v->domain, tsc);
     }
 
     return tsc + v->arch.hvm_vcpu.cache_tsc_offset;
index 7172f25136cbbf4064a356d4692255d6152e2e6d..979d226f033fd7a1401346c819fc591fb912e49e 100644 (file)
@@ -819,13 +819,6 @@ 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, hvm_tsc_scaling_ratio(v->domain));
-}
-
 static uint64_t svm_get_tsc_offset(uint64_t host_tsc, uint64_t guest_tsc,
     uint64_t ratio)
 {
@@ -2291,7 +2284,6 @@ static struct hvm_function_table __initdata svm_function_table = {
 
     .tsc_scaling = {
         .max_ratio = ~TSC_RATIO_RSVD_BITS,
-        .scale_tsc = svm_scale_tsc,
     },
 };
 
index fda96927bb2873717d679d28f8443ccd9cb86b17..687e39bce37fcd607ad081d485111853a333e9bf 100644 (file)
@@ -816,8 +816,7 @@ static void __update_vcpu_system_time(struct vcpu *v, int force)
     {
         if ( has_hvm_container_domain(d) && hvm_tsc_scaling_supported )
         {
-            tsc_stamp            =
-                hvm_funcs.tsc_scaling.scale_tsc(v, t->local_tsc_stamp);
+            tsc_stamp            = hvm_scale_tsc(d, t->local_tsc_stamp);
             _u.tsc_to_system_mul = d->arch.vtsc_to_ns.mul_frac;
             _u.tsc_shift         = d->arch.vtsc_to_ns.shift;
         }
index ddb1e33f3d6944317f0dd7c60bd6bc51fa014c32..c5c9328f347696afd6d60b1b4431ab88a5b7f8a8 100644 (file)
@@ -231,8 +231,6 @@ struct hvm_function_table {
         uint8_t  ratio_frac_bits;
         /* maximum-allowed TSC scaling ratio */
         uint64_t max_ratio;
-
-        uint64_t (*scale_tsc)(const struct vcpu *v, uint64_t tsc);
     } tsc_scaling;
 };
 
@@ -278,6 +276,7 @@ u64 hvm_get_guest_tsc_fixed(struct vcpu *v, u64 at_tsc);
 #define hvm_tsc_scaling_ratio(d) \
     ((d)->arch.hvm_domain.tsc_scaling_ratio)
 
+u64 hvm_scale_tsc(const struct domain *d, u64 tsc);
 u64 hvm_get_tsc_scaling_ratio(u32 gtsc_khz);
 
 int hvm_set_mode(struct vcpu *v, int mode);