]> xenbits.xensource.com Git - people/vhanquez/xen-unstable.git/commitdiff
x86: prevent call to xfree() in dump_irqs() while in an irq context
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 22 May 2012 14:28:45 +0000 (16:28 +0200)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 22 May 2012 14:28:45 +0000 (16:28 +0200)
Because of c/s 24707:96987c324a4f, dump_irqs() can now be called in an
irq context when a bug condition is encountered. If this is the case,
ignore the call to xsm_show_irq_ssid() and the subsequent call to
xfree().

This prevents an assertion failure in xfree(), and should allow all the
debug information to be dumped, before failing with a BUG() because of
the underlying race condition we are attempting to reproduce.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Rather than using the non-obvious conditional around an xfree() that
would be passed NULL only in the inverse case (which could easily get
removed by a future change on the basis that calling xfree(NULL) is
benign), switch the order of checks in xfree() itself and only suppress
the call to XSM that could potentially call xmalloc().

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
Committed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/irq.c
xen/common/xmalloc_tlsf.c

index 496c8048ae6349ec43b3bb5aa6575e89294f2efa..78a02e32900d71a6b0aaeb2b2112bd5cda30a138 100644 (file)
@@ -2060,7 +2060,7 @@ static void dump_irqs(unsigned char key)
         if ( !irq_desc_initialized(desc) || desc->handler == &no_irq_type )
             continue;
 
-        ssid = xsm_show_irq_sid(irq);
+        ssid = in_irq() ? NULL : xsm_show_irq_sid(irq);
 
         spin_lock_irqsave(&desc->lock, flags);
 
index 3235af117c868deaab0909bb484aad0a31732ba3..fa7c8b8165a830f2e733d4018487761350cc5d75 100644 (file)
@@ -604,11 +604,11 @@ void xfree(void *p)
 {
     struct bhdr *b;
 
-    ASSERT(!in_irq());
-
     if ( p == NULL )
         return;
 
+    ASSERT(!in_irq());
+
     /* Strip alignment padding. */
     b = (struct bhdr *)((char *) p - BHDR_OVERHEAD);
     if ( b->size & 1 )