scsi-megaraid_sas-megaraid_sas-driver-init-fails-in-kdump-kernel.patch
ext4-make-sure-group-number-is-bumped-after-a-inode-allocation-race.patch
hwmon-adt7470-fix-incorrect-return-code-check.patch
+virtio-console-fix-race-with-port-unplug-and-open-close.patch
+virtio-console-fix-race-in-port_fops_open-and-port-unplug.patch
+virtio-console-clean-up-port-data-immediately-at-time-of-unplug.patch
+virtio-console-fix-raising-sigio-after-port-unplug.patch
+virtio-console-return-enodev-on-all-read-operations-after-unplug.patch
--- /dev/null
+From ea3768b4386a8d1790f4cc9a35de4f55b92d6442 Mon Sep 17 00:00:00 2001
+From: Amit Shah <amit.shah@redhat.com>
+Date: Mon, 29 Jul 2013 14:20:29 +0930
+Subject: virtio: console: clean up port data immediately at time of unplug
+
+From: Amit Shah <amit.shah@redhat.com>
+
+commit ea3768b4386a8d1790f4cc9a35de4f55b92d6442 upstream.
+
+We used to keep the port's char device structs and the /sys entries
+around till the last reference to the port was dropped. This is
+actually unnecessary, and resulted in buggy behaviour:
+
+1. Open port in guest
+2. Hot-unplug port
+3. Hot-plug a port with the same 'name' property as the unplugged one
+
+This resulted in hot-plug being unsuccessful, as a port with the same
+name already exists (even though it was unplugged).
+
+This behaviour resulted in a warning message like this one:
+
+-------------------8<---------------------------------------
+WARNING: at fs/sysfs/dir.c:512 sysfs_add_one+0xc9/0x130() (Not tainted)
+Hardware name: KVM
+sysfs: cannot create duplicate filename
+'/devices/pci0000:00/0000:00:04.0/virtio0/virtio-ports/vport0p1'
+
+Call Trace:
+ [<ffffffff8106b607>] ? warn_slowpath_common+0x87/0xc0
+ [<ffffffff8106b6f6>] ? warn_slowpath_fmt+0x46/0x50
+ [<ffffffff811f2319>] ? sysfs_add_one+0xc9/0x130
+ [<ffffffff811f23e8>] ? create_dir+0x68/0xb0
+ [<ffffffff811f2469>] ? sysfs_create_dir+0x39/0x50
+ [<ffffffff81273129>] ? kobject_add_internal+0xb9/0x260
+ [<ffffffff812733d8>] ? kobject_add_varg+0x38/0x60
+ [<ffffffff812734b4>] ? kobject_add+0x44/0x70
+ [<ffffffff81349de4>] ? get_device_parent+0xf4/0x1d0
+ [<ffffffff8134b389>] ? device_add+0xc9/0x650
+
+-------------------8<---------------------------------------
+
+Instead of relying on guest applications to release all references to
+the ports, we should go ahead and unregister the port from all the core
+layers. Any open/read calls on the port will then just return errors,
+and an unplug/plug operation on the host will succeed as expected.
+
+This also caused buggy behaviour in case of the device removal (not just
+a port): when the device was removed (which means all ports on that
+device are removed automatically as well), the ports with active
+users would clean up only when the last references were dropped -- and
+it would be too late then to be referencing char device pointers,
+resulting in oopses:
+
+-------------------8<---------------------------------------
+PID: 6162 TASK: ffff8801147ad500 CPU: 0 COMMAND: "cat"
+ #0 [ffff88011b9d5a90] machine_kexec at ffffffff8103232b
+ #1 [ffff88011b9d5af0] crash_kexec at ffffffff810b9322
+ #2 [ffff88011b9d5bc0] oops_end at ffffffff814f4a50
+ #3 [ffff88011b9d5bf0] die at ffffffff8100f26b
+ #4 [ffff88011b9d5c20] do_general_protection at ffffffff814f45e2
+ #5 [ffff88011b9d5c50] general_protection at ffffffff814f3db5
+ [exception RIP: strlen+2]
+ RIP: ffffffff81272ae2 RSP: ffff88011b9d5d00 RFLAGS: 00010246
+ RAX: 0000000000000000 RBX: ffff880118901c18 RCX: 0000000000000000
+ RDX: ffff88011799982c RSI: 00000000000000d0 RDI: 3a303030302f3030
+ RBP: ffff88011b9d5d38 R8: 0000000000000006 R9: ffffffffa0134500
+ R10: 0000000000001000 R11: 0000000000001000 R12: ffff880117a1cc10
+ R13: 00000000000000d0 R14: 0000000000000017 R15: ffffffff81aff700
+ ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
+ #6 [ffff88011b9d5d00] kobject_get_path at ffffffff8126dc5d
+ #7 [ffff88011b9d5d40] kobject_uevent_env at ffffffff8126e551
+ #8 [ffff88011b9d5dd0] kobject_uevent at ffffffff8126e9eb
+ #9 [ffff88011b9d5de0] device_del at ffffffff813440c7
+
+-------------------8<---------------------------------------
+
+So clean up when we have all the context, and all that's left to do when
+the references to the port have dropped is to free up the port struct
+itself.
+
+Reported-by: chayang <chayang@redhat.com>
+Reported-by: YOGANANTH SUBRAMANIAN <anantyog@in.ibm.com>
+Reported-by: FuXiangChun <xfu@redhat.com>
+Reported-by: Qunfang Zhang <qzhang@redhat.com>
+Reported-by: Sibiao Luo <sluo@redhat.com>
+Signed-off-by: Amit Shah <amit.shah@redhat.com>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/virtio_console.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -1257,14 +1257,6 @@ static void remove_port(struct kref *kre
+
+ port = container_of(kref, struct port, kref);
+
+- sysfs_remove_group(&port->dev->kobj, &port_attribute_group);
+- device_destroy(pdrvdata.class, port->dev->devt);
+- cdev_del(port->cdev);
+-
+- kfree(port->name);
+-
+- debugfs_remove(port->debugfs_file);
+-
+ kfree(port);
+ }
+
+@@ -1318,6 +1310,14 @@ static void unplug_port(struct port *por
+ */
+ port->portdev = NULL;
+
++ sysfs_remove_group(&port->dev->kobj, &port_attribute_group);
++ device_destroy(pdrvdata.class, port->dev->devt);
++ cdev_del(port->cdev);
++
++ kfree(port->name);
++
++ debugfs_remove(port->debugfs_file);
++
+ /*
+ * Locks around here are not necessary - a port can't be
+ * opened after we removed the port struct from ports_list
--- /dev/null
+From 671bdea2b9f210566610603ecbb6584c8a201c8c Mon Sep 17 00:00:00 2001
+From: Amit Shah <amit.shah@redhat.com>
+Date: Mon, 29 Jul 2013 14:17:13 +0930
+Subject: virtio: console: fix race in port_fops_open() and port unplug
+
+From: Amit Shah <amit.shah@redhat.com>
+
+commit 671bdea2b9f210566610603ecbb6584c8a201c8c upstream.
+
+Between open() being called and processed, the port can be unplugged.
+Check if this happened, and bail out.
+
+A simple test script to reproduce this is:
+
+while true; do for i in $(seq 1 100); do echo $i > /dev/vport0p3; done; done;
+
+This opens and closes the port a lot of times; unplugging the port while
+this is happening triggers the bug.
+
+Signed-off-by: Amit Shah <amit.shah@redhat.com>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/virtio_console.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -794,6 +794,10 @@ static int port_fops_open(struct inode *
+
+ /* We get the port with a kref here */
+ port = find_port_by_devt(cdev->dev);
++ if (!port) {
++ /* Port was unplugged before we could proceed */
++ return -ENXIO;
++ }
+ filp->private_data = port;
+
+ /*
--- /dev/null
+From 057b82be3ca3d066478e43b162fc082930a746c9 Mon Sep 17 00:00:00 2001
+From: Amit Shah <amit.shah@redhat.com>
+Date: Mon, 29 Jul 2013 14:16:13 +0930
+Subject: virtio: console: fix race with port unplug and open/close
+
+From: Amit Shah <amit.shah@redhat.com>
+
+commit 057b82be3ca3d066478e43b162fc082930a746c9 upstream.
+
+There's a window between find_port_by_devt() returning a port and us
+taking a kref on the port, where the port could get unplugged. Fix it
+by taking the reference in find_port_by_devt() itself.
+
+Problem reported and analyzed by Mateusz Guzik.
+
+Reported-by: Mateusz Guzik <mguzik@redhat.com>
+Signed-off-by: Amit Shah <amit.shah@redhat.com>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/virtio_console.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -256,9 +256,12 @@ static struct port *find_port_by_devt_in
+ unsigned long flags;
+
+ spin_lock_irqsave(&portdev->ports_lock, flags);
+- list_for_each_entry(port, &portdev->ports, list)
+- if (port->cdev->dev == dev)
++ list_for_each_entry(port, &portdev->ports, list) {
++ if (port->cdev->dev == dev) {
++ kref_get(&port->kref);
+ goto out;
++ }
++ }
+ port = NULL;
+ out:
+ spin_unlock_irqrestore(&portdev->ports_lock, flags);
+@@ -789,14 +792,10 @@ static int port_fops_open(struct inode *
+ struct port *port;
+ int ret;
+
++ /* We get the port with a kref here */
+ port = find_port_by_devt(cdev->dev);
+ filp->private_data = port;
+
+- /* Prevent against a port getting hot-unplugged at the same time */
+- spin_lock_irq(&port->portdev->ports_lock);
+- kref_get(&port->kref);
+- spin_unlock_irq(&port->portdev->ports_lock);
+-
+ /*
+ * Don't allow opening of console port devices -- that's done
+ * via /dev/hvc
--- /dev/null
+From 92d3453815fbe74d539c86b60dab39ecdf01bb99 Mon Sep 17 00:00:00 2001
+From: Amit Shah <amit.shah@redhat.com>
+Date: Mon, 29 Jul 2013 14:21:32 +0930
+Subject: virtio: console: fix raising SIGIO after port unplug
+
+From: Amit Shah <amit.shah@redhat.com>
+
+commit 92d3453815fbe74d539c86b60dab39ecdf01bb99 upstream.
+
+SIGIO should be sent when a port gets unplugged. It should only be sent
+to prcesses that have the port opened, and have asked for SIGIO to be
+delivered. We were clearing out guest_connected before calling
+send_sigio_to_port(), resulting in a sigio not getting sent to
+processes.
+
+Fix by setting guest_connected to false after invoking the sigio
+function.
+
+Signed-off-by: Amit Shah <amit.shah@redhat.com>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/virtio_console.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -1286,12 +1286,14 @@ static void unplug_port(struct port *por
+ spin_unlock_irq(&port->portdev->ports_lock);
+
+ if (port->guest_connected) {
++ /* Let the app know the port is going down. */
++ send_sigio_to_port(port);
++
++ /* Do this after sigio is actually sent */
+ port->guest_connected = false;
+ port->host_connected = false;
+- wake_up_interruptible(&port->waitqueue);
+
+- /* Let the app know the port is going down. */
+- send_sigio_to_port(port);
++ wake_up_interruptible(&port->waitqueue);
+ }
+
+ if (is_console_port(port)) {
--- /dev/null
+From 96f97a83910cdb9d89d127c5ee523f8fc040a804 Mon Sep 17 00:00:00 2001
+From: Amit Shah <amit.shah@redhat.com>
+Date: Mon, 29 Jul 2013 14:23:21 +0930
+Subject: virtio: console: return -ENODEV on all read operations after unplug
+
+From: Amit Shah <amit.shah@redhat.com>
+
+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 <amit.shah@redhat.com>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ /*