@@ -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)
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(-)