Fix context_switch(). It is necessary to set_current() and

then check curr_vcpu all with interrupts disabled. This in
turn requires us to hoist the heck of next's vcpu_dirty_cpumask
as sending the flush IPI needs us to have interrupts enabled to
avoid deadlock.

Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2006-01-09 12:25:05 +01:00
1 parent 1676162e17
commit 89e23317ba
1 file changed
+21 -11
+21 -11
View File
@@ -689,6 +689,9 @@ static void __context_switch(void)
struct vcpu *p = percpu_ctxt[cpu].curr_vcpu;
struct vcpu *n = current;
ASSERT(p != n);
ASSERT(cpus_empty(n->vcpu_dirty_cpumask));
if ( !is_idle_domain(p->domain) )
{
memcpy(&p->arch.guest_context.user_regs,
@@ -748,24 +751,31 @@ static void __context_switch(void)
void context_switch(struct vcpu *prev, struct vcpu *next)
{
unsigned int cpu = smp_processor_id();
cpumask_t dirty_mask = next->vcpu_dirty_cpumask;
ASSERT(local_irq_is_enabled());
/* Allow at most one CPU at a time to be dirty. */
ASSERT(cpus_weight(dirty_mask) <= 1);
if ( unlikely(!cpu_isset(cpu, dirty_mask) && !cpus_empty(dirty_mask)) )
{
/* Other cpus call __sync_lazy_execstate from flush ipi handler. */
flush_tlb_mask(dirty_mask);
}
local_irq_disable();
set_current(next);
if ( (percpu_ctxt[cpu].curr_vcpu != next) &&
!is_idle_domain(next->domain) )
if ( (percpu_ctxt[cpu].curr_vcpu == next) || is_idle_domain(next->domain) )
{
local_irq_enable();
}
else
{
/* This may happen if next has been migrated by the scheduler. */
if ( unlikely(!cpus_empty(next->vcpu_dirty_cpumask)) )
{
ASSERT(!cpu_isset(cpu, next->vcpu_dirty_cpumask));
sync_vcpu_execstate(next);
ASSERT(cpus_empty(next->vcpu_dirty_cpumask));
}
local_irq_disable();
__context_switch();
/* Re-enable interrupts before restoring state which may fault. */
local_irq_enable();
if ( VMX_DOMAIN(next) )
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.