|
|
|
|
|
|
|
|
|
|
xen-changelog
[Xen-changelog] Fix context_switch(). It is necessary to set_current() a
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 0ba3b9d60da65bcb9a14122c8b17c255354db764
# Parent 8af1199488d3636135f3adf3f7302d4a04e9004e
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@xxxxxxxxxxxxx>
diff -r 8af1199488d3 -r 0ba3b9d60da6 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Mon Jan 9 11:22:17 2006
+++ b/xen/arch/x86/domain.c Mon Jan 9 11:25:05 2006
@@ -689,6 +689,9 @@
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 @@
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) )
- {
- /* 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();
+ if ( (percpu_ctxt[cpu].curr_vcpu == next) || is_idle_domain(next->domain) )
+ {
+ local_irq_enable();
+ }
+ else
+ {
__context_switch();
+
+ /* Re-enable interrupts before restoring state which may fault. */
local_irq_enable();
if ( VMX_DOMAIN(next) )
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|
<Prev in Thread] |
Current Thread |
[Next in Thread> |
- [Xen-changelog] Fix context_switch(). It is necessary to set_current() and,
Xen patchbot -unstable <=
|
|
|
|
|