Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+72
+61
drivers/vfio/pci/vfio_pci_core.c
··· 228 228 if (!ret) { 229 229 /* D3 might be unsupported via quirk, skip unless in D3 */ 230 230 if (needs_save && pdev->current_state >= PCI_D3hot) { 231 + /* 232 + * The current PCI state will be saved locally in 233 + * 'pm_save' during the D3hot transition. When the 234 + * device state is changed to D0 again with the current 235 + * function, then pci_store_saved_state() will restore 236 + * the state and will free the memory pointed by 237 + * 'pm_save'. There are few cases where the PCI power 238 + * state can be changed to D0 without the involvement 239 + * of the driver. For these cases, free the earlier 240 + * allocated memory first before overwriting 'pm_save' 241 + * to prevent the memory leak. 242 + */ 243 + kfree(vdev->pm_save); 231 244 vdev->pm_save = pci_store_saved_state(pdev); 232 245 } else if (needs_restore) { 233 246 pci_load_and_free_saved_state(pdev, &vdev->pm_save); ··· 334 321 335 322 /* For needs_reset */ 336 323 lockdep_assert_held(&vdev->vdev.dev_set->lock); 324 + 325 + /* 326 + * This function can be invoked while the power state is non-D0. 327 + * This function calls __pci_reset_function_locked() which internally 328 + * can use pci_pm_reset() for the function reset. pci_pm_reset() will 329 + * fail if the power state is non-D0. Also, for the devices which 330 + * have NoSoftRst-, the reset function can cause the PCI config space 331 + * reset without restoring the original state (saved locally in 332 + * 'vdev->pm_save'). 333 + */ 334 + vfio_pci_set_power_state(vdev, PCI_D0); 337 335 338 336 /* Stop the device from further DMA */ 339 337 pci_clear_master(pdev); ··· 945 921 return -EINVAL; 946 922 947 923 vfio_pci_zap_and_down_write_memory_lock(vdev); 924 + 925 + /* 926 + * This function can be invoked while the power state is non-D0. 927 + * If pci_try_reset_function() has been called while the power 928 + * state is non-D0, then pci_try_reset_function() will 929 + * internally set the power state to D0 without vfio driver 930 + * involvement. For the devices which have NoSoftRst-, the 931 + * reset function can cause the PCI config space reset without 932 + * restoring the original state (saved locally in 933 + * 'vdev->pm_save'). 934 + */ 935 + vfio_pci_set_power_state(vdev, PCI_D0); 936 + 948 937 ret = pci_try_reset_function(vdev->pdev); 949 938 up_write(&vdev->memory_lock); 950 939 ··· 2073 2036 } 2074 2037 cur_mem = NULL; 2075 2038 2039 + /* 2040 + * The pci_reset_bus() will reset all the devices in the bus. 2041 + * The power state can be non-D0 for some of the devices in the bus. 2042 + * For these devices, the pci_reset_bus() will internally set 2043 + * the power state to D0 without vfio driver involvement. 2044 + * For the devices which have NoSoftRst-, the reset function can 2045 + * cause the PCI config space reset without restoring the original 2046 + * state (saved locally in 'vdev->pm_save'). 2047 + */ 2048 + list_for_each_entry(cur, &dev_set->device_list, vdev.dev_set_list) 2049 + vfio_pci_set_power_state(cur, PCI_D0); 2050 + 2076 2051 ret = pci_reset_bus(pdev); 2077 2052 2078 2053 err_undo: ··· 2137 2088 pdev = vfio_pci_dev_set_resettable(dev_set); 2138 2089 if (!pdev) 2139 2090 return false; 2091 + 2092 + /* 2093 + * The pci_reset_bus() will reset all the devices in the bus. 2094 + * The power state can be non-D0 for some of the devices in the bus. 2095 + * For these devices, the pci_reset_bus() will internally set 2096 + * the power state to D0 without vfio driver involvement. 2097 + * For the devices which have NoSoftRst-, the reset function can 2098 + * cause the PCI config space reset without restoring the original 2099 + * state (saved locally in 'vdev->pm_save'). 2100 + */ 2101 + list_for_each_entry(cur, &dev_set->device_list, vdev.dev_set_list) 2102 + vfio_pci_set_power_state(cur, PCI_D0); 2140 2103 2141 2104 ret = pci_reset_bus(pdev); 2142 2105 if (ret)
+2
drivers/vfio/pci/vfio_pci_rdwr.c
··· 288 288 return done; 289 289 } 290 290 291 + #ifdef CONFIG_VFIO_PCI_VGA 291 292 ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev, char __user *buf, 292 293 size_t count, loff_t *ppos, bool iswrite) 293 294 { ··· 356 355 357 356 return done; 358 357 } 358 + #endif 359 359 360 360 static void vfio_pci_ioeventfd_do_write(struct vfio_pci_ioeventfd *ioeventfd, 361 361 bool test_mem)
+9
include/linux/vfio_pci_core.h
··· 159 159 extern ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf, 160 160 size_t count, loff_t *ppos, bool iswrite); 161 161 162 + #ifdef CONFIG_VFIO_PCI_VGA 162 163 extern ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev, char __user *buf, 163 164 size_t count, loff_t *ppos, bool iswrite); 165 + #else 166 + static inline ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev, 167 + char __user *buf, size_t count, 168 + loff_t *ppos, bool iswrite) 169 + { 170 + return -EINVAL; 171 + } 172 + #endif 164 173 165 174 extern long vfio_pci_ioeventfd(struct vfio_pci_core_device *vdev, loff_t offset, 166 175 uint64_t data, int count, int fd);