]> xenbits.xensource.com Git - people/sstabellini/xen-unstable.git/.git/commitdiff
x86/time: Alter tsc_set_info() to return an error value
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 20 Nov 2018 11:37:19 +0000 (11:37 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 18 Dec 2018 17:13:51 +0000 (17:13 +0000)
Currently, tsc_set_info() performs no parameter checking, and an invalid
tsc_mode goes largely unnoticed.  Fix it to reject invalid tsc_modes with
-EINVAL, and update the callers to check the return value.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/domain.c
xen/arch/x86/domctl.c
xen/arch/x86/time.c
xen/include/asm-x86/time.h

index f0e0cdbb0ee4886df1e92574c3530eb44818057e..ae9f24e457607d309886439067a6ddc11233eff6 100644 (file)
@@ -599,8 +599,11 @@ int arch_domain_create(struct domain *d,
     else
         ASSERT_UNREACHABLE(); /* Not HVM and not PV? */
 
-    /* initialize default tsc behavior in case tools don't */
-    tsc_set_info(d, TSC_MODE_DEFAULT, 0UL, 0, 0);
+    if ( (rc = tsc_set_info(d, TSC_MODE_DEFAULT, 0, 0, 0)) != 0 )
+    {
+        ASSERT_UNREACHABLE();
+        goto fail;
+    }
 
     /* PV/PVH guests get an emulated PIT too for video BIOSes to use. */
     pit_init(d, cpu_khz);
index aa8ad1947929b5431d18a4ef3f612ce07a747a30..ed46df8c5d615fafcc107912e10656aadf67d4b2 100644 (file)
@@ -975,10 +975,10 @@ long arch_do_domctl(
         else
         {
             domain_pause(d);
-            tsc_set_info(d, domctl->u.tsc_info.tsc_mode,
-                         domctl->u.tsc_info.elapsed_nsec,
-                         domctl->u.tsc_info.gtsc_khz,
-                         domctl->u.tsc_info.incarnation);
+            ret = tsc_set_info(d, domctl->u.tsc_info.tsc_mode,
+                               domctl->u.tsc_info.elapsed_nsec,
+                               domctl->u.tsc_info.gtsc_khz,
+                               domctl->u.tsc_info.incarnation);
             domain_unpause(d);
         }
         break;
index 24d4c2794b5c5a33da24d959b69c6c2e4b4ec79f..d80a5868a02a950b39c8ce745e418116d7183b8f 100644 (file)
@@ -2194,19 +2194,19 @@ void tsc_get_info(struct domain *d, uint32_t *tsc_mode,
  * only the last "sticks" and all are completed before the guest executes
  * an rdtsc instruction
  */
-void tsc_set_info(struct domain *d,
-                  uint32_t tsc_mode, uint64_t elapsed_nsec,
-                  uint32_t gtsc_khz, uint32_t incarnation)
+int tsc_set_info(struct domain *d,
+                 uint32_t tsc_mode, uint64_t elapsed_nsec,
+                 uint32_t gtsc_khz, uint32_t incarnation)
 {
     ASSERT(!is_system_domain(d));
 
     if ( is_pv_domain(d) && is_hardware_domain(d) )
     {
         d->arch.vtsc = 0;
-        return;
+        return 0;
     }
 
-    switch ( d->arch.tsc_mode = tsc_mode )
+    switch ( tsc_mode )
     {
         bool enable_tsc_scaling;
 
@@ -2253,7 +2253,13 @@ void tsc_set_info(struct domain *d,
                                   elapsed_nsec;
         }
         break;
+
+    default:
+        return -EINVAL;
     }
+
+    d->arch.tsc_mode = tsc_mode;
+
     d->arch.incarnation = incarnation + 1;
     if ( is_hvm_domain(d) )
     {
@@ -2280,6 +2286,8 @@ void tsc_set_info(struct domain *d,
     }
 
     recalculate_cpuid_policy(d);
+
+    return 0;
 }
 
 /* vtsc may incur measurable performance degradation, diagnose with this */
index ce96ec9778d26bb0dfb98e5b8433c64ee8701660..b85688dcfbe1ec2b5e38646b53f1516c799885f6 100644 (file)
@@ -60,9 +60,9 @@ uint64_t pv_soft_rdtsc(const struct vcpu *v, const struct cpu_user_regs *regs);
 u64 gtime_to_gtsc(struct domain *d, u64 time);
 u64 gtsc_to_gtime(struct domain *d, u64 tsc);
 
-void tsc_set_info(struct domain *d, uint32_t tsc_mode, uint64_t elapsed_nsec,
-                  uint32_t gtsc_khz, uint32_t incarnation);
-   
+int tsc_set_info(struct domain *d, uint32_t tsc_mode, uint64_t elapsed_nsec,
+                 uint32_t gtsc_khz, uint32_t incarnation);
+
 void tsc_get_info(struct domain *d, uint32_t *tsc_mode, uint64_t *elapsed_nsec,
                   uint32_t *gtsc_khz, uint32_t *incarnation);