diff options
Diffstat (limited to 'drivers/misc/vmw_vmci')
-rw-r--r-- | drivers/misc/vmw_vmci/Kconfig | 2 | ||||
-rw-r--r-- | drivers/misc/vmw_vmci/vmci_context.c | 15 | ||||
-rw-r--r-- | drivers/misc/vmw_vmci/vmci_guest.c | 4 | ||||
-rw-r--r-- | drivers/misc/vmw_vmci/vmci_queue_pair.c | 12 |
4 files changed, 24 insertions, 9 deletions
diff --git a/drivers/misc/vmw_vmci/Kconfig b/drivers/misc/vmw_vmci/Kconfig index 605794aadf11..b6d4d7fd686a 100644 --- a/drivers/misc/vmw_vmci/Kconfig +++ b/drivers/misc/vmw_vmci/Kconfig @@ -5,7 +5,7 @@ config VMWARE_VMCI tristate "VMware VMCI Driver" - depends on X86 && PCI + depends on (X86 || ARM64) && !CPU_BIG_ENDIAN && PCI help This is VMware's Virtual Machine Communication Interface. It enables high-speed communication between host and guest in a virtual diff --git a/drivers/misc/vmw_vmci/vmci_context.c b/drivers/misc/vmw_vmci/vmci_context.c index 6cf3e21c7604..172696abce31 100644 --- a/drivers/misc/vmw_vmci/vmci_context.c +++ b/drivers/misc/vmw_vmci/vmci_context.c @@ -665,9 +665,8 @@ int vmci_ctx_add_notification(u32 context_id, u32 remote_cid) int vmci_ctx_remove_notification(u32 context_id, u32 remote_cid) { struct vmci_ctx *context; - struct vmci_handle_list *notifier, *tmp; + struct vmci_handle_list *notifier = NULL, *iter, *tmp; struct vmci_handle handle; - bool found = false; context = vmci_ctx_get(context_id); if (!context) @@ -676,23 +675,23 @@ int vmci_ctx_remove_notification(u32 context_id, u32 remote_cid) handle = vmci_make_handle(remote_cid, VMCI_EVENT_HANDLER); spin_lock(&context->lock); - list_for_each_entry_safe(notifier, tmp, + list_for_each_entry_safe(iter, tmp, &context->notifier_list, node) { - if (vmci_handle_is_equal(notifier->handle, handle)) { - list_del_rcu(¬ifier->node); + if (vmci_handle_is_equal(iter->handle, handle)) { + list_del_rcu(&iter->node); context->n_notifiers--; - found = true; + notifier = iter; break; } } spin_unlock(&context->lock); - if (found) + if (notifier) kvfree_rcu(notifier); vmci_ctx_put(context); - return found ? VMCI_SUCCESS : VMCI_ERROR_NOT_FOUND; + return notifier ? VMCI_SUCCESS : VMCI_ERROR_NOT_FOUND; } static int vmci_ctx_get_chkpt_notifiers(struct vmci_ctx *context, diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c index 57a6157209a1..aa7b05de97dd 100644 --- a/drivers/misc/vmw_vmci/vmci_guest.c +++ b/drivers/misc/vmw_vmci/vmci_guest.c @@ -614,6 +614,10 @@ static int vmci_guest_probe_device(struct pci_dev *pdev, } if (!mmio_base) { + if (IS_ENABLED(CONFIG_ARM64)) { + dev_err(&pdev->dev, "MMIO base is invalid\n"); + return -ENXIO; + } error = pcim_iomap_regions(pdev, BIT(0), KBUILD_MODNAME); if (error) { dev_err(&pdev->dev, "Failed to reserve/map IO regions\n"); diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c b/drivers/misc/vmw_vmci/vmci_queue_pair.c index 94ebf7f3fd58..8f2de1893245 100644 --- a/drivers/misc/vmw_vmci/vmci_queue_pair.c +++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c @@ -2577,6 +2577,12 @@ static ssize_t qp_enqueue_locked(struct vmci_queue *produce_q, if (result < VMCI_SUCCESS) return result; + /* + * This virt_wmb() ensures that data written to the queue + * is observable before the new producer_tail is. + */ + virt_wmb(); + vmci_q_header_add_producer_tail(produce_q->q_header, written, produce_q_size); return written; @@ -2620,6 +2626,12 @@ static ssize_t qp_dequeue_locked(struct vmci_queue *produce_q, if (buf_ready < VMCI_SUCCESS) return (ssize_t) buf_ready; + /* + * This virt_rmb() ensures that data from the queue will be read + * after we have determined how much is ready to be consumed. + */ + virt_rmb(); + read = (size_t) (buf_ready > buf_size ? buf_size : buf_ready); head = vmci_q_header_consumer_head(produce_q->q_header); if (likely(head + read < consume_q_size)) { |