vfio-pci: Extend reset

Take what we've learned from pci-assign and apply it to vfio-pci.
On reset, disable previous interrupt config, perform a device
reset if available, re-enable INTx, and disable memory regions on
the device to prevent continuing DMA.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
Alex Williamson 2012-10-08 08:45:30 -06:00
parent 9b1e45c8f1
commit 5834a83f48

View File

@ -1891,16 +1891,31 @@ static void vfio_pci_reset(DeviceState *dev)
{
PCIDevice *pdev = DO_UPCAST(PCIDevice, qdev, dev);
VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, pdev);
uint16_t cmd;
if (!vdev->reset_works) {
return;
DPRINTF("%s(%04x:%02x:%02x.%x)\n", __func__, vdev->host.domain,
vdev->host.bus, vdev->host.slot, vdev->host.function);
vfio_disable_interrupts(vdev);
/*
* Stop any ongoing DMA by disconecting I/O, MMIO, and bus master.
* Also put INTx Disable in known state.
*/
cmd = vfio_pci_read_config(pdev, PCI_COMMAND, 2);
cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
PCI_COMMAND_INTX_DISABLE);
vfio_pci_write_config(pdev, PCI_COMMAND, cmd, 2);
if (vdev->reset_works) {
if (ioctl(vdev->fd, VFIO_DEVICE_RESET)) {
error_report("vfio: Error unable to reset physical device "
"(%04x:%02x:%02x.%x): %m\n", vdev->host.domain,
vdev->host.bus, vdev->host.slot, vdev->host.function);
}
}
if (ioctl(vdev->fd, VFIO_DEVICE_RESET)) {
error_report("vfio: Error unable to reset physical device "
"(%04x:%02x:%02x.%x): %m\n", vdev->host.domain,
vdev->host.bus, vdev->host.slot, vdev->host.function);
}
vfio_enable_intx(vdev);
}
static Property vfio_pci_dev_properties[] = {