diff options
author | hexin <hexin.op@gmail.com> | 2019-08-22 11:35:19 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-10-07 18:56:53 +0200 |
commit | 9b2d2f2ad0039fb8bb77993751cbf9eaaff223f0 (patch) | |
tree | 8720f3263a55b071a7ca4226f163b9ca67687090 /drivers/vfio | |
parent | c1f7b3fb87cf48e997bad6d5b8206c67953b5e54 (diff) | |
download | linux-stable-9b2d2f2ad0039fb8bb77993751cbf9eaaff223f0.tar.gz linux-stable-9b2d2f2ad0039fb8bb77993751cbf9eaaff223f0.tar.bz2 linux-stable-9b2d2f2ad0039fb8bb77993751cbf9eaaff223f0.zip |
vfio_pci: Restore original state on release
[ Upstream commit 92c8026854c25093946e0d7fe536fd9eac440f06 ]
vfio_pci_enable() saves the device's initial configuration information
with the intent that it is restored in vfio_pci_disable(). However,
the commit referenced in Fixes: below replaced the call to
__pci_reset_function_locked(), which is not wrapped in a state save
and restore, with pci_try_reset_function(), which overwrites the
restored device state with the current state before applying it to the
device. Reinstate use of __pci_reset_function_locked() to return to
the desired behavior.
Fixes: 890ed578df82 ("vfio-pci: Use pci "try" reset interface")
Signed-off-by: hexin <hexin15@baidu.com>
Signed-off-by: Liu Qi <liuqi16@baidu.com>
Signed-off-by: Zhang Yu <zhangyu31@baidu.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/vfio')
-rw-r--r-- | drivers/vfio/pci/vfio_pci.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 6cf00d9f512b..a92c2868d902 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -373,11 +373,20 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev) pci_write_config_word(pdev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE); /* - * Try to reset the device. The success of this is dependent on - * being able to lock the device, which is not always possible. + * Try to get the locks ourselves to prevent a deadlock. The + * success of this is dependent on being able to lock the device, + * which is not always possible. + * We can not use the "try" reset interface here, which will + * overwrite the previously restored configuration information. */ - if (vdev->reset_works && !pci_try_reset_function(pdev)) - vdev->needs_reset = false; + if (vdev->reset_works && pci_cfg_access_trylock(pdev)) { + if (device_trylock(&pdev->dev)) { + if (!__pci_reset_function_locked(pdev)) + vdev->needs_reset = false; + device_unlock(&pdev->dev); + } + pci_cfg_access_unlock(pdev); + } pci_restore_state(pdev); out: |