• Andrew Lunn's avatar
    There is a race condition in um_request_irq(). The SIGIO handling is · 356968d7
    Andrew Lunn authored
    first enabled with the call to activate_fd().  The irq handler is then
    registered with request_irq().  What can happen is that directly after
    activate_fd() the SIGIO goes off and the IRQ source is disabled at the low
    level, the pollfd is set to -1.  Since no irq handler has yet been
    registered, the interrupt it left disabled at the low level.  The
    interrupt handler is then registered, but its too late, the interrupt
    source has been disabled at the lower level and is never re-enabled.  To
    fix this race condition i swapped the order.  First request_irq() then
    activate_fd() the interrupt sources.
    
    There is a second bug.  In 2.6.31 there was a change to the way __do_IRQ()
    and friends work for chained interrupt sources.  The old way was that all
    chained interrupt handlers were called.  The new way is that the chain is
    walked only until a handler returns IRQ_HANDLED or IRQ_WAKE_THREAD. 
    uml_net_interrupt() would always return IRQ_HANDLED, irrespective of if
    the device really did receive an interrupt or not.  This mean with the new
    code only the first device on a chained interrupt ever got its interrupts
    handled.  The second/third/...  device never got any interrupts processed.
     I changed uml_net_interrupt() to always return IRQ_NONE so that all
    handlers get called on a chained interrupt.
    Signed-off-by: default avatarAndrew Lunn <andrew@lunn.ch>
    Cc: Jeff Dike <jdike@addtoit.com>
    Cc: Alexey Dobriyan <adobriyan@gmail.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Ingo Molnar <mingo@elte.hu>
    Cc: Yinghai Lu <yinghai@kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    356968d7
net_kern.c 20.1 KB