mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-06 05:02:31 +00:00
Merge branches 'v5.18/vfio/next/mlx5-migration-v10', 'v5.18/vfio/next/pm-fixes' and 'v5.18/vfio/next/uml-build-fix' into v5.18/vfio/next/next
This commit is contained in:
commit
f8a665b159
@ -228,6 +228,19 @@ int vfio_pci_set_power_state(struct vfio_pci_core_device *vdev, pci_power_t stat
|
||||
if (!ret) {
|
||||
/* D3 might be unsupported via quirk, skip unless in D3 */
|
||||
if (needs_save && pdev->current_state >= PCI_D3hot) {
|
||||
/*
|
||||
* The current PCI state will be saved locally in
|
||||
* 'pm_save' during the D3hot transition. When the
|
||||
* device state is changed to D0 again with the current
|
||||
* function, then pci_store_saved_state() will restore
|
||||
* the state and will free the memory pointed by
|
||||
* 'pm_save'. There are few cases where the PCI power
|
||||
* state can be changed to D0 without the involvement
|
||||
* of the driver. For these cases, free the earlier
|
||||
* allocated memory first before overwriting 'pm_save'
|
||||
* to prevent the memory leak.
|
||||
*/
|
||||
kfree(vdev->pm_save);
|
||||
vdev->pm_save = pci_store_saved_state(pdev);
|
||||
} else if (needs_restore) {
|
||||
pci_load_and_free_saved_state(pdev, &vdev->pm_save);
|
||||
@ -322,6 +335,17 @@ void vfio_pci_core_disable(struct vfio_pci_core_device *vdev)
|
||||
/* For needs_reset */
|
||||
lockdep_assert_held(&vdev->vdev.dev_set->lock);
|
||||
|
||||
/*
|
||||
* This function can be invoked while the power state is non-D0.
|
||||
* This function calls __pci_reset_function_locked() which internally
|
||||
* can use pci_pm_reset() for the function reset. pci_pm_reset() will
|
||||
* fail if the power state is non-D0. Also, for the devices which
|
||||
* have NoSoftRst-, the reset function can cause the PCI config space
|
||||
* reset without restoring the original state (saved locally in
|
||||
* 'vdev->pm_save').
|
||||
*/
|
||||
vfio_pci_set_power_state(vdev, PCI_D0);
|
||||
|
||||
/* Stop the device from further DMA */
|
||||
pci_clear_master(pdev);
|
||||
|
||||
@ -921,6 +945,19 @@ long vfio_pci_core_ioctl(struct vfio_device *core_vdev, unsigned int cmd,
|
||||
return -EINVAL;
|
||||
|
||||
vfio_pci_zap_and_down_write_memory_lock(vdev);
|
||||
|
||||
/*
|
||||
* This function can be invoked while the power state is non-D0.
|
||||
* If pci_try_reset_function() has been called while the power
|
||||
* state is non-D0, then pci_try_reset_function() will
|
||||
* internally set the power state to D0 without vfio driver
|
||||
* involvement. For the devices which have NoSoftRst-, the
|
||||
* reset function can cause the PCI config space reset without
|
||||
* restoring the original state (saved locally in
|
||||
* 'vdev->pm_save').
|
||||
*/
|
||||
vfio_pci_set_power_state(vdev, PCI_D0);
|
||||
|
||||
ret = pci_try_reset_function(vdev->pdev);
|
||||
up_write(&vdev->memory_lock);
|
||||
|
||||
@ -2036,6 +2073,18 @@ static int vfio_pci_dev_set_hot_reset(struct vfio_device_set *dev_set,
|
||||
}
|
||||
cur_mem = NULL;
|
||||
|
||||
/*
|
||||
* The pci_reset_bus() will reset all the devices in the bus.
|
||||
* The power state can be non-D0 for some of the devices in the bus.
|
||||
* For these devices, the pci_reset_bus() will internally set
|
||||
* the power state to D0 without vfio driver involvement.
|
||||
* For the devices which have NoSoftRst-, the reset function can
|
||||
* cause the PCI config space reset without restoring the original
|
||||
* state (saved locally in 'vdev->pm_save').
|
||||
*/
|
||||
list_for_each_entry(cur, &dev_set->device_list, vdev.dev_set_list)
|
||||
vfio_pci_set_power_state(cur, PCI_D0);
|
||||
|
||||
ret = pci_reset_bus(pdev);
|
||||
|
||||
err_undo:
|
||||
@ -2089,6 +2138,18 @@ static bool vfio_pci_dev_set_try_reset(struct vfio_device_set *dev_set)
|
||||
if (!pdev)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* The pci_reset_bus() will reset all the devices in the bus.
|
||||
* The power state can be non-D0 for some of the devices in the bus.
|
||||
* For these devices, the pci_reset_bus() will internally set
|
||||
* the power state to D0 without vfio driver involvement.
|
||||
* For the devices which have NoSoftRst-, the reset function can
|
||||
* cause the PCI config space reset without restoring the original
|
||||
* state (saved locally in 'vdev->pm_save').
|
||||
*/
|
||||
list_for_each_entry(cur, &dev_set->device_list, vdev.dev_set_list)
|
||||
vfio_pci_set_power_state(cur, PCI_D0);
|
||||
|
||||
ret = pci_reset_bus(pdev);
|
||||
if (ret)
|
||||
return false;
|
||||
|
@ -288,6 +288,7 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf,
|
||||
return done;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VFIO_PCI_VGA
|
||||
ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev, char __user *buf,
|
||||
size_t count, loff_t *ppos, bool iswrite)
|
||||
{
|
||||
@ -355,6 +356,7 @@ ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev, char __user *buf,
|
||||
|
||||
return done;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void vfio_pci_ioeventfd_do_write(struct vfio_pci_ioeventfd *ioeventfd,
|
||||
bool test_mem)
|
||||
|
@ -159,8 +159,17 @@ extern ssize_t vfio_pci_config_rw(struct vfio_pci_core_device *vdev,
|
||||
extern ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf,
|
||||
size_t count, loff_t *ppos, bool iswrite);
|
||||
|
||||
#ifdef CONFIG_VFIO_PCI_VGA
|
||||
extern ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev, char __user *buf,
|
||||
size_t count, loff_t *ppos, bool iswrite);
|
||||
#else
|
||||
static inline ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev,
|
||||
char __user *buf, size_t count,
|
||||
loff_t *ppos, bool iswrite)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern long vfio_pci_ioeventfd(struct vfio_pci_core_device *vdev, loff_t offset,
|
||||
uint64_t data, int count, int fd);
|
||||
|
Loading…
Reference in New Issue
Block a user