[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-3.1-testing] hvm: hpet: Clamp period to sane values to prevent excessive looping in



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1199965211 0
# Node ID f9ac2ee4d2364f917745d807a72d54292051a820
# Parent  05e63f05ece02a4dcd0377b2229fbc76fb14e786
hvm: hpet: Clamp period to sane values to prevent excessive looping in
hpet_timer_fn(), or excessive numbers of set_timer() callbacks.
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
xen-unstable changeset:   16697:1b2be7cf0b7b4b639b7d6f027545930021ebe1e0
xen-unstable date:        Wed Jan 09 10:32:13 2008 +0000
---
 xen/arch/x86/hvm/hpet.c |   26 +++++++++++++++++++-------
 1 files changed, 19 insertions(+), 7 deletions(-)

diff -r 05e63f05ece0 -r f9ac2ee4d236 xen/arch/x86/hvm/hpet.c
--- a/xen/arch/x86/hvm/hpet.c   Thu Jan 10 11:39:23 2008 +0000
+++ b/xen/arch/x86/hvm/hpet.c   Thu Jan 10 11:40:11 2008 +0000
@@ -278,7 +278,10 @@ static void hpet_write(
         }
 
         if ( new_val & HPET_TN_32BIT )
+        {
             h->hpet.timers[tn].cmp = (uint32_t)h->hpet.timers[tn].cmp;
+            h->hpet.period[tn] = (uint32_t)h->hpet.period[tn];
+        }
 
         break;
 
@@ -292,7 +295,17 @@ static void hpet_write(
              (h->hpet.timers[tn].config & HPET_TN_SETVAL) )
             h->hpet.timers[tn].cmp = new_val;
         else
+        {
+            /*
+             * Clamp period to reasonable min/max values:
+             *  - minimum is 900us, same as timers controlled by vpt.c
+             *  - maximum is to prevent overflow in time_after() calculations
+             */
+            if ( hpet_tick_to_ns(h, new_val) < MICROSECS(900) )
+                new_val = (MICROSECS(900) << 10) / h->hpet_to_ns_scale;
+            new_val &= (timer_is_32bit(h, tn) ? ~0u : ~0ull) >> 1;
             h->hpet.period[tn] = new_val;
+        }
         h->hpet.timers[tn].config &= ~HPET_TN_SETVAL;
         if ( hpet_enabled(h) )
             hpet_set_timer(h, tn);
@@ -351,7 +364,7 @@ static void hpet_route_interrupt(HPETSta
         return;
     }
 
-    /* We only support edge-triggered interrupt now  */
+    /* We support only edge-triggered interrupt. */
     spin_lock(&d->arch.hvm_domain.irq_lock);
     vioapic_irq_positive_edge(d, tn_int_route);
     spin_unlock(&d->arch.hvm_domain.irq_lock);
@@ -376,20 +389,19 @@ static void hpet_timer_fn(void *opaque)
 
     if ( timer_is_periodic(h, tn) && (h->hpet.period[tn] != 0) )
     {
-        uint64_t mc = hpet_read_maincounter(h);
+        uint64_t mc = hpet_read_maincounter(h), period = h->hpet.period[tn];
         if ( timer_is_32bit(h, tn) )
         {
             while ( hpet_time_after(mc, h->hpet.timers[tn].cmp) )
                 h->hpet.timers[tn].cmp = (uint32_t)(
-                    h->hpet.timers[tn].cmp + h->hpet.period[tn]);
+                    h->hpet.timers[tn].cmp + period);
         }
         else
         {
             while ( hpet_time_after64(mc, h->hpet.timers[tn].cmp) )
-                h->hpet.timers[tn].cmp += h->hpet.period[tn];
-        }
-        set_timer(&h->timers[tn], 
-                  NOW() + hpet_tick_to_ns(h, h->hpet.period[tn]));
+                h->hpet.timers[tn].cmp += period;
+        }
+        set_timer(&h->timers[tn], NOW() + hpet_tick_to_ns(h, period));
     }
 
     spin_unlock(&h->lock);

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.