diff mbox series

[2/2] viridian: fix mistakes in timer expiration and re-start

Message ID 20190318090700.1538-3-paul.durrant@citrix.com (mailing list archive)
State New, archived
Headers show
Series Follow-up viridian fixes | expand

Commit Message

Paul Durrant March 18, 2019, 9:07 a.m. UTC
This patch fixes a few issues:

- The specification says that a one-shot timers should be marked as
  disabled at the point of expiry, so the enabled bit should be cleared by
  stimer_expire() rather than poll_stimer(). For simplicity, call
  stimer_expire() from start_stimer() for timers that expire immediately
  rather than open-coding the expiry.

- The code omits updating the expiration value for one-shot timers and
  so the eventual message delivered via the synic will be incorrect.

- Periodic timers should only be re-started if they are still enabled so,
  now that enabled will be already clear for one-shot timers, call
  start_stimer() from poll_stimer() only if the timer is still enabled.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: "Roger Pau Monné" <roger.pau@citrix.com>
---
 xen/arch/x86/hvm/viridian/time.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/xen/arch/x86/hvm/viridian/time.c b/xen/arch/x86/hvm/viridian/time.c
index 7a759e70b3..692f014fc4 100644
--- a/xen/arch/x86/hvm/viridian/time.c
+++ b/xen/arch/x86/hvm/viridian/time.c
@@ -187,7 +187,7 @@  static void stop_stimer(struct viridian_stimer *vs)
 
 static void stimer_expire(void *data)
 {
-    const struct viridian_stimer *vs = data;
+    struct viridian_stimer *vs = data;
     struct vcpu *v = vs->v;
     struct viridian_vcpu *vv = v->arch.hvm.viridian;
     unsigned int stimerx = vs - &vv->stimer[0];
@@ -197,6 +197,9 @@  static void stimer_expire(void *data)
 
     set_bit(stimerx, &vv->stimer_pending);
     vcpu_kick(v);
+
+    if ( !vs->config.periodic )
+        vs->config.enabled = 0;
 }
 
 static void start_stimer(struct viridian_stimer *vs)
@@ -256,7 +259,8 @@  static void start_stimer(struct viridian_stimer *vs)
         expiration = vs->count;
         if ( expiration - now <= 0 )
         {
-            set_bit(stimerx, &vv->stimer_pending);
+            vs->expiration = expiration;
+            stimer_expire(vs);
             return;
         }
     }
@@ -285,10 +289,8 @@  static void poll_stimer(struct vcpu *v, unsigned int stimerx)
 
     clear_bit(stimerx, &vv->stimer_pending);
 
-    if ( vs->config.periodic )
+    if ( vs->config.enabled )
         start_stimer(vs);
-    else
-        vs->config.enabled = 0;
 }
 
 void viridian_time_poll_timers(struct vcpu *v)