From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757627Ab3HMGfE (ORCPT ); Tue, 13 Aug 2013 02:35:04 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:60853 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757602Ab3HMGfA (ORCPT ); Tue, 13 Aug 2013 02:35:00 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Amit Shah , Rusty Russell Subject: [ 09/17] virtio: console: return -ENODEV on all read operations after unplug Date: Mon, 12 Aug 2013 23:35:55 -0700 Message-Id: <20130813063502.484186083@linuxfoundation.org> X-Mailer: git-send-email 1.8.3.3.825.g36032ce.dirty In-Reply-To: <20130813063501.728847844@linuxfoundation.org> References: <20130813063501.728847844@linuxfoundation.org> User-Agent: quilt/0.60-1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Amit Shah commit 96f97a83910cdb9d89d127c5ee523f8fc040a804 upstream. If a port gets unplugged while a user is blocked on read(), -ENODEV is returned. However, subsequent read()s returned 0, indicating there's no host-side connection (but not indicating the device went away). This also happened when a port was unplugged and the user didn't have any blocking operation pending. If the user didn't monitor the SIGIO signal, they won't have a chance to find out if the port went away. Fix by returning -ENODEV on all read()s after the port gets unplugged. write() already behaves this way. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell Signed-off-by: Greg Kroah-Hartman --- drivers/char/virtio_console.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -633,6 +633,10 @@ static ssize_t port_fops_read(struct fil port = filp->private_data; + /* Port is hot-unplugged. */ + if (!port->guest_connected) + return -ENODEV; + if (!port_has_data(port)) { /* * If nothing's connected on the host just return 0 in @@ -649,7 +653,7 @@ static ssize_t port_fops_read(struct fil if (ret < 0) return ret; } - /* Port got hot-unplugged. */ + /* Port got hot-unplugged while we were waiting above. */ if (!port->guest_connected) return -ENODEV; /*