From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38852) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YJqFI-0005Ia-Aw for qemu-devel@nongnu.org; Fri, 06 Feb 2015 16:15:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YJqFE-0006qd-91 for qemu-devel@nongnu.org; Fri, 06 Feb 2015 16:15:24 -0500 Received: from mail-wi0-x231.google.com ([2a00:1450:400c:c05::231]:51856) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YJqFE-0006qR-08 for qemu-devel@nongnu.org; Fri, 06 Feb 2015 16:15:20 -0500 Received: by mail-wi0-f177.google.com with SMTP id r20so5355349wiv.4 for ; Fri, 06 Feb 2015 13:15:19 -0800 (PST) Received: from playground.station (net-93-66-105-136.cust.vodafonedsl.it. [93.66.105.136]) by mx.google.com with ESMTPSA id eb7sm3017776wic.11.2015.02.06.13.15.17 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 06 Feb 2015 13:15:18 -0800 (PST) Sender: Paolo Bonzini From: Paolo Bonzini Date: Fri, 6 Feb 2015 22:15:09 +0100 Message-Id: <1423257311-1345-2-git-send-email-pbonzini@redhat.com> In-Reply-To: <1423257311-1345-1-git-send-email-pbonzini@redhat.com> References: <1423257311-1345-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 1/3] vfio: cleanup vfio_get_device error path, remove vfio_populate_device callback List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Now that vfio_put_base_device is called unconditionally at instance_finalize time, it can be called twice if vfio_populate_device fails. This works but it is slightly harder to follow. Change vfio_get_device to not touch the vbasedev struct until it will definitely succeed, moving the vfio_populate_device call back to vfio-pci. This way, vfio_put_base_device will only be called once. Signed-off-by: Paolo Bonzini --- hw/vfio/common.c | 30 ++++++++++++------------------ hw/vfio/pci.c | 11 +++++++---- include/hw/vfio/vfio-common.h | 1 - 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index cf483ff..a4c6fc6 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -867,27 +867,28 @@ int vfio_get_device(VFIOGroup *group, const char *name, VFIODevice *vbasedev) { struct vfio_device_info dev_info = { .argsz = sizeof(dev_info) }; - int ret; + int ret, fd; - ret = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, name); - if (ret < 0) { + fd = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, name); + if (fd < 0) { error_report("vfio: error getting device %s from group %d: %m", name, group->groupid); error_printf("Verify all devices in group %d are bound to vfio- " "or pci-stub and not already in use\n", group->groupid); - return ret; + return fd; } - vbasedev->fd = ret; - vbasedev->group = group; - QLIST_INSERT_HEAD(&group->device_list, vbasedev, next); - - ret = ioctl(vbasedev->fd, VFIO_DEVICE_GET_INFO, &dev_info); + ret = ioctl(fd, VFIO_DEVICE_GET_INFO, &dev_info); if (ret) { error_report("vfio: error getting device info: %m"); - goto error; + close(fd); + return ret; } + vbasedev->fd = fd; + vbasedev->group = group; + QLIST_INSERT_HEAD(&group->device_list, vbasedev, next); + vbasedev->num_irqs = dev_info.num_irqs; vbasedev->num_regions = dev_info.num_regions; vbasedev->flags = dev_info.flags; @@ -896,14 +897,7 @@ int vfio_get_device(VFIOGroup *group, const char *name, dev_info.num_irqs); vbasedev->reset_works = !!(dev_info.flags & VFIO_DEVICE_FLAGS_RESET); - - ret = vbasedev->ops->vfio_populate_device(vbasedev); - -error: - if (ret) { - vfio_put_base_device(vbasedev); - } - return ret; + return 0; } void vfio_put_base_device(VFIODevice *vbasedev) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 014a92c..1fd3dae 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -195,7 +195,6 @@ static uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len); static void vfio_pci_write_config(PCIDevice *pdev, uint32_t addr, uint32_t val, int len); static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled); -static int vfio_populate_device(VFIODevice *vbasedev); /* * Disabling BAR mmaping can be slow, but toggling it around INTx can @@ -2934,12 +2933,11 @@ static VFIODeviceOps vfio_pci_ops = { .vfio_compute_needs_reset = vfio_pci_compute_needs_reset, .vfio_hot_reset_multi = vfio_pci_hot_reset_multi, .vfio_eoi = vfio_eoi, - .vfio_populate_device = vfio_populate_device, }; -static int vfio_populate_device(VFIODevice *vbasedev) +static int vfio_populate_device(VFIOPCIDevice *vdev) { - VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev); + VFIODevice *vbasedev = &vdev->vbasedev; struct vfio_region_info reg_info = { .argsz = sizeof(reg_info) }; struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info) }; int i, ret = -1; @@ -3247,6 +3245,11 @@ static int vfio_initfn(PCIDevice *pdev) return ret; } + ret = vfio_populate_device(vdev); + if (ret) { + goto out_put; + } + /* Get a copy of config space */ ret = pread(vdev->vbasedev.fd, vdev->pdev.config, MIN(pci_config_size(&vdev->pdev), vdev->config_size), diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index 1d5bfe8..5f3679b 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -112,7 +112,6 @@ struct VFIODeviceOps { void (*vfio_compute_needs_reset)(VFIODevice *vdev); int (*vfio_hot_reset_multi)(VFIODevice *vdev); void (*vfio_eoi)(VFIODevice *vdev); - int (*vfio_populate_device)(VFIODevice *vdev); }; typedef struct VFIOGroup { -- 1.8.3.1