aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor Mammedov <imammedo@redhat.com>2011-10-03 16:29:52 +0100
committerIgor Mammedov <imammedo@redhat.com>2011-10-03 16:29:52 +0100
commit2699490e04c9e44d67cd242f8da5943a3c40e26e (patch)
tree0974feffe968952377fd049a8fb9bba14234ba34
parentf0fa8aa75a4b93e3f465100b970d73ef44fbe34f (diff)
downloadxen-2699490e04c9e44d67cd242f8da5943a3c40e26e.tar.gz
xen-2699490e04c9e44d67cd242f8da5943a3c40e26e.tar.bz2
xen-2699490e04c9e44d67cd242f8da5943a3c40e26e.zip
Clear IRQ_GUEST in irq_desc->status when setting action to NULL.
Looking more closely at usage of action field with relation to IRQ_GUEST flag. It appears that set IRQ_GUEST implies that action is not NULL. As result it is not safe to set action to NULL and leave IRQ_GUEST set. Hence IRQ_GUEST should be cleared in dynamic_irq_cleanup where action is set to NULL. An addition remove BUGON at __pirq_guest_unbind that appears to be bogus and not needed anymore. Thanks Paolo Bonzini for NACKing previous patch, and pointing at the correct solution. Signed-off-by: Igor Mammedov <imammedo@redhat.com> Reinstate the BUG_ON, but after the action==NULL check. Since we then go and start interpreting action as an irq_guest_action_t, the BUG_ON is relevant here. More generally, the brute-force nature of dynamic_irq_cleanup() looks a bit worrying. Possibly there should be more integratioin with pirq_guest_unbind() logic, for cleaning up un-acked EOIs and the like. Signed-off-by: Keir Fraser <keir@xen.org> xen-unstable changeset: 23852:c944e82bb092 xen-unstable date: Sun Sep 18 00:00:26 2011 +0100
-rw-r--r--xen/arch/x86/irq.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 142894688d..f1ae8400b5 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -152,6 +152,7 @@ static void dynamic_irq_cleanup(unsigned int irq)
spin_lock_irqsave(&desc->lock, flags);
desc->status |= IRQ_DISABLED;
+ desc->status &= ~IRQ_GUEST;
desc->handler->shutdown(irq);
action = desc->action;
desc->action = NULL;
@@ -1288,8 +1289,6 @@ static irq_guest_action_t *__pirq_guest_unbind(
cpumask_t cpu_eoi_map;
int i;
- BUG_ON(!(desc->status & IRQ_GUEST));
-
action = (irq_guest_action_t *)desc->action;
irq = desc - irq_desc;
@@ -1300,6 +1299,8 @@ static irq_guest_action_t *__pirq_guest_unbind(
return NULL;
}
+ BUG_ON(!(desc->status & IRQ_GUEST));
+
for ( i = 0; (i < action->nr_guests) && (action->guest[i] != d); i++ )
continue;
BUG_ON(i == action->nr_guests);