]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 25 Jul 2017 00:08:16 +0000 (17:08 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 25 Jul 2017 00:08:16 +0000 (17:08 -0700)
added patches:
af_key-fix-sadb_x_ipsecrequest-parsing.patch
ipvs-snat-packet-replies-only-for-nated-connections.patch
md-don-t-use-flush_signals-in-userspace-processes.patch
pci-pm-restore-the-status-of-pci-devices-across-hibernation.patch
usb-cdc-acm-add-device-id-for-quirky-printer.patch
usb-renesas_usbhs-fix-usbhsc_resume-for-usbhsf_runtime_pwctrl.patch
usb-renesas_usbhs-gadget-disable-all-eps-when-the-driver-stops.patch
usb-storage-return-on-error-to-avoid-a-null-pointer-dereference.patch
xhci-fix-20000ms-port-resume-timeout.patch
xhci-fix-null-pointer-dereference-when-cleaning-up-streams-for-removed-host.patch

queue-4.4/af_key-fix-sadb_x_ipsecrequest-parsing.patch [new file with mode: 0644]
queue-4.4/ipvs-snat-packet-replies-only-for-nated-connections.patch [new file with mode: 0644]
queue-4.4/md-don-t-use-flush_signals-in-userspace-processes.patch [new file with mode: 0644]
queue-4.4/pci-pm-restore-the-status-of-pci-devices-across-hibernation.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/usb-cdc-acm-add-device-id-for-quirky-printer.patch [new file with mode: 0644]
queue-4.4/usb-renesas_usbhs-fix-usbhsc_resume-for-usbhsf_runtime_pwctrl.patch [new file with mode: 0644]
queue-4.4/usb-renesas_usbhs-gadget-disable-all-eps-when-the-driver-stops.patch [new file with mode: 0644]
queue-4.4/usb-storage-return-on-error-to-avoid-a-null-pointer-dereference.patch [new file with mode: 0644]
queue-4.4/xhci-fix-20000ms-port-resume-timeout.patch [new file with mode: 0644]
queue-4.4/xhci-fix-null-pointer-dereference-when-cleaning-up-streams-for-removed-host.patch [new file with mode: 0644]

diff --git a/queue-4.4/af_key-fix-sadb_x_ipsecrequest-parsing.patch b/queue-4.4/af_key-fix-sadb_x_ipsecrequest-parsing.patch
new file mode 100644 (file)
index 0000000..3a1792e
--- /dev/null
@@ -0,0 +1,146 @@
+From 096f41d3a8fcbb8dde7f71379b1ca85fe213eded Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Thu, 13 Apr 2017 18:35:59 +0800
+Subject: af_key: Fix sadb_x_ipsecrequest parsing
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+commit 096f41d3a8fcbb8dde7f71379b1ca85fe213eded upstream.
+
+The parsing of sadb_x_ipsecrequest is broken in a number of ways.
+First of all we're not verifying sadb_x_ipsecrequest_len.  This
+is needed when the structure carries addresses at the end.  Worse
+we don't even look at the length when we parse those optional
+addresses.
+
+The migration code had similar parsing code that's better but
+it also has some deficiencies.  The length is overcounted first
+of all as it includes the header itself.  It also fails to check
+the length before dereferencing the sa_family field.
+
+This patch fixes those problems in parse_sockaddr_pair and then
+uses it in parse_ipsecrequest.
+
+Reported-by: Andrey Konovalov <andreyknvl@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/key/af_key.c |   47 ++++++++++++++++++++++++++---------------------
+ 1 file changed, 26 insertions(+), 21 deletions(-)
+
+--- a/net/key/af_key.c
++++ b/net/key/af_key.c
+@@ -65,6 +65,10 @@ struct pfkey_sock {
+       } dump;
+ };
++static int parse_sockaddr_pair(struct sockaddr *sa, int ext_len,
++                             xfrm_address_t *saddr, xfrm_address_t *daddr,
++                             u16 *family);
++
+ static inline struct pfkey_sock *pfkey_sk(struct sock *sk)
+ {
+       return (struct pfkey_sock *)sk;
+@@ -1922,19 +1926,14 @@ parse_ipsecrequest(struct xfrm_policy *x
+       /* addresses present only in tunnel mode */
+       if (t->mode == XFRM_MODE_TUNNEL) {
+-              u8 *sa = (u8 *) (rq + 1);
+-              int family, socklen;
++              int err;
+-              family = pfkey_sockaddr_extract((struct sockaddr *)sa,
+-                                              &t->saddr);
+-              if (!family)
+-                      return -EINVAL;
+-
+-              socklen = pfkey_sockaddr_len(family);
+-              if (pfkey_sockaddr_extract((struct sockaddr *)(sa + socklen),
+-                                         &t->id.daddr) != family)
+-                      return -EINVAL;
+-              t->encap_family = family;
++              err = parse_sockaddr_pair(
++                      (struct sockaddr *)(rq + 1),
++                      rq->sadb_x_ipsecrequest_len - sizeof(*rq),
++                      &t->saddr, &t->id.daddr, &t->encap_family);
++              if (err)
++                      return err;
+       } else
+               t->encap_family = xp->family;
+@@ -1954,7 +1953,11 @@ parse_ipsecrequests(struct xfrm_policy *
+       if (pol->sadb_x_policy_len * 8 < sizeof(struct sadb_x_policy))
+               return -EINVAL;
+-      while (len >= sizeof(struct sadb_x_ipsecrequest)) {
++      while (len >= sizeof(*rq)) {
++              if (len < rq->sadb_x_ipsecrequest_len ||
++                  rq->sadb_x_ipsecrequest_len < sizeof(*rq))
++                      return -EINVAL;
++
+               if ((err = parse_ipsecrequest(xp, rq)) < 0)
+                       return err;
+               len -= rq->sadb_x_ipsecrequest_len;
+@@ -2417,7 +2420,6 @@ out:
+       return err;
+ }
+-#ifdef CONFIG_NET_KEY_MIGRATE
+ static int pfkey_sockaddr_pair_size(sa_family_t family)
+ {
+       return PFKEY_ALIGN8(pfkey_sockaddr_len(family) * 2);
+@@ -2429,7 +2431,7 @@ static int parse_sockaddr_pair(struct so
+ {
+       int af, socklen;
+-      if (ext_len < pfkey_sockaddr_pair_size(sa->sa_family))
++      if (ext_len < 2 || ext_len < pfkey_sockaddr_pair_size(sa->sa_family))
+               return -EINVAL;
+       af = pfkey_sockaddr_extract(sa, saddr);
+@@ -2445,6 +2447,7 @@ static int parse_sockaddr_pair(struct so
+       return 0;
+ }
++#ifdef CONFIG_NET_KEY_MIGRATE
+ static int ipsecrequests_to_migrate(struct sadb_x_ipsecrequest *rq1, int len,
+                                   struct xfrm_migrate *m)
+ {
+@@ -2452,13 +2455,14 @@ static int ipsecrequests_to_migrate(stru
+       struct sadb_x_ipsecrequest *rq2;
+       int mode;
+-      if (len <= sizeof(struct sadb_x_ipsecrequest) ||
+-          len < rq1->sadb_x_ipsecrequest_len)
++      if (len < sizeof(*rq1) ||
++          len < rq1->sadb_x_ipsecrequest_len ||
++          rq1->sadb_x_ipsecrequest_len < sizeof(*rq1))
+               return -EINVAL;
+       /* old endoints */
+       err = parse_sockaddr_pair((struct sockaddr *)(rq1 + 1),
+-                                rq1->sadb_x_ipsecrequest_len,
++                                rq1->sadb_x_ipsecrequest_len - sizeof(*rq1),
+                                 &m->old_saddr, &m->old_daddr,
+                                 &m->old_family);
+       if (err)
+@@ -2467,13 +2471,14 @@ static int ipsecrequests_to_migrate(stru
+       rq2 = (struct sadb_x_ipsecrequest *)((u8 *)rq1 + rq1->sadb_x_ipsecrequest_len);
+       len -= rq1->sadb_x_ipsecrequest_len;
+-      if (len <= sizeof(struct sadb_x_ipsecrequest) ||
+-          len < rq2->sadb_x_ipsecrequest_len)
++      if (len <= sizeof(*rq2) ||
++          len < rq2->sadb_x_ipsecrequest_len ||
++          rq2->sadb_x_ipsecrequest_len < sizeof(*rq2))
+               return -EINVAL;
+       /* new endpoints */
+       err = parse_sockaddr_pair((struct sockaddr *)(rq2 + 1),
+-                                rq2->sadb_x_ipsecrequest_len,
++                                rq2->sadb_x_ipsecrequest_len - sizeof(*rq2),
+                                 &m->new_saddr, &m->new_daddr,
+                                 &m->new_family);
+       if (err)
diff --git a/queue-4.4/ipvs-snat-packet-replies-only-for-nated-connections.patch b/queue-4.4/ipvs-snat-packet-replies-only-for-nated-connections.patch
new file mode 100644 (file)
index 0000000..ce36985
--- /dev/null
@@ -0,0 +1,95 @@
+From 3c5ab3f395d66a9e4e937fcfdf6ebc63894f028b Mon Sep 17 00:00:00 2001
+From: Julian Anastasov <ja@ssi.bg>
+Date: Sat, 29 Apr 2017 20:33:09 +0300
+Subject: ipvs: SNAT packet replies only for NATed connections
+
+From: Julian Anastasov <ja@ssi.bg>
+
+commit 3c5ab3f395d66a9e4e937fcfdf6ebc63894f028b upstream.
+
+We do not check if packet from real server is for NAT
+connection before performing SNAT. This causes problems
+for setups that use DR/TUN and allow local clients to
+access the real server directly, for example:
+
+- local client in director creates IPVS-DR/TUN connection
+CIP->VIP and the request packets are routed to RIP.
+Talks are finished but IPVS connection is not expired yet.
+
+- second local client creates non-IPVS connection CIP->RIP
+with same reply tuple RIP->CIP and when replies are received
+on LOCAL_IN we wrongly assign them for the first client
+connection because RIP->CIP matches the reply direction.
+As result, IPVS SNATs replies for non-IPVS connections.
+
+The problem is more visible to local UDP clients but in rare
+cases it can happen also for TCP or remote clients when the
+real server sends the reply traffic via the director.
+
+So, better to be more precise for the reply traffic.
+As replies are not expected for DR/TUN connections, better
+to not touch them.
+
+Reported-by: Nick Moriarty <nick.moriarty@york.ac.uk>
+Tested-by: Nick Moriarty <nick.moriarty@york.ac.uk>
+Signed-off-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/ipvs/ip_vs_core.c |   19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+--- a/net/netfilter/ipvs/ip_vs_core.c
++++ b/net/netfilter/ipvs/ip_vs_core.c
+@@ -845,10 +845,8 @@ static int handle_response_icmp(int af,
+ {
+       unsigned int verdict = NF_DROP;
+-      if (IP_VS_FWD_METHOD(cp) != 0) {
+-              pr_err("shouldn't reach here, because the box is on the "
+-                     "half connection in the tun/dr module.\n");
+-      }
++      if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
++              goto ignore_cp;
+       /* Ensure the checksum is correct */
+       if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
+@@ -882,6 +880,8 @@ static int handle_response_icmp(int af,
+               ip_vs_notrack(skb);
+       else
+               ip_vs_update_conntrack(skb, cp, 0);
++
++ignore_cp:
+       verdict = NF_ACCEPT;
+ out:
+@@ -1242,8 +1242,11 @@ ip_vs_out(struct netns_ipvs *ipvs, unsig
+        */
+       cp = pp->conn_out_get(ipvs, af, skb, &iph);
+-      if (likely(cp))
++      if (likely(cp)) {
++              if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
++                      goto ignore_cp;
+               return handle_response(af, skb, pd, cp, &iph, hooknum);
++      }
+       if (sysctl_nat_icmp_send(ipvs) &&
+           (pp->protocol == IPPROTO_TCP ||
+            pp->protocol == IPPROTO_UDP ||
+@@ -1285,9 +1288,15 @@ ip_vs_out(struct netns_ipvs *ipvs, unsig
+                       }
+               }
+       }
++
++out:
+       IP_VS_DBG_PKT(12, af, pp, skb, iph.off,
+                     "ip_vs_out: packet continues traversal as normal");
+       return NF_ACCEPT;
++
++ignore_cp:
++      __ip_vs_conn_put(cp);
++      goto out;
+ }
+ /*
diff --git a/queue-4.4/md-don-t-use-flush_signals-in-userspace-processes.patch b/queue-4.4/md-don-t-use-flush_signals-in-userspace-processes.patch
new file mode 100644 (file)
index 0000000..0580107
--- /dev/null
@@ -0,0 +1,72 @@
+From f9c79bc05a2a91f4fba8bfd653579e066714b1ec Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Wed, 7 Jun 2017 19:05:31 -0400
+Subject: md: don't use flush_signals in userspace processes
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit f9c79bc05a2a91f4fba8bfd653579e066714b1ec upstream.
+
+The function flush_signals clears all pending signals for the process. It
+may be used by kernel threads when we need to prepare a kernel thread for
+responding to signals. However using this function for an userspaces
+processes is incorrect - clearing signals without the program expecting it
+can cause misbehavior.
+
+The raid1 and raid5 code uses flush_signals in its request routine because
+it wants to prepare for an interruptible wait. This patch drops
+flush_signals and uses sigprocmask instead to block all signals (including
+SIGKILL) around the schedule() call. The signals are not lost, but the
+schedule() call won't respond to them.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Acked-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Shaohua Li <shli@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/raid1.c |    5 ++++-
+ drivers/md/raid5.c |    5 ++++-
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -1088,7 +1088,7 @@ static void make_request(struct mddev *m
+                */
+               DEFINE_WAIT(w);
+               for (;;) {
+-                      flush_signals(current);
++                      sigset_t full, old;
+                       prepare_to_wait(&conf->wait_barrier,
+                                       &w, TASK_INTERRUPTIBLE);
+                       if (bio_end_sector(bio) <= mddev->suspend_lo ||
+@@ -1097,7 +1097,10 @@ static void make_request(struct mddev *m
+                            !md_cluster_ops->area_resyncing(mddev, WRITE,
+                                    bio->bi_iter.bi_sector, bio_end_sector(bio))))
+                               break;
++                      sigfillset(&full);
++                      sigprocmask(SIG_BLOCK, &full, &old);
+                       schedule();
++                      sigprocmask(SIG_SETMASK, &old, NULL);
+               }
+               finish_wait(&conf->wait_barrier, &w);
+       }
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -5279,12 +5279,15 @@ static void make_request(struct mddev *m
+                                * userspace, we want an interruptible
+                                * wait.
+                                */
+-                              flush_signals(current);
+                               prepare_to_wait(&conf->wait_for_overlap,
+                                               &w, TASK_INTERRUPTIBLE);
+                               if (logical_sector >= mddev->suspend_lo &&
+                                   logical_sector < mddev->suspend_hi) {
++                                      sigset_t full, old;
++                                      sigfillset(&full);
++                                      sigprocmask(SIG_BLOCK, &full, &old);
+                                       schedule();
++                                      sigprocmask(SIG_SETMASK, &old, NULL);
+                                       do_prepare = true;
+                               }
+                               goto retry;
diff --git a/queue-4.4/pci-pm-restore-the-status-of-pci-devices-across-hibernation.patch b/queue-4.4/pci-pm-restore-the-status-of-pci-devices-across-hibernation.patch
new file mode 100644 (file)
index 0000000..1cde6ee
--- /dev/null
@@ -0,0 +1,93 @@
+From e60514bd4485c0c7c5a7cf779b200ce0b95c70d6 Mon Sep 17 00:00:00 2001
+From: Chen Yu <yu.c.chen@intel.com>
+Date: Thu, 25 May 2017 16:49:07 +0800
+Subject: PCI/PM: Restore the status of PCI devices across hibernation
+
+From: Chen Yu <yu.c.chen@intel.com>
+
+commit e60514bd4485c0c7c5a7cf779b200ce0b95c70d6 upstream.
+
+Currently we saw a lot of "No irq handler" errors during hibernation, which
+caused the system hang finally:
+
+  ata4.00: qc timeout (cmd 0xec)
+  ata4.00: failed to IDENTIFY (I/O error, err_mask=0x4)
+  ata4.00: revalidation failed (errno=-5)
+  ata4: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
+  do_IRQ: 31.151 No irq handler for vector
+
+According to above logs, there is an interrupt triggered and it is
+dispatched to CPU31 with a vector number 151, but there is no handler for
+it, thus this IRQ will not get acked and will cause an IRQ flood which
+kills the system.  To be more specific, the 31.151 is an interrupt from the
+AHCI host controller.
+
+After some investigation, the reason why this issue is triggered is because
+the thaw_noirq() function does not restore the MSI/MSI-X settings across
+hibernation.
+
+The scenario is illustrated below:
+
+  1. Before hibernation, IRQ 34 is the handler for the AHCI device, which
+     is bound to CPU31.
+
+  2. Hibernation starts, the AHCI device is put into low power state.
+
+  3. All the nonboot CPUs are put offline, so IRQ 34 has to be migrated to
+     the last alive one - CPU0.
+
+  4. After the snapshot has been created, all the nonboot CPUs are brought
+     up again; IRQ 34 remains bound to CPU0.
+
+  5. AHCI devices are put into D0.
+
+  6. The snapshot is written to the disk.
+
+The issue is triggered in step 6.  The AHCI interrupt should be delivered
+to CPU0, however it is delivered to the original CPU31 instead, which
+causes the "No irq handler" issue.
+
+Ying Huang has provided a clue that, in step 3 it is possible that writing
+to the register might not take effect as the PCI devices have been
+suspended.
+
+In step 3, the IRQ 34 affinity should be modified from CPU31 to CPU0, but
+in fact it is not.  In __pci_write_msi_msg(), if the device is already in
+low power state, the low level MSI message entry will not be updated but
+cached.  During the device restore process after a normal suspend/resume,
+pci_restore_msi_state() writes the cached MSI back to the hardware.
+
+But this is not the case for hibernation.  pci_restore_msi_state() is not
+currently called in pci_pm_thaw_noirq(), although pci_save_state() has
+saved the necessary PCI cached information in pci_pm_freeze_noirq().
+
+Restore the PCI status for the device during hibernation.  Otherwise the
+status might be lost across hibernation (for example, settings for MSI,
+MSI-X, ATS, ACS, IOV, etc.), which might cause problems during hibernation.
+
+Suggested-by: Ying Huang <ying.huang@intel.com>
+Suggested-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Chen Yu <yu.c.chen@intel.com>
+[bhelgaas: changelog]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Cc: Len Brown <len.brown@intel.com>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Cc: Rui Zhang <rui.zhang@intel.com>
+Cc: Ying Huang <ying.huang@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/pci-driver.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -945,6 +945,7 @@ static int pci_pm_thaw_noirq(struct devi
+               return pci_legacy_resume_early(dev);
+       pci_update_current_state(pci_dev, PCI_D0);
++      pci_restore_state(pci_dev);
+       if (drv && drv->pm && drv->pm->thaw_noirq)
+               error = drv->pm->thaw_noirq(dev);
index 062535ea3a13cbc46e2d4920051ef20e76cbe37f..552f7832b7629b428d48b10b84eab053296c46af 100644 (file)
@@ -28,3 +28,13 @@ powerpc-64-fix-atomic64_inc_not_zero-to-return-an-int.patch
 powerpc-fix-emulation-of-mcrf-in-emulate_step.patch
 powerpc-fix-emulation-of-mfocrf-in-emulate_step.patch
 powerpc-asm-mark-cr0-as-clobbered-in-mftb.patch
+af_key-fix-sadb_x_ipsecrequest-parsing.patch
+pci-pm-restore-the-status-of-pci-devices-across-hibernation.patch
+ipvs-snat-packet-replies-only-for-nated-connections.patch
+xhci-fix-20000ms-port-resume-timeout.patch
+xhci-fix-null-pointer-dereference-when-cleaning-up-streams-for-removed-host.patch
+usb-storage-return-on-error-to-avoid-a-null-pointer-dereference.patch
+usb-cdc-acm-add-device-id-for-quirky-printer.patch
+usb-renesas_usbhs-fix-usbhsc_resume-for-usbhsf_runtime_pwctrl.patch
+usb-renesas_usbhs-gadget-disable-all-eps-when-the-driver-stops.patch
+md-don-t-use-flush_signals-in-userspace-processes.patch
diff --git a/queue-4.4/usb-cdc-acm-add-device-id-for-quirky-printer.patch b/queue-4.4/usb-cdc-acm-add-device-id-for-quirky-printer.patch
new file mode 100644 (file)
index 0000000..3d0e7ce
--- /dev/null
@@ -0,0 +1,33 @@
+From fe855789d605590e57f9cd968d85ecce46f5c3fd Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 12 Jul 2017 15:08:39 +0200
+Subject: USB: cdc-acm: add device-id for quirky printer
+
+From: Johan Hovold <johan@kernel.org>
+
+commit fe855789d605590e57f9cd968d85ecce46f5c3fd upstream.
+
+Add device-id entry for DATECS FP-2000 fiscal printer needing the
+NO_UNION_NORMAL quirk.
+
+Reported-by: Anton Avramov <lukav@lukav.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Acked-by: Oliver Neukum <oneukum@suse.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
+@@ -1759,6 +1759,9 @@ static const struct usb_device_id acm_id
+       { USB_DEVICE(0x1576, 0x03b1), /* Maretron USB100 */
+       .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
+       },
++      { USB_DEVICE(0xfff0, 0x0100), /* DATECS FP-2000 */
++      .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
++      },
+       { USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */
+       .driver_info = CLEAR_HALT_CONDITIONS,
diff --git a/queue-4.4/usb-renesas_usbhs-fix-usbhsc_resume-for-usbhsf_runtime_pwctrl.patch b/queue-4.4/usb-renesas_usbhs-fix-usbhsc_resume-for-usbhsf_runtime_pwctrl.patch
new file mode 100644 (file)
index 0000000..3f0da8c
--- /dev/null
@@ -0,0 +1,37 @@
+From 59a0879a0e17b2e43ecdc5e3299da85b8410d7ce Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Wed, 19 Jul 2017 16:16:54 +0900
+Subject: usb: renesas_usbhs: fix usbhsc_resume() for !USBHSF_RUNTIME_PWCTRL
+
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+
+commit 59a0879a0e17b2e43ecdc5e3299da85b8410d7ce upstream.
+
+This patch fixes an issue that some registers may be not initialized
+after resume if the USBHSF_RUNTIME_PWCTRL is not set. Otherwise,
+if a cable is not connected, the driver will not enable INTENB0.VBSE
+after resume. And then, the driver cannot detect the VBUS.
+
+Fixes: ca8a282a5373 ("usb: gadget: renesas_usbhs: add suspend/resume support")
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/renesas_usbhs/common.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/renesas_usbhs/common.c
++++ b/drivers/usb/renesas_usbhs/common.c
+@@ -733,8 +733,10 @@ static int usbhsc_resume(struct device *
+       struct usbhs_priv *priv = dev_get_drvdata(dev);
+       struct platform_device *pdev = usbhs_priv_to_pdev(priv);
+-      if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
++      if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) {
+               usbhsc_power_ctrl(priv, 1);
++              usbhs_mod_autonomy_mode(priv);
++      }
+       usbhs_platform_call(priv, phy_reset, pdev);
diff --git a/queue-4.4/usb-renesas_usbhs-gadget-disable-all-eps-when-the-driver-stops.patch b/queue-4.4/usb-renesas_usbhs-gadget-disable-all-eps-when-the-driver-stops.patch
new file mode 100644 (file)
index 0000000..338e9a0
--- /dev/null
@@ -0,0 +1,121 @@
+From b8b9c974afee685789fcbb191b52d1790be3608c Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Wed, 19 Jul 2017 16:16:55 +0900
+Subject: usb: renesas_usbhs: gadget: disable all eps when the driver stops
+
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+
+commit b8b9c974afee685789fcbb191b52d1790be3608c upstream.
+
+A gadget driver will not disable eps immediately when ->disconnect()
+is called. But, since this driver assumes all eps stop after
+the ->disconnect(), unexpected behavior happens (especially in system
+suspend).
+So, this patch disables all eps in usbhsg_try_stop(). After disabling
+eps by renesas_usbhs driver, since some functions will be called by
+both a gadget and renesas_usbhs driver, renesas_usbhs driver should
+protect uep->pipe. To protect uep->pipe easily, this patch adds a new
+lock in struct usbhsg_uep.
+
+Fixes: 2f98382dc ("usb: renesas_usbhs: Add Renesas USBHS Gadget")
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/renesas_usbhs/mod_gadget.c |   31 ++++++++++++++++++++++++-------
+ 1 file changed, 24 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/renesas_usbhs/mod_gadget.c
++++ b/drivers/usb/renesas_usbhs/mod_gadget.c
+@@ -37,6 +37,7 @@ struct usbhsg_gpriv;
+ struct usbhsg_uep {
+       struct usb_ep            ep;
+       struct usbhs_pipe       *pipe;
++      spinlock_t              lock;   /* protect the pipe */
+       char ep_name[EP_NAME_SIZE];
+@@ -638,10 +639,16 @@ usbhsg_ep_enable_end:
+ static int usbhsg_ep_disable(struct usb_ep *ep)
+ {
+       struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
+-      struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
++      struct usbhs_pipe *pipe;
++      unsigned long flags;
++      int ret = 0;
+-      if (!pipe)
+-              return -EINVAL;
++      spin_lock_irqsave(&uep->lock, flags);
++      pipe = usbhsg_uep_to_pipe(uep);
++      if (!pipe) {
++              ret = -EINVAL;
++              goto out;
++      }
+       usbhsg_pipe_disable(uep);
+       usbhs_pipe_free(pipe);
+@@ -649,6 +656,9 @@ static int usbhsg_ep_disable(struct usb_
+       uep->pipe->mod_private  = NULL;
+       uep->pipe               = NULL;
++out:
++      spin_unlock_irqrestore(&uep->lock, flags);
++
+       return 0;
+ }
+@@ -698,8 +708,11 @@ static int usbhsg_ep_dequeue(struct usb_
+ {
+       struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
+       struct usbhsg_request *ureq = usbhsg_req_to_ureq(req);
+-      struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
++      struct usbhs_pipe *pipe;
++      unsigned long flags;
++      spin_lock_irqsave(&uep->lock, flags);
++      pipe = usbhsg_uep_to_pipe(uep);
+       if (pipe)
+               usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq));
+@@ -708,6 +721,7 @@ static int usbhsg_ep_dequeue(struct usb_
+        * even if the pipe is NULL.
+        */
+       usbhsg_queue_pop(uep, ureq, -ECONNRESET);
++      spin_unlock_irqrestore(&uep->lock, flags);
+       return 0;
+ }
+@@ -854,10 +868,10 @@ static int usbhsg_try_stop(struct usbhs_
+ {
+       struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
+       struct usbhs_mod *mod = usbhs_mod_get_current(priv);
+-      struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv);
++      struct usbhsg_uep *uep;
+       struct device *dev = usbhs_priv_to_dev(priv);
+       unsigned long flags;
+-      int ret = 0;
++      int ret = 0, i;
+       /********************  spin lock ********************/
+       usbhs_lock(priv, flags);
+@@ -889,7 +903,9 @@ static int usbhsg_try_stop(struct usbhs_
+       usbhs_sys_set_test_mode(priv, 0);
+       usbhs_sys_function_ctrl(priv, 0);
+-      usbhsg_ep_disable(&dcp->ep);
++      /* disable all eps */
++      usbhsg_for_each_uep_with_dcp(uep, gpriv, i)
++              usbhsg_ep_disable(&uep->ep);
+       dev_dbg(dev, "stop gadget\n");
+@@ -1072,6 +1088,7 @@ int usbhs_mod_gadget_probe(struct usbhs_
+               ret = -ENOMEM;
+               goto usbhs_mod_gadget_probe_err_gpriv;
+       }
++      spin_lock_init(&uep->lock);
+       gpriv->transceiver = usb_get_phy(USB_PHY_TYPE_UNDEFINED);
+       dev_info(dev, "%stransceiver found\n",
diff --git a/queue-4.4/usb-storage-return-on-error-to-avoid-a-null-pointer-dereference.patch b/queue-4.4/usb-storage-return-on-error-to-avoid-a-null-pointer-dereference.patch
new file mode 100644 (file)
index 0000000..5d163f0
--- /dev/null
@@ -0,0 +1,44 @@
+From 446230f52a5bef593554510302465eabab45a372 Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Thu, 6 Jul 2017 16:06:32 +0100
+Subject: usb: storage: return on error to avoid a null pointer dereference
+
+From: Colin Ian King <colin.king@canonical.com>
+
+commit 446230f52a5bef593554510302465eabab45a372 upstream.
+
+When us->extra is null the driver is not initialized, however, a
+later call to osd200_scsi_to_ata is made that dereferences
+us->extra, causing a null pointer dereference.  The code
+currently detects and reports that the driver is not initialized;
+add a return to avoid the subsequent dereference issue in this
+check.
+
+Thanks to Alan Stern for pointing out that srb->result needs setting
+to DID_ERROR << 16
+
+Detected by CoverityScan, CID#100308 ("Dereference after null check")
+
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/storage/isd200.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/storage/isd200.c
++++ b/drivers/usb/storage/isd200.c
+@@ -1520,8 +1520,11 @@ static void isd200_ata_command(struct sc
+       /* Make sure driver was initialized */
+-      if (us->extra == NULL)
++      if (us->extra == NULL) {
+               usb_stor_dbg(us, "ERROR Driver not initialized\n");
++              srb->result = DID_ERROR << 16;
++              return;
++      }
+       scsi_set_resid(srb, 0);
+       /* scsi_bufflen might change in protocol translation to ata */
diff --git a/queue-4.4/xhci-fix-20000ms-port-resume-timeout.patch b/queue-4.4/xhci-fix-20000ms-port-resume-timeout.patch
new file mode 100644 (file)
index 0000000..94c7382
--- /dev/null
@@ -0,0 +1,41 @@
+From a54408d0a004757789863d74e29c2297edae0b4d Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Thu, 20 Jul 2017 14:48:29 +0300
+Subject: xhci: fix 20000ms port resume timeout
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit a54408d0a004757789863d74e29c2297edae0b4d upstream.
+
+A uncleared PLC (port link change) bit will prevent furuther port event
+interrupts for that port. Leaving it uncleared caused get_port_status()
+to timeout after 20000ms while waiting to get the final port event
+interrupt for resume -> U0 state change.
+
+This is a targeted fix for a specific case where we get a port resume event
+racing with xhci resume. The port event interrupt handler notices xHC is
+not yet running and bails out early, leaving PLC uncleared.
+
+The whole xhci port resuming needs more attention, but while working on it
+it anyways makes sense to always ensure PLC is cleared in get_port_status
+before setting a new link state and waiting for its completion.
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-hub.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -768,6 +768,9 @@ static u32 xhci_get_port_status(struct u
+                       clear_bit(wIndex, &bus_state->resuming_ports);
+                       set_bit(wIndex, &bus_state->rexit_ports);
++
++                      xhci_test_and_clear_bit(xhci, port_array, wIndex,
++                                              PORT_PLC);
+                       xhci_set_link_state(xhci, port_array, wIndex,
+                                       XDEV_U0);
diff --git a/queue-4.4/xhci-fix-null-pointer-dereference-when-cleaning-up-streams-for-removed-host.patch b/queue-4.4/xhci-fix-null-pointer-dereference-when-cleaning-up-streams-for-removed-host.patch
new file mode 100644 (file)
index 0000000..9e1b900
--- /dev/null
@@ -0,0 +1,51 @@
+From 4b895868bb2da60a386a17cde3bf9ecbc70c79f4 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Thu, 20 Jul 2017 14:48:26 +0300
+Subject: xhci: Fix NULL pointer dereference when cleaning up streams for removed host
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 4b895868bb2da60a386a17cde3bf9ecbc70c79f4 upstream.
+
+This off by one in stream_id indexing caused NULL pointer dereference and
+soft lockup on machines with USB attached SCSI devices connected to a
+hotpluggable xhci controller.
+
+The code that cleans up pending URBs for dead hosts tried to dereference
+a stream ring at the invalid stream_id 0.
+ep->stream_info->stream_rings[0] doesn't point to a ring.
+
+Start looping stream_id from 1 like in all the other places in the driver,
+and check that the ring exists before trying to kill URBs on it.
+
+Reported-by: rocko r <rockorequin@gmail.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |   11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -856,13 +856,16 @@ static void xhci_kill_endpoint_urbs(stru
+                       (ep->ep_state & EP_GETTING_NO_STREAMS)) {
+               int stream_id;
+-              for (stream_id = 0; stream_id < ep->stream_info->num_streams;
++              for (stream_id = 1; stream_id < ep->stream_info->num_streams;
+                               stream_id++) {
++                      ring = ep->stream_info->stream_rings[stream_id];
++                      if (!ring)
++                              continue;
++
+                       xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
+                                       "Killing URBs for slot ID %u, ep index %u, stream %u",
+-                                      slot_id, ep_index, stream_id + 1);
+-                      xhci_kill_ring_urbs(xhci,
+-                                      ep->stream_info->stream_rings[stream_id]);
++                                      slot_id, ep_index, stream_id);
++                      xhci_kill_ring_urbs(xhci, ring);
+               }
+       } else {
+               ring = ep->ring;