From 2d9e7d4cddd901a3cb57d2fc150186c70b7139a7 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Sun, 20 Dec 2020 17:35:39 +0100 Subject: virtio-mmio: fix guest kernel crash with SHM regions In the kernel, virtio_gpu_init() uses virtio_get_shm_region() since commit 6076a9711dc5 ("drm/virtio: implement blob resources: probe for host visible region") but vm_get_shm_region() unconditionally uses VIRTIO_MMIO_SHM_SEL to get the address and the length of the region. commit 38e895487afc ("virtio: Implement get_shm_region for MMIO transport" As this is not implemented in QEMU, address and length are 0 and passed as is to devm_request_mem_region() that triggers a crash: [drm:virtio_gpu_init] *ERROR* Could not reserve host visible region Unable to handle kernel NULL pointer dereference at virtual address (ptrval) According to the comments in the kernel, a non existent shared region has a length of (u64)-1. This is what we return now with this patch to disable the region. Signed-off-by: Laurent Vivier Message-Id: <20201220163539.2255963-1-laurent@vivier.eu> Acked-by: Gerd Hoffmann Reviewed-by: Stefano Garzarella Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio-mmio.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'hw/virtio') diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c index e1b5c3b..610661d 100644 --- a/hw/virtio/virtio-mmio.c +++ b/hw/virtio/virtio-mmio.c @@ -191,6 +191,14 @@ static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size) return 0; } return vdev->generation; + case VIRTIO_MMIO_SHM_LEN_LOW: + case VIRTIO_MMIO_SHM_LEN_HIGH: + /* + * VIRTIO_MMIO_SHM_SEL is unimplemented + * according to the linux driver, if region length is -1 + * the shared memory doesn't exist + */ + return -1; case VIRTIO_MMIO_DEVICE_FEATURES_SEL: case VIRTIO_MMIO_DRIVER_FEATURES: case VIRTIO_MMIO_DRIVER_FEATURES_SEL: -- cgit v1.1 From f6ab64c05f8a6229bf6569d3791c23abb9f6eee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= Date: Mon, 25 Jan 2021 20:25:05 +0100 Subject: virtio: Add corresponding memory_listener_unregister to unrealize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address space is destroyed without proper removal of its listeners with current code. They are expected to be removed in virtio_device_instance_finalize [1], but qemu calls it through object_deinit, after address_space_destroy call through device_set_realized [2]. Move it to virtio_device_unrealize, called before device_set_realized [3] and making it symmetric with memory_listener_register in virtio_device_realize. v2: Delete no-op call of virtio_device_instance_finalize. Add backtraces. [1] #0 virtio_device_instance_finalize (obj=0x555557de5120) at /home/qemu/include/hw/virtio/virtio.h:71 #1 0x0000555555b703c9 in object_deinit (type=0x555556639860, obj=) at ../qom/object.c:671 #2 object_finalize (data=0x555557de5120) at ../qom/object.c:685 #3 object_unref (objptr=0x555557de5120) at ../qom/object.c:1184 #4 0x0000555555b4de9d in bus_free_bus_child (kid=0x555557df0660) at ../hw/core/qdev.c:55 #5 0x0000555555c65003 in call_rcu_thread (opaque=opaque@entry=0x0) at ../util/rcu.c:281 Queued by: #0 bus_remove_child (bus=0x555557de5098, child=child@entry=0x555557de5120) at ../hw/core/qdev.c:60 #1 0x0000555555b4ee31 in device_unparent (obj=) at ../hw/core/qdev.c:984 #2 0x0000555555b70465 in object_finalize_child_property ( obj=, name=, opaque=0x555557de5120) at ../qom/object.c:1725 #3 0x0000555555b6fa17 in object_property_del_child ( child=0x555557de5120, obj=0x555557ddcf90) at ../qom/object.c:645 #4 object_unparent (obj=0x555557de5120) at ../qom/object.c:664 #5 0x0000555555b4c071 in bus_unparent (obj=) at ../hw/core/bus.c:147 #6 0x0000555555b70465 in object_finalize_child_property ( obj=, name=, opaque=0x555557de5098) at ../qom/object.c:1725 #7 0x0000555555b6fa17 in object_property_del_child ( child=0x555557de5098, obj=0x555557ddcf90) at ../qom/object.c:645 #8 object_unparent (obj=0x555557de5098) at ../qom/object.c:664 #9 0x0000555555b4ee19 in device_unparent (obj=) at ../hw/core/qdev.c:981 #10 0x0000555555b70465 in object_finalize_child_property ( obj=, name=, opaque=0x555557ddcf90) at ../qom/object.c:1725 #11 0x0000555555b6fa17 in object_property_del_child ( child=0x555557ddcf90, obj=0x55555685da10) at ../qom/object.c:645 #12 object_unparent (obj=0x555557ddcf90) at ../qom/object.c:664 #13 0x00005555558dc331 in pci_for_each_device_under_bus ( opaque=, fn=, bus=) at ../hw/pci/pci.c:1654 [2] Optimizer omits pci_qdev_unrealize, called by device_set_realized, and do_pci_unregister_device, called by pci_qdev_unrealize and caller of address_space_destroy. #0 address_space_destroy (as=0x555557ddd1b8) at ../softmmu/memory.c:2840 #1 0x0000555555b4fc53 in device_set_realized (obj=0x555557ddcf90, value=, errp=0x7fffeea8f1e0) at ../hw/core/qdev.c:850 #2 0x0000555555b6eaa6 in property_set_bool (obj=0x555557ddcf90, v=, name=, opaque=0x555556650ba0, errp=0x7fffeea8f1e0) at ../qom/object.c:2255 #3 0x0000555555b70e07 in object_property_set ( obj=obj@entry=0x555557ddcf90, name=name@entry=0x555555db99df "realized", v=v@entry=0x7fffe46b7500, errp=errp@entry=0x5555565bbf38 ) at ../qom/object.c:1400 #4 0x0000555555b73c5f in object_property_set_qobject ( obj=obj@entry=0x555557ddcf90, name=name@entry=0x555555db99df "realized", value=value@entry=0x7fffe44f6180, errp=errp@entry=0x5555565bbf38 ) at ../qom/qom-qobject.c:28 #5 0x0000555555b71044 in object_property_set_bool ( obj=0x555557ddcf90, name=0x555555db99df "realized", value=, errp=0x5555565bbf38 ) at ../qom/object.c:1470 #6 0x0000555555921cb7 in pcie_unplug_device (bus=, dev=0x555557ddcf90, opaque=) at /home/qemu/include/hw/qdev-core.h:17 #7 0x00005555558dc331 in pci_for_each_device_under_bus ( opaque=, fn=, bus=) at ../hw/pci/pci.c:1654 [3] #0 virtio_device_unrealize (dev=0x555557de5120) at ../hw/virtio/virtio.c:3680 #1 0x0000555555b4fc63 in device_set_realized (obj=0x555557de5120, value=, errp=0x7fffee28df90) at ../hw/core/qdev.c:850 #2 0x0000555555b6eab6 in property_set_bool (obj=0x555557de5120, v=, name=, opaque=0x555556650ba0, errp=0x7fffee28df90) at ../qom/object.c:2255 #3 0x0000555555b70e17 in object_property_set ( obj=obj@entry=0x555557de5120, name=name@entry=0x555555db99ff "realized", v=v@entry=0x7ffdd8035040, errp=errp@entry=0x5555565bbf38 ) at ../qom/object.c:1400 #4 0x0000555555b73c6f in object_property_set_qobject ( obj=obj@entry=0x555557de5120, name=name@entry=0x555555db99ff "realized", value=value@entry=0x7ffdd8035020, errp=errp@entry=0x5555565bbf38 ) at ../qom/qom-qobject.c:28 #5 0x0000555555b71054 in object_property_set_bool ( obj=0x555557de5120, name=name@entry=0x555555db99ff "realized", value=value@entry=false, errp=0x5555565bbf38 ) at ../qom/object.c:1470 #6 0x0000555555b4edc5 in qdev_unrealize (dev=) at ../hw/core/qdev.c:403 #7 0x0000555555b4c2a9 in bus_set_realized (obj=, value=, errp=) at ../hw/core/bus.c:204 #8 0x0000555555b6eab6 in property_set_bool (obj=0x555557de5098, v=, name=, opaque=0x555557df04c0, errp=0x7fffee28e0a0) at ../qom/object.c:2255 #9 0x0000555555b70e17 in object_property_set ( obj=obj@entry=0x555557de5098, name=name@entry=0x555555db99ff "realized", v=v@entry=0x7ffdd8034f50, errp=errp@entry=0x5555565bbf38 ) at ../qom/object.c:1400 #10 0x0000555555b73c6f in object_property_set_qobject ( obj=obj@entry=0x555557de5098, name=name@entry=0x555555db99ff "realized", value=value@entry=0x7ffdd8020630, errp=errp@entry=0x5555565bbf38 ) at ../qom/qom-qobject.c:28 #11 0x0000555555b71054 in object_property_set_bool ( obj=obj@entry=0x555557de5098, name=name@entry=0x555555db99ff "realized", value=value@entry=false, errp=0x5555565bbf38 ) at ../qom/object.c:1470 #12 0x0000555555b4c725 in qbus_unrealize ( bus=bus@entry=0x555557de5098) at ../hw/core/bus.c:178 #13 0x0000555555b4fc00 in device_set_realized (obj=0x555557ddcf90, value=, errp=0x7fffee28e1e0) at ../hw/core/qdev.c:844 #14 0x0000555555b6eab6 in property_set_bool (obj=0x555557ddcf90, v=, name=, opaque=0x555556650ba0, errp=0x7fffee28e1e0) at ../qom/object.c:2255 #15 0x0000555555b70e17 in object_property_set ( obj=obj@entry=0x555557ddcf90, name=name@entry=0x555555db99ff "realized", v=v@entry=0x7ffdd8020560, errp=errp@entry=0x5555565bbf38 ) at ../qom/object.c:1400 #16 0x0000555555b73c6f in object_property_set_qobject ( obj=obj@entry=0x555557ddcf90, name=name@entry=0x555555db99ff "realized", value=value@entry=0x7ffdd8020540, errp=errp@entry=0x5555565bbf38 ) at ../qom/qom-qobject.c:28 #17 0x0000555555b71054 in object_property_set_bool ( obj=0x555557ddcf90, name=0x555555db99ff "realized", value=, errp=0x5555565bbf38 ) at ../qom/object.c:1470 #18 0x0000555555921cb7 in pcie_unplug_device (bus=, dev=0x555557ddcf90, opaque=) at /home/qemu/include/hw/qdev-core.h:17 #19 0x00005555558dc331 in pci_for_each_device_under_bus ( opaque=, fn=, bus=) at ../hw/pci/pci.c:1654 Fixes: c611c76417f ("virtio: add MemoryListener to cache ring translations") Buglink: https://bugs.launchpad.net/qemu/+bug/1912846 Signed-off-by: Eugenio Pérez Message-Id: <20210125192505.390554-1-eperezma@redhat.com> Reviewed-by: Peter Xu Acked-by: Jason Wang Reviewed-by: Stefano Garzarella Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/virtio') diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index b308026..1fd1917 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -3680,6 +3680,7 @@ static void virtio_device_unrealize(DeviceState *dev) VirtIODevice *vdev = VIRTIO_DEVICE(dev); VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(dev); + memory_listener_unregister(&vdev->listener); virtio_bus_device_unplugged(vdev); if (vdc->unrealize != NULL) { @@ -3710,7 +3711,6 @@ static void virtio_device_instance_finalize(Object *obj) { VirtIODevice *vdev = VIRTIO_DEVICE(obj); - memory_listener_unregister(&vdev->listener); virtio_device_free_virtqueues(vdev); g_free(vdev->config); -- cgit v1.1 From 73b123073d5e74f948eac9a2492e0b367006cd87 Mon Sep 17 00:00:00 2001 From: Pankaj Gupta Date: Tue, 17 Nov 2020 12:57:05 +0100 Subject: virtio-pmem: add trace events This patch adds trace events for virtio-pmem functionality. Adding trace events for virtio pmem request, reponse and host side fsync functionality. Signed-off-by: Pankaj Gupta Message-Id: <20201117115705.32195-1-pankaj.gupta.linux@gmail.com> Reviewed-by: David Hildenbrand Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/trace-events | 5 +++++ hw/virtio/virtio-pmem.c | 4 ++++ 2 files changed, 9 insertions(+) (limited to 'hw/virtio') diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 2060a14..c62727f 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -122,3 +122,8 @@ virtio_mem_unplug_all_request(void) "" virtio_mem_resized_usable_region(uint64_t old_size, uint64_t new_size) "old_size=0x%" PRIx64 "new_size=0x%" PRIx64 virtio_mem_state_request(uint64_t addr, uint16_t nb_blocks) "addr=0x%" PRIx64 " nb_blocks=%" PRIu16 virtio_mem_state_response(uint16_t state) "state=%" PRIu16 + +# virtio-pmem.c +virtio_pmem_flush_request(void) "flush request" +virtio_pmem_response(void) "flush response" +virtio_pmem_flush_done(int type) "fsync return=%d" diff --git a/hw/virtio/virtio-pmem.c b/hw/virtio/virtio-pmem.c index ddb0125..d83e973 100644 --- a/hw/virtio/virtio-pmem.c +++ b/hw/virtio/virtio-pmem.c @@ -24,6 +24,7 @@ #include "sysemu/hostmem.h" #include "block/aio.h" #include "block/thread-pool.h" +#include "trace.h" typedef struct VirtIODeviceRequest { VirtQueueElement elem; @@ -41,6 +42,7 @@ static int worker_cb(void *opaque) /* flush raw backing image */ err = fsync(req_data->fd); + trace_virtio_pmem_flush_done(err); if (err != 0) { err = 1; } @@ -59,6 +61,7 @@ static void done_cb(void *opaque, int ret) /* Callbacks are serialized, so no need to use atomic ops. */ virtqueue_push(req_data->pmem->rq_vq, &req_data->elem, len); virtio_notify((VirtIODevice *)req_data->pmem, req_data->pmem->rq_vq); + trace_virtio_pmem_response(); g_free(req_data); } @@ -69,6 +72,7 @@ static void virtio_pmem_flush(VirtIODevice *vdev, VirtQueue *vq) HostMemoryBackend *backend = MEMORY_BACKEND(pmem->memdev); ThreadPool *pool = aio_get_thread_pool(qemu_get_aio_context()); + trace_virtio_pmem_flush_request(); req_data = virtqueue_pop(vq, sizeof(VirtIODeviceRequest)); if (!req_data) { virtio_error(vdev, "virtio-pmem missing request data"); -- cgit v1.1 From 958ec334bca3fa9862289e4cfe31bf1019e55816 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Thu, 4 Feb 2021 14:12:28 -0500 Subject: vhost: Unbreak SMMU and virtio-iommu on dev-iotlb support Previous work on dev-iotlb message broke vhost on either SMMU or virtio-iommu since dev-iotlb (or PCIe ATS) is not yet supported for those archs. An initial idea is that we can let IOMMU to export this information to vhost so that vhost would know whether the vIOMMU would support dev-iotlb, then vhost can conditionally register to dev-iotlb or the old iotlb way. We can work based on some previous patch to introduce PCIIOMMUOps as Yi Liu proposed [1]. However it's not as easy as I thought since vhost_iommu_region_add() does not have a PCIDevice context at all since it's completely a backend. It seems non-trivial to pass over a PCI device to the backend during init. E.g. when the IOMMU notifier registered hdev->vdev is still NULL. To make the fix smaller and easier, this patch goes the other way to leverage the flag_changed() hook of vIOMMUs so that SMMU and virtio-iommu can trap the dev-iotlb registration and fail it. Then vhost could try the fallback solution as using UNMAP invalidation for it's translations. [1] https://lore.kernel.org/qemu-devel/1599735398-6829-4-git-send-email-yi.l.liu@intel.com/ Reported-by: Eric Auger Fixes: b68ba1ca57677acf870d5ab10579e6105c1f5338 Reviewed-by: Eric Auger Tested-by: Eric Auger Signed-off-by: Peter Xu Message-Id: <20210204191228.187550-1-peterx@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/vhost.c | 13 +++++++++++-- hw/virtio/virtio-iommu.c | 5 +++++ 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'hw/virtio') diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 28c7d78..6e17d63 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -704,6 +704,7 @@ static void vhost_iommu_region_add(MemoryListener *listener, Int128 end; int iommu_idx; IOMMUMemoryRegion *iommu_mr; + int ret; if (!memory_region_is_iommu(section->mr)) { return; @@ -726,8 +727,16 @@ static void vhost_iommu_region_add(MemoryListener *listener, iommu->iommu_offset = section->offset_within_address_space - section->offset_within_region; iommu->hdev = dev; - memory_region_register_iommu_notifier(section->mr, &iommu->n, - &error_fatal); + ret = memory_region_register_iommu_notifier(section->mr, &iommu->n, NULL); + if (ret) { + /* + * Some vIOMMUs do not support dev-iotlb yet. If so, try to use the + * UNMAP legacy message + */ + iommu->n.notifier_flags = IOMMU_NOTIFIER_UNMAP; + memory_region_register_iommu_notifier(section->mr, &iommu->n, + &error_fatal); + } QLIST_INSERT_HEAD(&dev->iommu_list, iommu, iommu_next); /* TODO: can replay help performance here? */ } diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 6b9ef7f..c2883a2 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -893,6 +893,11 @@ static int virtio_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu_mr, IOMMUNotifierFlag new, Error **errp) { + if (new & IOMMU_NOTIFIER_DEVIOTLB_UNMAP) { + error_setg(errp, "Virtio-iommu does not support dev-iotlb yet"); + return -EINVAL; + } + if (old == IOMMU_NOTIFIER_NONE) { trace_virtio_iommu_notify_flag_add(iommu_mr->parent_obj.name); } else if (new == IOMMU_NOTIFIER_NONE) { -- cgit v1.1 From d8be0c6b68c6dac3e2ded573292b52542a1dc814 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 3 Feb 2021 18:18:31 +0100 Subject: hw/virtio/virtio-balloon: Remove the "class" property This property was only required for compatibility reasons in the pc-1.0 machine type and earlier. Now that these machine types have been removed, the property is not useful anymore. Signed-off-by: Thomas Huth Message-Id: <20210203171832.483176-4-thuth@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Acked-by: David Hildenbrand --- hw/virtio/virtio-balloon-pci.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'hw/virtio') diff --git a/hw/virtio/virtio-balloon-pci.c b/hw/virtio/virtio-balloon-pci.c index a2c5cc7..79a3ba9 100644 --- a/hw/virtio/virtio-balloon-pci.c +++ b/hw/virtio/virtio-balloon-pci.c @@ -34,21 +34,13 @@ struct VirtIOBalloonPCI { VirtIOPCIProxy parent_obj; VirtIOBalloon vdev; }; -static Property virtio_balloon_pci_properties[] = { - DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0), - DEFINE_PROP_END_OF_LIST(), -}; static void virtio_balloon_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) { VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(vpci_dev); DeviceState *vdev = DEVICE(&dev->vdev); - if (vpci_dev->class_code != PCI_CLASS_OTHERS && - vpci_dev->class_code != PCI_CLASS_MEMORY_RAM) { /* qemu < 1.1 */ - vpci_dev->class_code = PCI_CLASS_OTHERS; - } - + vpci_dev->class_code = PCI_CLASS_OTHERS; qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } @@ -59,7 +51,6 @@ static void virtio_balloon_pci_class_init(ObjectClass *klass, void *data) PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass); k->realize = virtio_balloon_pci_realize; set_bit(DEVICE_CATEGORY_MISC, dc->categories); - device_class_set_props(dc, virtio_balloon_pci_properties); pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET; pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_BALLOON; pcidev_k->revision = VIRTIO_PCI_ABI_VERSION; -- cgit v1.1 From 4d1ccc17f40f73313e13c84914f70ec3d40ac738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= Date: Fri, 29 Jan 2021 10:07:28 +0100 Subject: vhost: Check for valid vdev in vhost_backend_handle_iotlb_msg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not checking this can lead to invalid dev->vdev member access in vhost_device_iotlb_miss if backend issue an iotlb message in a bad timing, either maliciously or by a bug. Reproduced rebooting a guest with testpmd in txonly forward mode. #0 0x0000559ffff94394 in vhost_device_iotlb_miss ( dev=dev@entry=0x55a0012f6680, iova=10245279744, write=1) at ../hw/virtio/vhost.c:1013 #1 0x0000559ffff9ac31 in vhost_backend_handle_iotlb_msg ( imsg=0x7ffddcfd32c0, dev=0x55a0012f6680) at ../hw/virtio/vhost-backend.c:411 #2 vhost_backend_handle_iotlb_msg (dev=dev@entry=0x55a0012f6680, imsg=imsg@entry=0x7ffddcfd32c0) at ../hw/virtio/vhost-backend.c:404 #3 0x0000559fffeded7b in slave_read (opaque=0x55a0012f6680) at ../hw/virtio/vhost-user.c:1464 #4 0x000055a0000c541b in aio_dispatch_handler ( ctx=ctx@entry=0x55a0010a2120, node=0x55a0012d9e00) at ../util/aio-posix.c:329 Fixes: 020e571b8b ("vhost: rework IOTLB messaging") Signed-off-by: Eugenio Pérez Message-Id: <20210129090728.831208-1-eperezma@redhat.com> Acked-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/vhost-backend.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'hw/virtio') diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c index 222bbcc..31b33bd 100644 --- a/hw/virtio/vhost-backend.c +++ b/hw/virtio/vhost-backend.c @@ -406,6 +406,11 @@ int vhost_backend_handle_iotlb_msg(struct vhost_dev *dev, { int ret = 0; + if (unlikely(!dev->vdev)) { + error_report("Unexpected IOTLB message when virtio device is stopped"); + return -EINVAL; + } + switch (imsg->type) { case VHOST_IOTLB_MISS: ret = vhost_device_iotlb_miss(dev, imsg->iova, -- cgit v1.1