kvm-lapic-sync-highest-isr-to-hardware-apic-on-eoi.patch
arm-at91-fix-at91_sysirq_mask_rtc-for-sam9x5-socs.patch
mips-kvm-allocate-at-least-16kb-for-exception-handlers.patch
+usb-cdc-acm-fix-write-and-suspend-race.patch
+usb-cdc-acm-fix-write-and-resume-race.patch
+usb-cdc-acm-fix-broken-runtime-suspend.patch
+usb-cdc-acm-fix-runtime-pm-for-control-messages.patch
+usb-cdc-acm-fix-shutdown-and-suspend-race.patch
+usb-cdc-acm-fix-i-o-after-failed-open.patch
+usb-cdc-acm-fix-runtime-pm-imbalance-at-shutdown.patch
--- /dev/null
+From 140cb81ac8c625942a1d695875932c615767a526 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Mon, 26 May 2014 19:23:38 +0200
+Subject: USB: cdc-acm: fix broken runtime suspend
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 140cb81ac8c625942a1d695875932c615767a526 upstream.
+
+The current ACM runtime-suspend implementation is broken in several
+ways:
+
+Firstly, it buffers only the first write request being made while
+suspended -- any further writes are silently dropped.
+
+Secondly, writes being dropped also leak write urbs, which are never
+reclaimed (until the device is unbound).
+
+Thirdly, even the single buffered write is not cleared at shutdown
+(which may happen before the device is resumed), something which can
+lead to another urb leak as well as a PM usage-counter leak.
+
+Fix this by implementing a delayed-write queue using urb anchors and
+making sure to discard the queue properly at shutdown.
+
+Fixes: 11ea859d64b6 ("USB: additional power savings for cdc-acm devices
+that support remote wakeup")
+
+Reported-by: Xiao Jin <jin.xiao@intel.com>
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-acm.c | 32 ++++++++++++++++++++++----------
+ drivers/usb/class/cdc-acm.h | 2 +-
+ 2 files changed, 23 insertions(+), 11 deletions(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -233,12 +233,9 @@ static int acm_write_start(struct acm *a
+ acm->susp_count);
+ usb_autopm_get_interface_async(acm->control);
+ if (acm->susp_count) {
+- if (!acm->delayed_wb)
+- acm->delayed_wb = wb;
+- else
+- usb_autopm_put_interface_async(acm->control);
++ usb_anchor_urb(wb->urb, &acm->delayed);
+ spin_unlock_irqrestore(&acm->write_lock, flags);
+- return 0; /* A white lie */
++ return 0;
+ }
+ usb_mark_last_busy(acm->dev);
+
+@@ -591,6 +588,8 @@ static void acm_port_destruct(struct tty
+ static void acm_port_shutdown(struct tty_port *port)
+ {
+ struct acm *acm = container_of(port, struct acm, port);
++ struct urb *urb;
++ struct acm_wb *wb;
+ int i;
+
+ dev_dbg(&acm->control->dev, "%s\n", __func__);
+@@ -599,6 +598,16 @@ static void acm_port_shutdown(struct tty
+ if (!acm->disconnected) {
+ usb_autopm_get_interface(acm->control);
+ acm_set_control(acm, acm->ctrlout = 0);
++
++ for (;;) {
++ urb = usb_get_from_anchor(&acm->delayed);
++ if (!urb)
++ break;
++ wb = urb->context;
++ wb->use = 0;
++ usb_autopm_put_interface_async(acm->control);
++ }
++
+ usb_kill_urb(acm->ctrlurb);
+ for (i = 0; i < ACM_NW; i++)
+ usb_kill_urb(acm->wb[i].urb);
+@@ -1190,6 +1199,7 @@ made_compressed_probe:
+ acm->bInterval = epread->bInterval;
+ tty_port_init(&acm->port);
+ acm->port.ops = &acm_port_ops;
++ init_usb_anchor(&acm->delayed);
+
+ buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
+ if (!buf) {
+@@ -1459,7 +1469,7 @@ static int acm_suspend(struct usb_interf
+ static int acm_resume(struct usb_interface *intf)
+ {
+ struct acm *acm = usb_get_intfdata(intf);
+- struct acm_wb *wb;
++ struct urb *urb;
+ int rv = 0;
+
+ spin_lock_irq(&acm->read_lock);
+@@ -1471,10 +1481,12 @@ static int acm_resume(struct usb_interfa
+ if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) {
+ rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC);
+
+- if (acm->delayed_wb) {
+- wb = acm->delayed_wb;
+- acm->delayed_wb = NULL;
+- acm_start_wb(acm, wb);
++ for (;;) {
++ urb = usb_get_from_anchor(&acm->delayed);
++ if (!urb)
++ break;
++
++ acm_start_wb(acm, urb->context);
+ }
+
+ /*
+--- a/drivers/usb/class/cdc-acm.h
++++ b/drivers/usb/class/cdc-acm.h
+@@ -117,7 +117,7 @@ struct acm {
+ unsigned int throttled:1; /* actually throttled */
+ unsigned int throttle_req:1; /* throttle requested */
+ u8 bInterval;
+- struct acm_wb *delayed_wb; /* write queued for a device about to be woken */
++ struct usb_anchor delayed; /* writes queued for a device about to be woken */
+ };
+
+ #define CDC_DATA_INTERFACE_TYPE 0x0a
--- /dev/null
+From e4c36076c2a6195ec62c35b03c3fde84d0087dc8 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Mon, 26 May 2014 19:23:44 +0200
+Subject: USB: cdc-acm: fix I/O after failed open
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit e4c36076c2a6195ec62c35b03c3fde84d0087dc8 upstream.
+
+Make sure to kill any already submitted read urbs on read-urb submission
+failures in open in order to prevent doing I/O for a closed port.
+
+Fixes: 088c64f81284 ("USB: cdc-acm: re-write read processing")
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-acm.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -523,6 +523,7 @@ static int acm_port_activate(struct tty_
+ {
+ struct acm *acm = container_of(port, struct acm, port);
+ int retval = -ENODEV;
++ int i;
+
+ dev_dbg(&acm->control->dev, "%s\n", __func__);
+
+@@ -571,6 +572,8 @@ static int acm_port_activate(struct tty_
+ return 0;
+
+ error_submit_read_urbs:
++ for (i = 0; i < acm->rx_buflimit; i++)
++ usb_kill_urb(acm->read_urbs[i]);
+ acm->ctrlout = 0;
+ acm_set_control(acm, acm->ctrlout);
+ error_set_control:
--- /dev/null
+From bae3f4c53585e9a170da9436e0f06919874bda9a Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Mon, 26 May 2014 19:23:39 +0200
+Subject: USB: cdc-acm: fix runtime PM for control messages
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit bae3f4c53585e9a170da9436e0f06919874bda9a upstream.
+
+Fix runtime PM handling of control messages by adding the required PM
+counter operations.
+
+Fixes: 11ea859d64b6 ("USB: additional power savings for cdc-acm devices
+that support remote wakeup")
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-acm.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -122,13 +122,23 @@ static void acm_release_minor(struct acm
+ static int acm_ctrl_msg(struct acm *acm, int request, int value,
+ void *buf, int len)
+ {
+- int retval = usb_control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0),
++ int retval;
++
++ retval = usb_autopm_get_interface(acm->control);
++ if (retval)
++ return retval;
++
++ retval = usb_control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0),
+ request, USB_RT_ACM, value,
+ acm->control->altsetting[0].desc.bInterfaceNumber,
+ buf, len, 5000);
++
+ dev_dbg(&acm->control->dev,
+ "%s - rq 0x%02x, val %#x, len %#x, result %d\n",
+ __func__, request, value, len, retval);
++
++ usb_autopm_put_interface(acm->control);
++
+ return retval < 0 ? retval : 0;
+ }
+
--- /dev/null
+From 5292afa657d0e790b7479ad8eef9450c1e040b3d Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Mon, 26 May 2014 19:23:45 +0200
+Subject: USB: cdc-acm: fix runtime PM imbalance at shutdown
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 5292afa657d0e790b7479ad8eef9450c1e040b3d upstream.
+
+Make sure only to decrement the PM counters if they were actually
+incremented.
+
+Note that the USB PM counter, but not necessarily the driver core PM
+counter, is reset when the interface is unbound.
+
+Fixes: 11ea859d64b6 ("USB: additional power savings for cdc-acm devices
+that support remote wakeup")
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-acm.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -604,12 +604,13 @@ static void acm_port_shutdown(struct tty
+ struct urb *urb;
+ struct acm_wb *wb;
+ int i;
++ int pm_err;
+
+ dev_dbg(&acm->control->dev, "%s\n", __func__);
+
+ mutex_lock(&acm->mutex);
+ if (!acm->disconnected) {
+- usb_autopm_get_interface(acm->control);
++ pm_err = usb_autopm_get_interface(acm->control);
+ acm_set_control(acm, acm->ctrlout = 0);
+
+ for (;;) {
+@@ -627,7 +628,8 @@ static void acm_port_shutdown(struct tty
+ for (i = 0; i < acm->rx_buflimit; i++)
+ usb_kill_urb(acm->read_urbs[i]);
+ acm->control->needs_remote_wakeup = 0;
+- usb_autopm_put_interface(acm->control);
++ if (!pm_err)
++ usb_autopm_put_interface(acm->control);
+ }
+ mutex_unlock(&acm->mutex);
+ }
--- /dev/null
+From ed797074031a37bb9bf4a70952fffc606b77274d Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Mon, 26 May 2014 19:23:40 +0200
+Subject: USB: cdc-acm: fix shutdown and suspend race
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit ed797074031a37bb9bf4a70952fffc606b77274d upstream.
+
+We should stop I/O unconditionally at suspend rather than rely on the
+tty-port initialised flag (which is set prior to stopping I/O during
+shutdown) in order to prevent suspend returning with URBs still active.
+
+Fixes: 11ea859d64b6 ("USB: additional power savings for cdc-acm devices
+that support remote wakeup")
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-acm.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1470,8 +1470,7 @@ static int acm_suspend(struct usb_interf
+ if (cnt)
+ return 0;
+
+- if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags))
+- stop_data_traffic(acm);
++ stop_data_traffic(acm);
+
+ return 0;
+ }
--- /dev/null
+From e144ed28bed10684f9aaec6325ed974d53f76110 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Mon, 26 May 2014 19:23:37 +0200
+Subject: USB: cdc-acm: fix write and resume race
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit e144ed28bed10684f9aaec6325ed974d53f76110 upstream.
+
+Fix race between write() and resume() due to improper locking that could
+lead to writes being reordered.
+
+Resume must be done atomically and susp_count be protected by the
+write_lock in order to prevent racing with write(). This could otherwise
+lead to writes being reordered if write() grabs the write_lock after
+susp_count is decremented, but before the delayed urb is submitted.
+
+Fixes: 11ea859d64b6 ("USB: additional power savings for cdc-acm devices
+that support remote wakeup")
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-acm.c | 23 +++++++++--------------
+ 1 file changed, 9 insertions(+), 14 deletions(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1461,27 +1461,20 @@ static int acm_resume(struct usb_interfa
+ struct acm *acm = usb_get_intfdata(intf);
+ struct acm_wb *wb;
+ int rv = 0;
+- int cnt;
+
+ spin_lock_irq(&acm->read_lock);
+- acm->susp_count -= 1;
+- cnt = acm->susp_count;
+- spin_unlock_irq(&acm->read_lock);
++ spin_lock(&acm->write_lock);
+
+- if (cnt)
+- return 0;
++ if (--acm->susp_count)
++ goto out;
+
+ if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) {
+- rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO);
++ rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC);
+
+- spin_lock_irq(&acm->write_lock);
+ if (acm->delayed_wb) {
+ wb = acm->delayed_wb;
+ acm->delayed_wb = NULL;
+- spin_unlock_irq(&acm->write_lock);
+ acm_start_wb(acm, wb);
+- } else {
+- spin_unlock_irq(&acm->write_lock);
+ }
+
+ /*
+@@ -1489,12 +1482,14 @@ static int acm_resume(struct usb_interfa
+ * do the write path at all cost
+ */
+ if (rv < 0)
+- goto err_out;
++ goto out;
+
+- rv = acm_submit_read_urbs(acm, GFP_NOIO);
++ rv = acm_submit_read_urbs(acm, GFP_ATOMIC);
+ }
++out:
++ spin_unlock(&acm->write_lock);
++ spin_unlock_irq(&acm->read_lock);
+
+-err_out:
+ return rv;
+ }
+
--- /dev/null
+From 5a345c20c17d87099224a4be12e69e5bd7023dca Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Mon, 26 May 2014 19:23:36 +0200
+Subject: USB: cdc-acm: fix write and suspend race
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 5a345c20c17d87099224a4be12e69e5bd7023dca upstream.
+
+Fix race between write() and suspend() which could lead to writes being
+dropped (or I/O while suspended) if the device is runtime suspended
+while a write request is being processed.
+
+Specifically, suspend() releases the write_lock after determining the
+device is idle but before incrementing the susp_count, thus leaving a
+window where a concurrent write() can submit an urb.
+
+Fixes: 11ea859d64b6 ("USB: additional power savings for cdc-acm devices
+that support remote wakeup")
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-acm.c | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1434,18 +1434,15 @@ static int acm_suspend(struct usb_interf
+ struct acm *acm = usb_get_intfdata(intf);
+ int cnt;
+
++ spin_lock_irq(&acm->read_lock);
++ spin_lock(&acm->write_lock);
+ if (PMSG_IS_AUTO(message)) {
+- int b;
+-
+- spin_lock_irq(&acm->write_lock);
+- b = acm->transmitting;
+- spin_unlock_irq(&acm->write_lock);
+- if (b)
++ if (acm->transmitting) {
++ spin_unlock(&acm->write_lock);
++ spin_unlock_irq(&acm->read_lock);
+ return -EBUSY;
++ }
+ }
+-
+- spin_lock_irq(&acm->read_lock);
+- spin_lock(&acm->write_lock);
+ cnt = acm->susp_count++;
+ spin_unlock(&acm->write_lock);
+ spin_unlock_irq(&acm->read_lock);