aboutsummaryrefslogtreecommitdiff
path: root/hw/vfio
diff options
context:
space:
mode:
authorZhenzhong Duan <zhenzhong.duan@intel.com>2023-06-29 16:40:38 +0800
committerCédric Le Goater <clg@redhat.com>2023-06-30 06:02:51 +0200
commit357bd7932a136613d700ee8bc83e9165f059d1f7 (patch)
treea974a48764cdbe8bddaa0273d9522f69b96870ea /hw/vfio
parent2696da621e237b3ecfbf63085ea0603f439fb863 (diff)
downloadqemu-357bd7932a136613d700ee8bc83e9165f059d1f7.zip
qemu-357bd7932a136613d700ee8bc83e9165f059d1f7.tar.gz
qemu-357bd7932a136613d700ee8bc83e9165f059d1f7.tar.bz2
vfio/pci: Fix a segfault in vfio_realize
The kvm irqchip notifier is only registered if the device supports INTx, however it's unconditionally removed in vfio realize error path. If the assigned device does not support INTx, this will cause QEMU to crash when vfio realize fails. Change it to conditionally remove the notifier only if the notify hook is setup. Before fix: (qemu) device_add vfio-pci,host=81:11.1,id=vfio1,bus=root1,xres=1 Connection closed by foreign host. After fix: (qemu) device_add vfio-pci,host=81:11.1,id=vfio1,bus=root1,xres=1 Error: vfio 0000:81:11.1: xres and yres properties require display=on (qemu) Fixes: c5478fea27ac ("vfio/pci: Respond to KVM irqchip change notifier") Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Reviewed-by: Joao Martins <joao.m.martins@oracle.com> Signed-off-by: Cédric Le Goater <clg@redhat.com>
Diffstat (limited to 'hw/vfio')
-rw-r--r--hw/vfio/pci.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 73e19a0..48df517 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3221,7 +3221,9 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
out_deregister:
pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);
- kvm_irqchip_remove_change_notifier(&vdev->irqchip_change_notifier);
+ if (vdev->irqchip_change_notifier.notify) {
+ kvm_irqchip_remove_change_notifier(&vdev->irqchip_change_notifier);
+ }
out_teardown:
vfio_teardown_msi(vdev);
vfio_bars_exit(vdev);