lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <1461164635-8916-2-git-send-email-tomas.winkler@intel.com>
Date:	Wed, 20 Apr 2016 11:03:55 -0400
From:	Tomas Winkler <tomas.winkler@...el.com>
To:	Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Cc:	Alexander Usyskin <alexander.usyskin@...el.com>,
	linux-kernel@...r.kernel.org,
	Tomas Winkler <tomas.winkler@...el.com>
Subject: [char-misc-next 2/2] mei: fix waiting for wr_ctrl for corner cases.

From: Alexander Usyskin <alexander.usyskin@...el.com>

A control message reply may not be received if either a link reset has
occurred or disconnection is initiated by the FW.
In the both cases the client state will be set straight to DISCONNECTED
and the driver will wait till timeout.
Adding DISCONNECTED state in the waiting condition will release the
client from the stall.

Signed-off-by: Alexander Usyskin <alexander.usyskin@...el.com>
Signed-off-by: Tomas Winkler <tomas.winkler@...el.com>
---
 drivers/misc/mei/client.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 85ae11d410cc..eed254da63a8 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -727,6 +727,11 @@ static void mei_cl_wake_all(struct mei_cl *cl)
 		cl_dbg(dev, cl, "Waking up waiting for event clients!\n");
 		wake_up_interruptible(&cl->ev_wait);
 	}
+	/* synchronized under device mutex */
+	if (waitqueue_active(&cl->wait)) {
+		cl_dbg(dev, cl, "Waking up ctrl write clients!\n");
+		wake_up_interruptible(&cl->wait);
+	}
 }
 
 /**
@@ -879,12 +884,15 @@ static int __mei_cl_disconnect(struct mei_cl *cl)
 	}
 
 	mutex_unlock(&dev->device_lock);
-	wait_event_timeout(cl->wait, cl->state == MEI_FILE_DISCONNECT_REPLY,
+	wait_event_timeout(cl->wait,
+			   cl->state == MEI_FILE_DISCONNECT_REPLY ||
+			   cl->state == MEI_FILE_DISCONNECTED,
 			   mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
 	mutex_lock(&dev->device_lock);
 
 	rets = cl->status;
-	if (cl->state != MEI_FILE_DISCONNECT_REPLY) {
+	if (cl->state != MEI_FILE_DISCONNECT_REPLY &&
+	    cl->state != MEI_FILE_DISCONNECTED) {
 		cl_dbg(dev, cl, "timeout on disconnect from FW client.\n");
 		rets = -ETIME;
 	}
@@ -1085,6 +1093,7 @@ int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl,
 	mutex_unlock(&dev->device_lock);
 	wait_event_timeout(cl->wait,
 			(cl->state == MEI_FILE_CONNECTED ||
+			 cl->state == MEI_FILE_DISCONNECTED ||
 			 cl->state == MEI_FILE_DISCONNECT_REQUIRED ||
 			 cl->state == MEI_FILE_DISCONNECT_REPLY),
 			mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
@@ -1333,8 +1342,9 @@ int mei_cl_notify_request(struct mei_cl *cl,
 	}
 
 	mutex_unlock(&dev->device_lock);
-	wait_event_timeout(cl->wait, cl->notify_en == request,
-			mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
+	wait_event_timeout(cl->wait,
+			   cl->notify_en == request || !mei_cl_is_connected(cl),
+			   mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
 	mutex_lock(&dev->device_lock);
 
 	if (cl->notify_en != request && !cl->status)
-- 
2.5.5

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ