diff options
author | Igor Mammedov <imammedo@redhat.com> | 2011-10-03 16:35:03 +0100 |
---|---|---|
committer | Igor Mammedov <imammedo@redhat.com> | 2011-10-03 16:35:03 +0100 |
commit | 853368fb06f61c01d5646b20d3f78e76be475a55 (patch) | |
tree | 50c0a7ef3d23b293d130a328d58eaf96be6d648b | |
parent | 5734ae43b40794262320f139b0d94136ff72b3df (diff) | |
download | xen-853368fb06f61c01d5646b20d3f78e76be475a55.tar.gz xen-853368fb06f61c01d5646b20d3f78e76be475a55.tar.bz2 xen-853368fb06f61c01d5646b20d3f78e76be475a55.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.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 60cb65d121..bf0bcf68de 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -154,6 +154,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; @@ -1277,8 +1278,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; @@ -1289,6 +1288,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); |