Must always send VIRQ_TIMER to a blocked guest.
Signed-off-by: Keir Fraser <keir.fraser@cl.cam.ac.uk>
spin_unlock(&d->time_lock);
}
-void update_dom_time(struct exec_domain *ed)
+int update_dom_time(struct exec_domain *ed)
{
unsigned long flags;
- if ( ed->domain->shared_info->tsc_timestamp != full_tsc_irq )
- {
- read_lock_irqsave(&time_lock, flags);
- __update_dom_time(ed);
- read_unlock_irqrestore(&time_lock, flags);
- send_guest_virq(ed, VIRQ_TIMER);
- }
+ if ( ed->domain->shared_info->tsc_timestamp == full_tsc_irq )
+ return 0;
+
+ read_lock_irqsave(&time_lock, flags);
+ __update_dom_time(ed);
+ read_unlock_irqrestore(&time_lock, flags);
+
+ return 1;
}
/* Set clock to <secs,usecs> after 00:00:00 UTC, 1 January, 1970. */
clear_bit(EDF_RUNNING, &prev->ed_flags);
/* Ensure that the domain has an up-to-date time base. */
- if ( !is_idle_task(next->domain) )
- update_dom_time(next);
+ if ( !is_idle_task(next->domain) && update_dom_time(next) )
+ send_guest_virq(next, VIRQ_TIMER);
schedule_tail(next);
TRACE_0D(TRC_SCHED_T_TIMER_FN);
- if ( !is_idle_task(ed->domain) )
- update_dom_time(ed);
+ if ( !is_idle_task(ed->domain) && update_dom_time(ed) )
+ send_guest_virq(ed, VIRQ_TIMER);
t_timer[ed->processor].expires = NOW() + MILLISECS(10);
add_ac_timer(&t_timer[ed->processor]);
struct exec_domain *ed = (struct exec_domain *)data;
TRACE_0D(TRC_SCHED_DOM_TIMER_FN);
- update_dom_time(ed);
+ (void)update_dom_time(ed);
+ send_guest_virq(ed, VIRQ_TIMER);
}
/* Initialise the data structures. */
#define MILLISECS(_ms) (((s_time_t)(_ms)) * 1000000ULL )
#define MICROSECS(_us) (((s_time_t)(_us)) * 1000ULL )
-extern void update_dom_time(struct exec_domain *ed);
+extern int update_dom_time(struct exec_domain *ed);
extern void do_settime(unsigned long secs, unsigned long usecs,
u64 system_time_base);