From a733ded50b6ea846200073e7381a302df71e13b3 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 5 Mar 2017 21:40:41 +0200 Subject: mei: fix deadlock on mei reset This patch fixes 'mei: synchronize irq before initiating a reset' The patch had introduced a deadlock between irq thread and mei_reset() as they are both holding the same device lock. ---> device_lock: mei_reset() <---- interrupt thread device_lock ---> synchornize_irq() wait on interrupt thread == (dead lock) The fix is to call synchronize_irq prior to call locked mei_reset function. Cc: #4.10+ Fixes: f302bb0de6ac (mei: synchronize irq before initiating a reset) Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/init.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index cfb1cdf..13c55b8 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -124,8 +124,6 @@ int mei_reset(struct mei_device *dev) mei_clear_interrupts(dev); - mei_synchronize_irq(dev); - /* we're already in reset, cancel the init timer * if the reset was called due the hbm protocol error * we need to call it before hw start @@ -304,6 +302,9 @@ static void mei_reset_work(struct work_struct *work) container_of(work, struct mei_device, reset_work); int ret; + mei_clear_interrupts(dev); + mei_synchronize_irq(dev); + mutex_lock(&dev->device_lock); ret = mei_reset(dev); @@ -328,6 +329,9 @@ void mei_stop(struct mei_device *dev) mei_cancel_work(dev); + mei_clear_interrupts(dev); + mei_synchronize_irq(dev); + mutex_lock(&dev->device_lock); dev->dev_state = MEI_DEV_POWER_DOWN; -- cgit v1.1 From c6240cacdb2c3cb56a21fb3ea0c105154ab87a2a Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Sun, 5 Mar 2017 21:40:42 +0200 Subject: mei: don't wait for os version message reply The driver still struggles with firmwares that do not replay to the OS version request. It is safe not waiting for the replay. First, the driver doesn't do anything with the replay second the connection is closed immediately, hence the packet will be just safely discarded in case it is received and last the driver won't get stuck if the firmware won't reply. Cc: #4.10+ Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/bus-fixup.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c index 3600c99..29f2dae 100644 --- a/drivers/misc/mei/bus-fixup.c +++ b/drivers/misc/mei/bus-fixup.c @@ -112,11 +112,9 @@ struct mkhi_msg { static int mei_osver(struct mei_cl_device *cldev) { - int ret; const size_t size = sizeof(struct mkhi_msg_hdr) + sizeof(struct mkhi_fwcaps) + sizeof(struct mei_os_ver); - size_t length = 8; char buf[size]; struct mkhi_msg *req; struct mkhi_fwcaps *fwcaps; @@ -137,15 +135,7 @@ static int mei_osver(struct mei_cl_device *cldev) os_ver = (struct mei_os_ver *)fwcaps->data; os_ver->os_type = OSTYPE_LINUX; - ret = __mei_cl_send(cldev->cl, buf, size, mode); - if (ret < 0) - return ret; - - ret = __mei_cl_recv(cldev->cl, buf, length, 0); - if (ret < 0) - return ret; - - return 0; + return __mei_cl_send(cldev->cl, buf, size, mode); } static void mei_mkhi_fix(struct mei_cl_device *cldev) @@ -160,7 +150,7 @@ static void mei_mkhi_fix(struct mei_cl_device *cldev) return; ret = mei_osver(cldev); - if (ret) + if (ret < 0) dev_err(&cldev->dev, "OS version command failed %d\n", ret); mei_cldev_disable(cldev); -- cgit v1.1 From c3423563c68fc454b805b46cb69fd4816db933e2 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 3 Mar 2017 07:58:06 -0700 Subject: vmw_vmci: handle the return value from pci_alloc_irq_vectors correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It returns the number of vectors allocated when successful, so check for a negative error only. Fixes: 3bb434cd ("vmw_vmci: switch to pci_irq_alloc_vectors") Signed-off-by: Christoph Hellwig Reported-by: Loïc Yhuel Signed-off-by: Greg Kroah-Hartman --- drivers/misc/vmw_vmci/vmci_guest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c index 9d65954..dad5abe 100644 --- a/drivers/misc/vmw_vmci/vmci_guest.c +++ b/drivers/misc/vmw_vmci/vmci_guest.c @@ -566,10 +566,10 @@ static int vmci_guest_probe_device(struct pci_dev *pdev, */ error = pci_alloc_irq_vectors(pdev, VMCI_MAX_INTRS, VMCI_MAX_INTRS, PCI_IRQ_MSIX); - if (error) { + if (error < 0) { error = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX | PCI_IRQ_MSI | PCI_IRQ_LEGACY); - if (error) + if (error < 0) goto err_remove_bitmap; } else { vmci_dev->exclusive_vectors = true; -- cgit v1.1