qemu vfio-pci: Move devices to D0 on reset
PATCH 1/1 qemu vfio-pci: Move devices to D0 on reset
Guests may leave devices in a low power state at reboot, but we expect devices to be woken up for the next boot. Make this happen.
Signed-off-by Alex Williamson <[email protected]>
--- hw/vfio_pci.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
hw/vfio_pci.c +23 -0
@@ -161,6 +161,7 @@ typedef struct VFIODevice {#define VFIO_FEATURE_ENABLE_VGA_BIT 0#define VFIO_FEATURE_ENABLE_VGA (1 << VFIO_FEATURE_ENABLE_VGA_BIT)uint8_t bustype; +uint8_t pm_cap;bool reset_works;bool has_vga; } VFIODevice;
@@ -2297,6 +2298,8 @@ static int vfio_add_std_cap(VFIODevice *vdev, uint8_t pos)case PCI_CAP_ID_MSIX : ret =vfio_setup_msix (vdev, pos);break ; +case PCI_CAP_ID_PM : + vdev->pm_cap = pos;default : ret =pci_add_capability (pdev, cap_id, pos, size);break ;
@@ -2869,6 +2872,26 @@ static void vfio_pci_reset(DeviceState *dev)vfio_disable_interrupts (vdev); +/* Make sure the device is in D0 */ +if (vdev->pm_cap) { +uint16_t pmcsr; +uint8_t state; + + pmcsr =vfio_pci_read_config (pdev, vdev->pm_cap +PCI_PM_CTRL ,2 ); + state = pmcsr &PCI_PM_CTRL_STATE_MASK ; +if (state) { + pmcsr &= ~PCI_PM_CTRL_STATE_MASK ; +vfio_pci_write_config (pdev, vdev->pm_cap +PCI_PM_CTRL , pmcsr,2 ); +/* vfio handles the necessary delay here */ + pmcsr =vfio_pci_read_config (pdev, vdev->pm_cap +PCI_PM_CTRL ,2 ); + state = pmcsr &PCI_PM_CTRL_STATE_MASK ; +if (state) { +error_report ("vfio: Unable to power on device, stuck in D%d\n" , + state); + } + } + } +/* * Stop any ongoing DMA by disconecting I/O, MMIO, and bus master. * Also put INTx Disable in known state.