Commit ba69ce76 authored by Keir Fraser's avatar Keir Fraser

[Mini-OS] Make sure schedule() is called safely

If a thread tries to sleep from a callback or with callbacks disabled,
Mini-OS will completely lock, so make sure this never happens.
Signed-off-by: default avatarSamuel Thibault <samuel.thibault@citrix.com>
parent 5b64dd07
......@@ -33,6 +33,8 @@
((sh)->evtchn_pending[idx] & \
~(sh)->evtchn_mask[idx])
int in_callback;
void do_hypervisor_callback(struct pt_regs *regs)
{
unsigned long l1, l2, l1i, l2i;
......@@ -41,6 +43,7 @@ void do_hypervisor_callback(struct pt_regs *regs)
shared_info_t *s = HYPERVISOR_shared_info;
vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
in_callback = 1;
vcpu_info->evtchn_upcall_pending = 0;
/* NB. No need for a barrier here -- XCHG is a barrier on x86. */
......@@ -59,6 +62,8 @@ void do_hypervisor_callback(struct pt_regs *regs)
do_event(port, regs);
}
}
in_callback = 0;
}
......
......@@ -42,4 +42,6 @@ void mask_evtchn(u32 port);
void unmask_evtchn(u32 port);
void clear_evtchn(u32 port);
extern int in_callback;
#endif /* __HYPERVISOR_H__ */
......@@ -125,6 +125,14 @@ void schedule(void)
unsigned long flags;
prev = current;
local_irq_save(flags);
if (in_callback) {
printk("Must not call schedule() from a callback\n");
BUG();
}
if (flags) {
printk("Must not call schedule() with IRQs disabled\n");
BUG();
}
list_for_each(iterator, &exited_threads)
{
thread = list_entry(iterator, struct thread, thread_list);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment