Commit 77e86161 authored by Christophe JAILLET's avatar Christophe JAILLET Committed by Greg Kroah-Hartman
Browse files

VMCI: Fix some error handling paths in vmci_guest_probe_device()



The 'err_remove_vmci_dev_g' error label is not at the right place.
This could lead to un-released resource.

There is also a missing label. If pci_alloc_irq_vectors() fails, the
previous vmci_event_subscribe() call must be undone.

Acked-by: default avatarVishnu Dasa <vdasa@vmware.com>
Signed-off-by: default avatarChristophe JAILLET <christophe.jaillet@wanadoo.fr>
Link: https://lore.kernel.org/r/959218ce3b135197946d85cd9453551cd04fa5da.1645734041.git.christophe.jaillet@wanadoo.fr


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent cc312da2
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -765,7 +765,7 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
	/* Check host capabilities. */
	error = vmci_check_host_caps(pdev);
	if (error)
		goto err_remove_bitmap;
		goto err_remove_vmci_dev_g;

	/* Enable device. */

@@ -795,7 +795,7 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
		error = pci_alloc_irq_vectors(pdev, 1, 1,
				PCI_IRQ_MSIX | PCI_IRQ_MSI | PCI_IRQ_LEGACY);
		if (error < 0)
			goto err_remove_bitmap;
			goto err_unsubscribe_event;
	} else {
		vmci_dev->exclusive_vectors = true;
	}
@@ -871,13 +871,19 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
err_disable_msi:
	pci_free_irq_vectors(pdev);

err_unsubscribe_event:
	vmci_err = vmci_event_unsubscribe(ctx_update_sub_id);
	if (vmci_err < VMCI_SUCCESS)
		dev_warn(&pdev->dev,
			 "Failed to unsubscribe from event (type=%d) with subscriber (ID=0x%x): %d\n",
			 VMCI_EVENT_CTX_ID_UPDATE, ctx_update_sub_id, vmci_err);

err_remove_bitmap:
err_remove_vmci_dev_g:
	spin_lock_irq(&vmci_dev_spinlock);
	vmci_pdev = NULL;
	vmci_dev_g = NULL;
	spin_unlock_irq(&vmci_dev_spinlock);

	if (vmci_dev->notification_bitmap) {
		vmci_write_reg(vmci_dev, VMCI_CONTROL_RESET, VMCI_CONTROL_ADDR);
		dma_free_coherent(&pdev->dev, PAGE_SIZE,
@@ -885,12 +891,6 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
				  vmci_dev->notification_base);
	}

err_remove_vmci_dev_g:
	spin_lock_irq(&vmci_dev_spinlock);
	vmci_pdev = NULL;
	vmci_dev_g = NULL;
	spin_unlock_irq(&vmci_dev_spinlock);

err_free_data_buffers:
	vmci_free_dg_buffers(vmci_dev);