• Thomas Gleixner's avatar
    PCI/MSI: Protect msi_desc::masked for multi-MSI · 77e89afc
    Thomas Gleixner authored
    Multi-MSI uses a single MSI descriptor and there is a single mask register
    when the device supports per vector masking. To avoid reading back the mask
    register the value is cached in the MSI descriptor and updates are done by
    clearing and setting bits in the cache and writing it to the device.
    
    But nothing protects msi_desc::masked and the mask register from being
    modified concurrently on two different CPUs for two different Linux
    interrupts which belong to the same multi-MSI descriptor.
    
    Add a lock to struct device and protect any operation on the mask and the
    mask register with it.
    
    This makes the update of msi_desc::masked unconditional, but there is no
    place which requires a modification of the hardware register without
    updating the masked cache.
    
    msi_mask_irq() is now an empty wrapper which will be cleaned up in follow
    up changes.
    
    The problem goes way back to the initial support of multi-MSI, but picking
    the commit which introduced the mask cache is a valid cut off point
    (2.6.30).
    
    Fixes: f2440d9a ("PCI MSI: Refactor interrupt masking code")
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Tested-by: default avatarMarc Zyngier <maz@kernel.org>
    Reviewed-by: default avatarMarc Zyngier <maz@kernel.org>
    Cc: stable@vger.kernel.org
    Link: https://lore.kernel.org/r/20210729222542.726833414@linutronix.de
    77e89afc
msi.c 41.5 KB