WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] hvm: Lower HPET frequency to 1/32 of the

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] hvm: Lower HPET frequency to 1/32 of the TSC.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 20 Mar 2007 09:50:18 -0700
Delivery-date: Tue, 20 Mar 2007 09:51:04 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1174312080 0
# Node ID 0611355e0df246070c7459f51106eda98447911e
# Parent  9b9aa9d6603b84b4c7d8095da5a70965b33949a6
hvm: Lower HPET frequency to 1/32 of the TSC.

The frequency of HPET device model is defined to be the same as TSC's,
but this doesn't work well with calibrate_tsc_hpet() in Linux kernel
2.6.16-33, causing some IA32 Linux HVM guests to failt o boot.

Calibrate_tsc_hpet() tries to figure out how many HPET ticks a TSC
cycle equals; it magnifies the result by scale of 2^32, trying to get
a more accurate result since it assumes the frequency of HPET in real
world is usually less than 1/100 of TSC, so the result of "(2^32 *
hpet_freq) / tsc_freq" may exceed 32bits, then a "divide error
(overflow)" would occur!

The result doesn't overflow every time because hpet_freq/tsc_freq may
less than 1.0 due to the little inaccuracy in the implementation of
HVM timer virtualization.

Signed-off-by: Dexuan Cui <dexuan.cui@xxxxxxxxx>
---
 xen/arch/x86/hvm/hpet.c |   24 +++++++++++++++---------
 1 files changed, 15 insertions(+), 9 deletions(-)

diff -r 9b9aa9d6603b -r 0611355e0df2 xen/arch/x86/hvm/hpet.c
--- a/xen/arch/x86/hvm/hpet.c   Mon Mar 19 13:44:31 2007 +0000
+++ b/xen/arch/x86/hvm/hpet.c   Mon Mar 19 13:48:00 2007 +0000
@@ -29,6 +29,10 @@
 #define S_TO_NS  1000000000ULL           /* 1s  = 10^9  ns */
 #define S_TO_FS  1000000000000000ULL     /* 1s  = 10^15 fs */
 
+/* Frequency_of_TSC / frequency_of_HPET = 32 */
+#define TSC_PER_HPET_TICK 32
+#define guest_time_hpet(v) (hvm_get_guest_time(v) / TSC_PER_HPET_TICK)
+
 #define HPET_ID         0x000
 #define HPET_PERIOD     0x004
 #define HPET_CFG        0x010
@@ -67,7 +71,9 @@
 #define HPET_TN_INT_ROUTE_CAP_MASK (0xffffffffULL \
                     << HPET_TN_INT_ROUTE_CAP_SHIFT)
 
-#define hpet_tick_to_ns(h, tick) ((s_time_t)(tick)*S_TO_NS/h->tsc_freq)
+#define hpet_tick_to_ns(h, tick) ((s_time_t)(tick)* \
+                                  (S_TO_NS*TSC_PER_HPET_TICK)/h->tsc_freq)
+
 #define timer_config(h, n)       (h->hpet.timers[n].config)
 #define timer_enabled(h, n)      (timer_config(h, n) & HPET_TN_ENABLE)
 #define timer_is_periodic(h, n)  (timer_config(h, n) & HPET_TN_PERIODIC)
@@ -108,7 +114,7 @@ static inline uint64_t hpet_read_maincou
 static inline uint64_t hpet_read_maincounter(HPETState *h)
 {
     if ( hpet_enabled(h) )
-        return hvm_get_guest_time(h->vcpu) + h->mc_offset;
+        return guest_time_hpet(h->vcpu) + h->mc_offset;
     else 
         return h->hpet.mc64;
 }
@@ -144,7 +150,7 @@ static void hpet_stop_timer(HPETState *h
 
 /* the number of HPET tick that stands for
  * 1/(2^10) second, namely, 0.9765625 milliseconds */
-#define  HPET_TINY_TIME_SPAN  (h->tsc_freq >> 10)
+#define  HPET_TINY_TIME_SPAN  ((h->tsc_freq >> 10) / TSC_PER_HPET_TICK)
 
 static void hpet_set_timer(HPETState *h, unsigned int tn)
 {
@@ -225,14 +231,14 @@ static void hpet_write(
         if ( !(old_val & HPET_CFG_ENABLE) && (new_val & HPET_CFG_ENABLE) )
         {
             /* Enable main counter and interrupt generation. */
-            h->mc_offset = h->hpet.mc64 - hvm_get_guest_time(h->vcpu);
+            h->mc_offset = h->hpet.mc64 - guest_time_hpet(h->vcpu);
             for ( i = 0; i < HPET_TIMER_NUM; i++ )
                 hpet_set_timer(h, i); 
         }
         else if ( (old_val & HPET_CFG_ENABLE) && !(new_val & HPET_CFG_ENABLE) )
         {
             /* Halt main counter and disable interrupt generation. */
-            h->hpet.mc64 = h->mc_offset + hvm_get_guest_time(h->vcpu);
+            h->hpet.mc64 = h->mc_offset + guest_time_hpet(h->vcpu);
             for ( i = 0; i < HPET_TIMER_NUM; i++ )
                 hpet_stop_timer(h, i);
         }
@@ -384,7 +390,7 @@ static int hpet_save(struct domain *d, h
     HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet;
 
     /* Write the proper value into the main counter */
-    hp->hpet.mc64 = hp->mc_offset + hvm_get_guest_time(hp->vcpu);
+    hp->hpet.mc64 = hp->mc_offset + guest_time_hpet(hp->vcpu);
 
     /* Save the HPET registers */
     return hvm_save_entry(HPET, 0, h, &hp->hpet);
@@ -400,7 +406,7 @@ static int hpet_load(struct domain *d, h
         return -EINVAL;
     
     /* Recalculate the offset between the main counter and guest time */
-    hp->mc_offset = hp->hpet.mc64 - hvm_get_guest_time(hp->vcpu);
+    hp->mc_offset = hp->hpet.mc64 - guest_time_hpet(hp->vcpu);
                 
     /* Restart the timers */
     for ( i = 0; i < HPET_TIMER_NUM; i++ )
@@ -425,8 +431,8 @@ void hpet_init(struct vcpu *v)
     h->hpet.capability = 0x8086A201ULL;
 
     /* This is the number of femptoseconds per HPET tick. */
-    /* Here we define HPET's frequency to be the same as the TSC's. */
-    h->hpet.capability |= ((S_TO_FS/h->tsc_freq) << 32);
+    /* Here we define HPET's frequency to be 1/32 of the TSC's */
+    h->hpet.capability |= ((S_TO_FS*TSC_PER_HPET_TICK/h->tsc_freq) << 32);
 
     for ( i = 0; i < HPET_TIMER_NUM; i++ )
     {

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] hvm: Lower HPET frequency to 1/32 of the TSC., Xen patchbot-unstable <=