• Dexuan Cui's avatar
    PCI: hv: Fix a race condition in hv_irq_unmask() that can cause panic · 2738d5ab
    Dexuan Cui authored
    When the host tries to remove a PCI device, the host first sends a
    PCI_EJECT message to the guest, and the guest is supposed to gracefully
    remove the PCI device and send a PCI_EJECTION_COMPLETE message to the host;
    the host then sends a VMBus message CHANNELMSG_RESCIND_CHANNELOFFER to
    the guest (when the guest receives this message, the device is already
    unassigned from the guest) and the guest can do some final cleanup work;
    if the guest fails to respond to the PCI_EJECT message within one minute,
    the host sends the VMBus message CHANNELMSG_RESCIND_CHANNELOFFER and
    removes the PCI device forcibly.
    
    In the case of fast device addition/removal, it's possible that the PCI
    device driver is still configuring MSI-X interrupts when the guest receives
    the PCI_EJECT message; the channel callback calls hv_pci_eject_device(),
    which sets hpdev->state to hv_pcichild_ejecting, and schedules a work
    hv_eject_device_work(); if the PCI device driver is calling
    pci_alloc_irq_vectors() -> ... -> hv_compose_msi_msg(), we can break the
    while loop in hv_compose_msi_msg() due to the updated hpdev->state, and
    leave data->chip_data with its default value of NULL; later, when the PCI
    device driver calls request_irq() -> ... -> hv_irq_unmask(), the guest
    crashes in hv_arch_irq_unmask() due to data->chip_data being NULL.
    
    Fix the issue by not testing hpdev->state in the while loop: when the
    guest receives PCI_EJECT, the device is still assigned to the guest, and
    the guest has one minute to finish the device removal gracefully. We don't
    really need to (and we should not) test hpdev->state in the loop.
    
    Fixes: de0aa7b2 ("PCI: hv: Fix 2 hang issues in hv_compose_msi_msg()")
    Signed-off-by: default avatarDexuan Cui <decui@microsoft.com>
    Reviewed-by: default avatarMichael Kelley <mikelley@microsoft.com>
    Cc: stable@vger.kernel.org
    Link: https://lore.kernel.org/r/20230615044451.5580-3-decui@microsoft.comSigned-off-by: default avatarWei Liu <wei.liu@kernel.org>
    2738d5ab
pci-hyperv.c 114 KB