• Boris Ostrovsky's avatar
    xen/events: Mask a moving irq · d1985623
    Boris Ostrovsky authored
    commit ff1e22e7 upstream.
    
    Moving an unmasked irq may result in irq handler being invoked on both
    source and target CPUs.
    
    With 2-level this can happen as follows:
    
    On source CPU:
            evtchn_2l_handle_events() ->
                generic_handle_irq() ->
                    handle_edge_irq() ->
                       eoi_pirq():
                           irq_move_irq(data);
    
                           /***** WE ARE HERE *****/
    
                           if (VALID_EVTCHN(evtchn))
                               clear_evtchn(evtchn);
    
    If at this moment target processor is handling an unrelated event in
    evtchn_2l_handle_events()'s loop it may pick up our event since target's
    cpu_evtchn_mask claims that this event belongs to it *and* the event is
    unmasked and still pending. At the same time, source CPU will continue
    executing its own handle_edge_irq().
    
    With FIFO interrupt the scenario is similar: irq_move_irq() may result
    in a EVTCHNOP_unmask hypercall which, in turn, may make the event
    pending on the target CPU.
    
    We can avoid this situation by moving and clearing the event while
    keeping event masked.
    Signed-off-by: default avatarBoris Ostrovsky <boris.ostrovsky@oracle.com>
    Signed-off-by: default avatarDavid Vrabel <david.vrabel@citrix.com>
    Signed-off-by: default avatarKamal Mostafa <kamal@canonical.com>
    d1985623
events_base.c 37.9 KB