--- zzzz-none-000/linux-3.10.107/drivers/misc/vmw_vmci/vmci_guest.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/misc/vmw_vmci/vmci_guest.c 2021-02-04 17:41:59.000000000 +0000 @@ -35,7 +35,6 @@ #include "vmci_driver.h" #include "vmci_event.h" -#define PCI_VENDOR_ID_VMWARE 0x15AD #define PCI_DEVICE_ID_VMWARE_VMCI 0x0740 #define VMCI_UTIL_NUM_RESOURCES 1 @@ -65,9 +64,11 @@ void *data_buffer; void *notification_bitmap; + dma_addr_t notification_base; }; /* vmci_dev singleton device and supporting data*/ +struct pci_dev *vmci_pdev; static struct vmci_guest_device *vmci_dev_g; static DEFINE_SPINLOCK(vmci_dev_spinlock); @@ -163,7 +164,7 @@ * true if required hypercalls (or fallback hypercalls) are * supported by the host, false otherwise. */ -static bool vmci_check_host_caps(struct pci_dev *pdev) +static int vmci_check_host_caps(struct pci_dev *pdev) { bool result; struct vmci_resource_query_msg *msg; @@ -174,7 +175,7 @@ check_msg = kmalloc(msg_size, GFP_KERNEL); if (!check_msg) { dev_err(&pdev->dev, "%s: Insufficient memory\n", __func__); - return false; + return -ENOMEM; } check_msg->dst = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID, @@ -194,7 +195,7 @@ __func__, result ? "PASSED" : "FAILED"); /* We need the vector. There are no fallbacks. */ - return result; + return result ? 0 : -ENXIO; } /* @@ -381,11 +382,12 @@ vmci_dev->msix_entries[i].vector = i; } - result = pci_enable_msix(pdev, vmci_dev->msix_entries, VMCI_MAX_INTRS); + result = pci_enable_msix_exact(pdev, + vmci_dev->msix_entries, VMCI_MAX_INTRS); if (result == 0) vmci_dev->exclusive_vectors = true; - else if (result > 0) - result = pci_enable_msix(pdev, vmci_dev->msix_entries, 1); + else if (result == -ENOSPC) + result = pci_enable_msix_exact(pdev, vmci_dev->msix_entries, 1); return result; } @@ -528,7 +530,9 @@ * well. */ if (capabilities & VMCI_CAPS_NOTIFICATIONS) { - vmci_dev->notification_bitmap = vmalloc(PAGE_SIZE); + vmci_dev->notification_bitmap = dma_alloc_coherent( + &pdev->dev, PAGE_SIZE, &vmci_dev->notification_base, + GFP_KERNEL); if (!vmci_dev->notification_bitmap) { dev_warn(&pdev->dev, "Unable to allocate notification bitmap\n"); @@ -546,6 +550,7 @@ /* Set up global device so that we can start sending datagrams */ spin_lock_irq(&vmci_dev_spinlock); vmci_dev_g = vmci_dev; + vmci_pdev = pdev; spin_unlock_irq(&vmci_dev_spinlock); /* @@ -553,19 +558,20 @@ * used. */ if (capabilities & VMCI_CAPS_NOTIFICATIONS) { - struct page *page = - vmalloc_to_page(vmci_dev->notification_bitmap); - unsigned long bitmap_ppn = page_to_pfn(page); + unsigned long bitmap_ppn = + vmci_dev->notification_base >> PAGE_SHIFT; if (!vmci_dbell_register_notification_bitmap(bitmap_ppn)) { dev_warn(&pdev->dev, "VMCI device unable to register notification bitmap with PPN 0x%x\n", (u32) bitmap_ppn); + error = -ENXIO; goto err_remove_vmci_dev_g; } } /* Check host capabilities. */ - if (!vmci_check_host_caps(pdev)) + error = vmci_check_host_caps(pdev); + if (error) goto err_remove_bitmap; /* Enable device. */ @@ -645,7 +651,7 @@ return 0; err_free_irq: - free_irq(vmci_dev->irq, &vmci_dev); + free_irq(vmci_dev->irq, vmci_dev); tasklet_kill(&vmci_dev->datagram_tasklet); tasklet_kill(&vmci_dev->bm_tasklet); @@ -665,11 +671,14 @@ if (vmci_dev->notification_bitmap) { iowrite32(VMCI_CONTROL_RESET, vmci_dev->iobase + VMCI_CONTROL_ADDR); - vfree(vmci_dev->notification_bitmap); + dma_free_coherent(&pdev->dev, PAGE_SIZE, + vmci_dev->notification_bitmap, + 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); @@ -699,6 +708,7 @@ spin_lock_irq(&vmci_dev_spinlock); vmci_dev_g = NULL; + vmci_pdev = NULL; spin_unlock_irq(&vmci_dev_spinlock); dev_dbg(&pdev->dev, "Resetting vmci device\n"); @@ -727,7 +737,9 @@ * device, so we can safely free it here. */ - vfree(vmci_dev->notification_bitmap); + dma_free_coherent(&pdev->dev, PAGE_SIZE, + vmci_dev->notification_bitmap, + vmci_dev->notification_base); } vfree(vmci_dev->data_buffer); @@ -735,7 +747,7 @@ /* The rest are managed resources and will be freed by PCI core */ } -static DEFINE_PCI_DEVICE_TABLE(vmci_ids) = { +static const struct pci_device_id vmci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_VMCI), }, { 0 }, };