diff options
author | Johannes Berg <johannes.berg@intel.com> | 2021-03-05 13:19:59 +0100 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2021-06-17 21:45:44 +0200 |
commit | 43c590cb86665be702c0af0231a10ec813df9cfd (patch) | |
tree | dc1c8389fce0e298bf113e880eb457e0bd69de5e /arch/um/drivers/virt-pci.c | |
parent | 68f5d3f3b6543266b29e047cfaf9842333019b4c (diff) |
um: virtio/pci: enable suspend/resume
The UM virtual PCI devices currently cannot be suspended properly
since the virtio driver already disables VQs well before the PCI
bus's suspend_noirq wants to complete the transition by writing to
PCI config space.
After trying around for a long time with moving the devices on the
DPM list, trying to create dependencies between them, etc. I gave
up and instead added UML specific cross-driver API that lets the
virt-pci code enable not suspending/resuming VQs for its devices.
This then allows the PCI bus suspend_noirq to still talk to the
device, and suspend/resume works properly.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch/um/drivers/virt-pci.c')
-rw-r--r-- | arch/um/drivers/virt-pci.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c index dd85f36197aa..0b802834f40a 100644 --- a/arch/um/drivers/virt-pci.c +++ b/arch/um/drivers/virt-pci.c @@ -10,6 +10,7 @@ #include <linux/logic_iomem.h> #include <linux/irqdomain.h> #include <linux/virtio_pcidev.h> +#include <linux/virtio-uml.h> #include <linux/delay.h> #include <linux/msi.h> #include <asm/unaligned.h> @@ -134,6 +135,9 @@ static int um_pci_send_cmd(struct um_pci_device *dev, if (completed == HANDLE_NO_FREE(cmd)) break; + if (completed && !HANDLE_IS_NO_FREE(completed)) + kfree(completed); + if (WARN_ONCE(virtqueue_is_broken(dev->cmd_vq) || ++delay_count > UM_VIRT_PCI_MAXDELAY, "um virt-pci delay: %d", delay_count)) { @@ -550,6 +554,12 @@ static int um_pci_virtio_probe(struct virtio_device *vdev) device_set_wakeup_enable(&vdev->dev, true); + /* + * In order to do suspend-resume properly, don't allow VQs + * to be suspended. + */ + virtio_uml_set_no_vq_suspend(vdev, true); + um_pci_rescan(); return 0; error: |