From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757595Ab3HMGub (ORCPT ); Tue, 13 Aug 2013 02:50:31 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:60583 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756861Ab3HMGd3 (ORCPT ); Tue, 13 Aug 2013 02:33:29 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Amit Shah , Rusty Russell Subject: [ 38/60] virtio: console: return -ENODEV on all read operations after unplug Date: Mon, 12 Aug 2013 23:34:05 -0700 Message-Id: <20130813063337.359784188@linuxfoundation.org> X-Mailer: git-send-email 1.8.3.3.825.g36032ce.dirty In-Reply-To: <20130813063331.950321483@linuxfoundation.org> References: <20130813063331.950321483@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.10-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 @@ -749,6 +749,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 @@ -765,7 +769,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; /*