]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 13 Aug 2021 09:03:58 +0000 (11:03 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 13 Aug 2021 09:03:58 +0000 (11:03 +0200)
added patches:
alsa-hda-add-quirk-for-asus-flow-x13.patch
kvm-x86-mmu-use-the-correct-inherited-permissions-to-get-shadow-page.patch
ovl-prevent-private-clone-if-bind-mount-is-not-allowed.patch
ppp-fix-generating-ppp-unit-id-when-ifname-is-not-specified.patch
tracing-reject-string-operand-in-the-histogram-expression.patch
usb-dwc3-gadget-allow-runtime-suspend-if-udc-unbinded.patch
usb-dwc3-gadget-avoid-runtime-resume-if-disabling-pullup.patch
usb-dwc3-gadget-clear-dep-flags-after-stop-transfers-in-ep-disable.patch
usb-dwc3-gadget-disable-gadget-irq-during-pullup-disable.patch
usb-dwc3-gadget-prevent-ep-queuing-while-stopping-transfers.patch
usb-dwc3-gadget-restart-dwc3-gadget-when-enabling-pullup.patch
usb-dwc3-stop-active-transfers-before-halting-the-controller.patch
usb-ehci-fix-kunpeng920-ehci-hardware-problem.patch

15 files changed:
queue-5.4/alsa-hda-add-quirk-for-asus-flow-x13.patch [new file with mode: 0644]
queue-5.4/kvm-x86-mmu-use-the-correct-inherited-permissions-to-get-shadow-page.patch [new file with mode: 0644]
queue-5.4/ovl-prevent-private-clone-if-bind-mount-is-not-allowed.patch [new file with mode: 0644]
queue-5.4/ppp-fix-generating-ppp-unit-id-when-ifname-is-not-specified.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/tracing-reject-string-operand-in-the-histogram-expression.patch [new file with mode: 0644]
queue-5.4/usb-dwc3-gadget-allow-runtime-suspend-if-udc-unbinded.patch [new file with mode: 0644]
queue-5.4/usb-dwc3-gadget-avoid-runtime-resume-if-disabling-pullup.patch [new file with mode: 0644]
queue-5.4/usb-dwc3-gadget-clear-dep-flags-after-stop-transfers-in-ep-disable.patch [new file with mode: 0644]
queue-5.4/usb-dwc3-gadget-disable-gadget-irq-during-pullup-disable.patch [new file with mode: 0644]
queue-5.4/usb-dwc3-gadget-prevent-ep-queuing-while-stopping-transfers.patch [new file with mode: 0644]
queue-5.4/usb-dwc3-gadget-restart-dwc3-gadget-when-enabling-pullup.patch [new file with mode: 0644]
queue-5.4/usb-dwc3-gadget-use-list_replace_init-before-travers.patch [deleted file]
queue-5.4/usb-dwc3-stop-active-transfers-before-halting-the-controller.patch [new file with mode: 0644]
queue-5.4/usb-ehci-fix-kunpeng920-ehci-hardware-problem.patch [new file with mode: 0644]

diff --git a/queue-5.4/alsa-hda-add-quirk-for-asus-flow-x13.patch b/queue-5.4/alsa-hda-add-quirk-for-asus-flow-x13.patch
new file mode 100644 (file)
index 0000000..9bbae39
--- /dev/null
@@ -0,0 +1,31 @@
+From 739d0959fbed23838a96c48fbce01dd2f6fb2c5f Mon Sep 17 00:00:00 2001
+From: Luke D Jones <luke@ljones.dev>
+Date: Sat, 7 Aug 2021 14:58:05 +1200
+Subject: ALSA: hda: Add quirk for ASUS Flow x13
+
+From: Luke D Jones <luke@ljones.dev>
+
+commit 739d0959fbed23838a96c48fbce01dd2f6fb2c5f upstream.
+
+The ASUS GV301QH sound appears to work well with the quirk for
+ALC294_FIXUP_ASUS_DUAL_SPK.
+
+Signed-off-by: Luke D Jones <luke@ljones.dev>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20210807025805.27321-1-luke@ljones.dev
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/patch_realtek.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8122,6 +8122,7 @@ static const struct snd_pci_quirk alc269
+       SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
+       SND_PCI_QUIRK(0x1043, 0x1740, "ASUS UX430UA", ALC295_FIXUP_ASUS_DACS),
+       SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
++      SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK),
+       SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS),
+       SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC),
diff --git a/queue-5.4/kvm-x86-mmu-use-the-correct-inherited-permissions-to-get-shadow-page.patch b/queue-5.4/kvm-x86-mmu-use-the-correct-inherited-permissions-to-get-shadow-page.patch
new file mode 100644 (file)
index 0000000..57d26ac
--- /dev/null
@@ -0,0 +1,153 @@
+From b1bd5cba3306691c771d558e94baa73e8b0b96b7 Mon Sep 17 00:00:00 2001
+From: Lai Jiangshan <laijs@linux.alibaba.com>
+Date: Thu, 3 Jun 2021 13:24:55 +0800
+Subject: KVM: X86: MMU: Use the correct inherited permissions to get shadow page
+
+From: Lai Jiangshan <laijs@linux.alibaba.com>
+
+commit b1bd5cba3306691c771d558e94baa73e8b0b96b7 upstream.
+
+When computing the access permissions of a shadow page, use the effective
+permissions of the walk up to that point, i.e. the logic AND of its parents'
+permissions.  Two guest PxE entries that point at the same table gfn need to
+be shadowed with different shadow pages if their parents' permissions are
+different.  KVM currently uses the effective permissions of the last
+non-leaf entry for all non-leaf entries.  Because all non-leaf SPTEs have
+full ("uwx") permissions, and the effective permissions are recorded only
+in role.access and merged into the leaves, this can lead to incorrect
+reuse of a shadow page and eventually to a missing guest protection page
+fault.
+
+For example, here is a shared pagetable:
+
+   pgd[]   pud[]        pmd[]            virtual address pointers
+                     /->pmd1(u--)->pte1(uw-)->page1 <- ptr1 (u--)
+        /->pud1(uw-)--->pmd2(uw-)->pte2(uw-)->page2 <- ptr2 (uw-)
+   pgd-|           (shared pmd[] as above)
+        \->pud2(u--)--->pmd1(u--)->pte1(uw-)->page1 <- ptr3 (u--)
+                     \->pmd2(uw-)->pte2(uw-)->page2 <- ptr4 (u--)
+
+  pud1 and pud2 point to the same pmd table, so:
+  - ptr1 and ptr3 points to the same page.
+  - ptr2 and ptr4 points to the same page.
+
+(pud1 and pud2 here are pud entries, while pmd1 and pmd2 here are pmd entries)
+
+- First, the guest reads from ptr1 first and KVM prepares a shadow
+  page table with role.access=u--, from ptr1's pud1 and ptr1's pmd1.
+  "u--" comes from the effective permissions of pgd, pud1 and
+  pmd1, which are stored in pt->access.  "u--" is used also to get
+  the pagetable for pud1, instead of "uw-".
+
+- Then the guest writes to ptr2 and KVM reuses pud1 which is present.
+  The hypervisor set up a shadow page for ptr2 with pt->access is "uw-"
+  even though the pud1 pmd (because of the incorrect argument to
+  kvm_mmu_get_page in the previous step) has role.access="u--".
+
+- Then the guest reads from ptr3.  The hypervisor reuses pud1's
+  shadow pmd for pud2, because both use "u--" for their permissions.
+  Thus, the shadow pmd already includes entries for both pmd1 and pmd2.
+
+- At last, the guest writes to ptr4.  This causes no vmexit or pagefault,
+  because pud1's shadow page structures included an "uw-" page even though
+  its role.access was "u--".
+
+Any kind of shared pagetable might have the similar problem when in
+virtual machine without TDP enabled if the permissions are different
+from different ancestors.
+
+In order to fix the problem, we change pt->access to be an array, and
+any access in it will not include permissions ANDed from child ptes.
+
+The test code is: https://lore.kernel.org/kvm/20210603050537.19605-1-jiangshanlai@gmail.com/
+Remember to test it with TDP disabled.
+
+The problem had existed long before the commit 41074d07c78b ("KVM: MMU:
+Fix inherited permissions for emulated guest pte updates"), and it
+is hard to find which is the culprit.  So there is no fixes tag here.
+
+Signed-off-by: Lai Jiangshan <laijs@linux.alibaba.com>
+Message-Id: <20210603052455.21023-1-jiangshanlai@gmail.com>
+Cc: stable@vger.kernel.org
+Fixes: cea0f0e7ea54 ("[PATCH] KVM: MMU: Shadow page table caching")
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+[OP: - apply arch/x86/kvm/mmu/* changes to arch/x86/kvm
+     - apply documentation changes to Documentation/virt/kvm/mmu.txt
+     - adjusted context in arch/x86/kvm/paging_tmpl.h]
+Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/virt/kvm/mmu.txt |    4 ++--
+ arch/x86/kvm/paging_tmpl.h     |   14 +++++++++-----
+ 2 files changed, 11 insertions(+), 7 deletions(-)
+
+--- a/Documentation/virt/kvm/mmu.txt
++++ b/Documentation/virt/kvm/mmu.txt
+@@ -152,8 +152,8 @@ Shadow pages contain the following infor
+     shadow pages) so role.quadrant takes values in the range 0..3.  Each
+     quadrant maps 1GB virtual address space.
+   role.access:
+-    Inherited guest access permissions in the form uwx.  Note execute
+-    permission is positive, not negative.
++    Inherited guest access permissions from the parent ptes in the form uwx.
++    Note execute permission is positive, not negative.
+   role.invalid:
+     The page is invalid and should not be used.  It is a root page that is
+     currently pinned (by a cpu hardware register pointing to it); once it is
+--- a/arch/x86/kvm/paging_tmpl.h
++++ b/arch/x86/kvm/paging_tmpl.h
+@@ -90,8 +90,8 @@ struct guest_walker {
+       gpa_t pte_gpa[PT_MAX_FULL_LEVELS];
+       pt_element_t __user *ptep_user[PT_MAX_FULL_LEVELS];
+       bool pte_writable[PT_MAX_FULL_LEVELS];
+-      unsigned pt_access;
+-      unsigned pte_access;
++      unsigned int pt_access[PT_MAX_FULL_LEVELS];
++      unsigned int pte_access;
+       gfn_t gfn;
+       struct x86_exception fault;
+ };
+@@ -406,13 +406,15 @@ retry_walk:
+               }
+               walker->ptes[walker->level - 1] = pte;
++
++              /* Convert to ACC_*_MASK flags for struct guest_walker.  */
++              walker->pt_access[walker->level - 1] = FNAME(gpte_access)(pt_access ^ walk_nx_mask);
+       } while (!is_last_gpte(mmu, walker->level, pte));
+       pte_pkey = FNAME(gpte_pkeys)(vcpu, pte);
+       accessed_dirty = have_ad ? pte_access & PT_GUEST_ACCESSED_MASK : 0;
+       /* Convert to ACC_*_MASK flags for struct guest_walker.  */
+-      walker->pt_access = FNAME(gpte_access)(pt_access ^ walk_nx_mask);
+       walker->pte_access = FNAME(gpte_access)(pte_access ^ walk_nx_mask);
+       errcode = permission_fault(vcpu, mmu, walker->pte_access, pte_pkey, access);
+       if (unlikely(errcode))
+@@ -451,7 +453,8 @@ retry_walk:
+       }
+       pgprintk("%s: pte %llx pte_access %x pt_access %x\n",
+-               __func__, (u64)pte, walker->pte_access, walker->pt_access);
++               __func__, (u64)pte, walker->pte_access,
++               walker->pt_access[walker->level - 1]);
+       return 1;
+ error:
+@@ -620,7 +623,7 @@ static int FNAME(fetch)(struct kvm_vcpu
+ {
+       struct kvm_mmu_page *sp = NULL;
+       struct kvm_shadow_walk_iterator it;
+-      unsigned direct_access, access = gw->pt_access;
++      unsigned int direct_access, access;
+       int top_level, ret;
+       gfn_t gfn, base_gfn;
+@@ -652,6 +655,7 @@ static int FNAME(fetch)(struct kvm_vcpu
+               sp = NULL;
+               if (!is_shadow_present_pte(*it.sptep)) {
+                       table_gfn = gw->table_gfn[it.level - 2];
++                      access = gw->pt_access[it.level - 2];
+                       sp = kvm_mmu_get_page(vcpu, table_gfn, addr, it.level-1,
+                                             false, access);
+               }
diff --git a/queue-5.4/ovl-prevent-private-clone-if-bind-mount-is-not-allowed.patch b/queue-5.4/ovl-prevent-private-clone-if-bind-mount-is-not-allowed.patch
new file mode 100644 (file)
index 0000000..751a9f1
--- /dev/null
@@ -0,0 +1,97 @@
+From 427215d85e8d1476da1a86b8d67aceb485eb3631 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Mon, 9 Aug 2021 10:19:47 +0200
+Subject: ovl: prevent private clone if bind mount is not allowed
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit 427215d85e8d1476da1a86b8d67aceb485eb3631 upstream.
+
+Add the following checks from __do_loopback() to clone_private_mount() as
+well:
+
+ - verify that the mount is in the current namespace
+
+ - verify that there are no locked children
+
+Reported-by: Alois Wohlschlager <alois1@gmx-topmail.de>
+Fixes: c771d683a62e ("vfs: introduce clone_private_mount()")
+Cc: <stable@vger.kernel.org> # v3.18
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/namespace.c |   42 ++++++++++++++++++++++++++++--------------
+ 1 file changed, 28 insertions(+), 14 deletions(-)
+
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -1861,6 +1861,20 @@ void drop_collected_mounts(struct vfsmou
+       namespace_unlock();
+ }
++static bool has_locked_children(struct mount *mnt, struct dentry *dentry)
++{
++      struct mount *child;
++
++      list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
++              if (!is_subdir(child->mnt_mountpoint, dentry))
++                      continue;
++
++              if (child->mnt.mnt_flags & MNT_LOCKED)
++                      return true;
++      }
++      return false;
++}
++
+ /**
+  * clone_private_mount - create a private clone of a path
+  *
+@@ -1875,14 +1889,27 @@ struct vfsmount *clone_private_mount(con
+       struct mount *old_mnt = real_mount(path->mnt);
+       struct mount *new_mnt;
++      down_read(&namespace_sem);
+       if (IS_MNT_UNBINDABLE(old_mnt))
+-              return ERR_PTR(-EINVAL);
++              goto invalid;
++
++      if (!check_mnt(old_mnt))
++              goto invalid;
++
++      if (has_locked_children(old_mnt, path->dentry))
++              goto invalid;
+       new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE);
++      up_read(&namespace_sem);
++
+       if (IS_ERR(new_mnt))
+               return ERR_CAST(new_mnt);
+       return &new_mnt->mnt;
++
++invalid:
++      up_read(&namespace_sem);
++      return ERR_PTR(-EINVAL);
+ }
+ EXPORT_SYMBOL_GPL(clone_private_mount);
+@@ -2234,19 +2261,6 @@ static int do_change_type(struct path *p
+       return err;
+ }
+-static bool has_locked_children(struct mount *mnt, struct dentry *dentry)
+-{
+-      struct mount *child;
+-      list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
+-              if (!is_subdir(child->mnt_mountpoint, dentry))
+-                      continue;
+-
+-              if (child->mnt.mnt_flags & MNT_LOCKED)
+-                      return true;
+-      }
+-      return false;
+-}
+-
+ static struct mount *__do_loopback(struct path *old_path, int recurse)
+ {
+       struct mount *mnt = ERR_PTR(-EINVAL), *old = real_mount(old_path->mnt);
diff --git a/queue-5.4/ppp-fix-generating-ppp-unit-id-when-ifname-is-not-specified.patch b/queue-5.4/ppp-fix-generating-ppp-unit-id-when-ifname-is-not-specified.patch
new file mode 100644 (file)
index 0000000..39fccf2
--- /dev/null
@@ -0,0 +1,109 @@
+From 3125f26c514826077f2a4490b75e9b1c7a644c42 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
+Date: Sat, 7 Aug 2021 18:00:50 +0200
+Subject: ppp: Fix generating ppp unit id when ifname is not specified
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+commit 3125f26c514826077f2a4490b75e9b1c7a644c42 upstream.
+
+When registering new ppp interface via PPPIOCNEWUNIT ioctl then kernel has
+to choose interface name as this ioctl API does not support specifying it.
+
+Kernel in this case register new interface with name "ppp<id>" where <id>
+is the ppp unit id, which can be obtained via PPPIOCGUNIT ioctl. This
+applies also in the case when registering new ppp interface via rtnl
+without supplying IFLA_IFNAME.
+
+PPPIOCNEWUNIT ioctl allows to specify own ppp unit id which will kernel
+assign to ppp interface, in case this ppp id is not already used by other
+ppp interface.
+
+In case user does not specify ppp unit id then kernel choose the first free
+ppp unit id. This applies also for case when creating ppp interface via
+rtnl method as it does not provide a way for specifying own ppp unit id.
+
+If some network interface (does not have to be ppp) has name "ppp<id>"
+with this first free ppp id then PPPIOCNEWUNIT ioctl or rtnl call fails.
+
+And registering new ppp interface is not possible anymore, until interface
+which holds conflicting name is renamed. Or when using rtnl method with
+custom interface name in IFLA_IFNAME.
+
+As list of allocated / used ppp unit ids is not possible to retrieve from
+kernel to userspace, userspace has no idea what happens nor which interface
+is doing this conflict.
+
+So change the algorithm how ppp unit id is generated. And choose the first
+number which is not neither used as ppp unit id nor in some network
+interface with pattern "ppp<id>".
+
+This issue can be simply reproduced by following pppd call when there is no
+ppp interface registered and also no interface with name pattern "ppp<id>":
+
+    pppd ifname ppp1 +ipv6 noip noauth nolock local nodetach pty "pppd +ipv6 noip noauth nolock local nodetach notty"
+
+Or by creating the one ppp interface (which gets assigned ppp unit id 0),
+renaming it to "ppp1" and then trying to create a new ppp interface (which
+will always fails as next free ppp unit id is 1, but network interface with
+name "ppp1" exists).
+
+This patch fixes above described issue by generating new and new ppp unit
+id until some non-conflicting id with network interfaces is generated.
+
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ppp/ppp_generic.c |   19 +++++++++++++++----
+ 1 file changed, 15 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -283,7 +283,7 @@ static struct channel *ppp_find_channel(
+ static int ppp_connect_channel(struct channel *pch, int unit);
+ static int ppp_disconnect_channel(struct channel *pch);
+ static void ppp_destroy_channel(struct channel *pch);
+-static int unit_get(struct idr *p, void *ptr);
++static int unit_get(struct idr *p, void *ptr, int min);
+ static int unit_set(struct idr *p, void *ptr, int n);
+ static void unit_put(struct idr *p, int n);
+ static void *unit_find(struct idr *p, int n);
+@@ -959,9 +959,20 @@ static int ppp_unit_register(struct ppp
+       mutex_lock(&pn->all_ppp_mutex);
+       if (unit < 0) {
+-              ret = unit_get(&pn->units_idr, ppp);
++              ret = unit_get(&pn->units_idr, ppp, 0);
+               if (ret < 0)
+                       goto err;
++              if (!ifname_is_set) {
++                      while (1) {
++                              snprintf(ppp->dev->name, IFNAMSIZ, "ppp%i", ret);
++                              if (!__dev_get_by_name(ppp->ppp_net, ppp->dev->name))
++                                      break;
++                              unit_put(&pn->units_idr, ret);
++                              ret = unit_get(&pn->units_idr, ppp, ret + 1);
++                              if (ret < 0)
++                                      goto err;
++                      }
++              }
+       } else {
+               /* Caller asked for a specific unit number. Fail with -EEXIST
+                * if unavailable. For backward compatibility, return -EEXIST
+@@ -3294,9 +3305,9 @@ static int unit_set(struct idr *p, void
+ }
+ /* get new free unit number and associate pointer with it */
+-static int unit_get(struct idr *p, void *ptr)
++static int unit_get(struct idr *p, void *ptr, int min)
+ {
+-      return idr_alloc(p, ptr, 0, 0, GFP_KERNEL);
++      return idr_alloc(p, ptr, min, 0, GFP_KERNEL);
+ }
+ /* put unit number back to a pool */
index 42173c2be131f3bd74644163a3bf17b84a8dd1a1..139939da9771cebff7099f0e36de80a20eaa06b8 100644 (file)
@@ -1,4 +1,16 @@
 kvm-svm-fix-off-by-one-indexing-when-nullifying-last.patch
 tee-correct-inappropriate-usage-of-tee_shm_dma_buf-f.patch
-usb-dwc3-gadget-use-list_replace_init-before-travers.patch
 media-v4l2-mem2mem-always-consider-output-queue-during-poll.patch
+tracing-reject-string-operand-in-the-histogram-expression.patch
+usb-dwc3-stop-active-transfers-before-halting-the-controller.patch
+usb-dwc3-gadget-allow-runtime-suspend-if-udc-unbinded.patch
+usb-dwc3-gadget-restart-dwc3-gadget-when-enabling-pullup.patch
+usb-dwc3-gadget-prevent-ep-queuing-while-stopping-transfers.patch
+usb-dwc3-gadget-clear-dep-flags-after-stop-transfers-in-ep-disable.patch
+usb-dwc3-gadget-disable-gadget-irq-during-pullup-disable.patch
+usb-dwc3-gadget-avoid-runtime-resume-if-disabling-pullup.patch
+kvm-x86-mmu-use-the-correct-inherited-permissions-to-get-shadow-page.patch
+usb-ehci-fix-kunpeng920-ehci-hardware-problem.patch
+alsa-hda-add-quirk-for-asus-flow-x13.patch
+ppp-fix-generating-ppp-unit-id-when-ifname-is-not-specified.patch
+ovl-prevent-private-clone-if-bind-mount-is-not-allowed.patch
diff --git a/queue-5.4/tracing-reject-string-operand-in-the-histogram-expression.patch b/queue-5.4/tracing-reject-string-operand-in-the-histogram-expression.patch
new file mode 100644 (file)
index 0000000..0342f71
--- /dev/null
@@ -0,0 +1,74 @@
+From a9d10ca4986571bffc19778742d508cc8dd13e02 Mon Sep 17 00:00:00 2001
+From: Masami Hiramatsu <mhiramat@kernel.org>
+Date: Wed, 28 Jul 2021 07:55:43 +0900
+Subject: tracing: Reject string operand in the histogram expression
+
+From: Masami Hiramatsu <mhiramat@kernel.org>
+
+commit a9d10ca4986571bffc19778742d508cc8dd13e02 upstream.
+
+Since the string type can not be the target of the addition / subtraction
+operation, it must be rejected. Without this fix, the string type silently
+converted to digits.
+
+Link: https://lkml.kernel.org/r/162742654278.290973.1523000673366456634.stgit@devnote2
+
+Cc: stable@vger.kernel.org
+Fixes: 100719dcef447 ("tracing: Add simple expression support to hist triggers")
+Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace_events_hist.c |   20 +++++++++++++++++++-
+ 1 file changed, 19 insertions(+), 1 deletion(-)
+
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -66,7 +66,8 @@
+       C(INVALID_SUBSYS_EVENT, "Invalid subsystem or event name"),     \
+       C(INVALID_REF_KEY,      "Using variable references in keys not supported"), \
+       C(VAR_NOT_FOUND,        "Couldn't find variable"),              \
+-      C(FIELD_NOT_FOUND,      "Couldn't find field"),
++      C(FIELD_NOT_FOUND,      "Couldn't find field"),                 \
++      C(INVALID_STR_OPERAND,  "String type can not be an operand in expression"),
+ #undef C
+ #define C(a, b)               HIST_ERR_##a
+@@ -3038,6 +3039,13 @@ static struct hist_field *parse_unary(st
+               ret = PTR_ERR(operand1);
+               goto free;
+       }
++      if (operand1->flags & HIST_FIELD_FL_STRING) {
++              /* String type can not be the operand of unary operator. */
++              hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(str));
++              destroy_hist_field(operand1, 0);
++              ret = -EINVAL;
++              goto free;
++      }
+       expr->flags |= operand1->flags &
+               (HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS);
+@@ -3139,6 +3147,11 @@ static struct hist_field *parse_expr(str
+               operand1 = NULL;
+               goto free;
+       }
++      if (operand1->flags & HIST_FIELD_FL_STRING) {
++              hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(operand1_str));
++              ret = -EINVAL;
++              goto free;
++      }
+       /* rest of string could be another expression e.g. b+c in a+b+c */
+       operand_flags = 0;
+@@ -3148,6 +3161,11 @@ static struct hist_field *parse_expr(str
+               operand2 = NULL;
+               goto free;
+       }
++      if (operand2->flags & HIST_FIELD_FL_STRING) {
++              hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(str));
++              ret = -EINVAL;
++              goto free;
++      }
+       ret = check_expr_operands(file->tr, operand1, operand2);
+       if (ret)
diff --git a/queue-5.4/usb-dwc3-gadget-allow-runtime-suspend-if-udc-unbinded.patch b/queue-5.4/usb-dwc3-gadget-allow-runtime-suspend-if-udc-unbinded.patch
new file mode 100644 (file)
index 0000000..0e0778a
--- /dev/null
@@ -0,0 +1,60 @@
+From foo@baz Fri Aug 13 10:48:08 AM CEST 2021
+From: Sam Protsenko <semen.protsenko@linaro.org>
+Date: Thu, 12 Aug 2021 20:16:47 +0300
+Subject: usb: dwc3: gadget: Allow runtime suspend if UDC unbinded
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: stable@vger.kernel.org, Wesley Cheng <wcheng@codeaurora.org>
+Message-ID: <20210812171652.23803-3-semen.protsenko@linaro.org>
+
+From: Wesley Cheng <wcheng@codeaurora.org>
+
+[ Upstream commit 77adb8bdf4227257e26b7ff67272678e66a0b250 ]
+
+The DWC3 runtime suspend routine checks for the USB connected parameter to
+determine if the controller can enter into a low power state.  The
+connected state is only set to false after receiving a disconnect event.
+However, in the case of a device initiated disconnect (i.e. UDC unbind),
+the controller is halted and a disconnect event is never generated.  Set
+the connected flag to false if issuing a device initiated disconnect to
+allow the controller to be suspended.
+
+Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
+Link: https://lore.kernel.org/r/1609283136-22140-2-git-send-email-wcheng@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/gadget.c |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -2018,6 +2018,17 @@ static int dwc3_gadget_pullup(struct usb
+       }
+       /*
++       * Check the return value for successful resume, or error.  For a
++       * successful resume, the DWC3 runtime PM resume routine will handle
++       * the run stop sequence, so avoid duplicate operations here.
++       */
++      ret = pm_runtime_get_sync(dwc->dev);
++      if (!ret || ret < 0) {
++              pm_runtime_put(dwc->dev);
++              return 0;
++      }
++
++      /*
+        * Synchronize any pending event handling before executing the controller
+        * halt routine.
+        */
+@@ -2055,10 +2066,12 @@ static int dwc3_gadget_pullup(struct usb
+                       dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) %
+                                               dwc->ev_buf->length;
+               }
++              dwc->connected = false;
+       }
+       ret = dwc3_gadget_run_stop(dwc, is_on, false);
+       spin_unlock_irqrestore(&dwc->lock, flags);
++      pm_runtime_put(dwc->dev);
+       return ret;
+ }
diff --git a/queue-5.4/usb-dwc3-gadget-avoid-runtime-resume-if-disabling-pullup.patch b/queue-5.4/usb-dwc3-gadget-avoid-runtime-resume-if-disabling-pullup.patch
new file mode 100644 (file)
index 0000000..428044e
--- /dev/null
@@ -0,0 +1,69 @@
+From foo@baz Fri Aug 13 10:48:08 AM CEST 2021
+From: Sam Protsenko <semen.protsenko@linaro.org>
+Date: Thu, 12 Aug 2021 20:16:52 +0300
+Subject: usb: dwc3: gadget: Avoid runtime resume if disabling pullup
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: stable@vger.kernel.org, Wesley Cheng <wcheng@codeaurora.org>
+Message-ID: <20210812171652.23803-8-semen.protsenko@linaro.org>
+
+From: Wesley Cheng <wcheng@codeaurora.org>
+
+[ Upstream commit cb10f68ad8150f243964b19391711aaac5e8ff42 ]
+
+If the device is already in the runtime suspended state, any call to
+the pullup routine will issue a runtime resume on the DWC3 core
+device.  If the USB gadget is disabling the pullup, then avoid having
+to issue a runtime resume, as DWC3 gadget has already been
+halted/stopped.
+
+This fixes an issue where the following condition occurs:
+
+usb_gadget_remove_driver()
+-->usb_gadget_disconnect()
+ -->dwc3_gadget_pullup(0)
+  -->pm_runtime_get_sync() -> ret = 0
+  -->pm_runtime_put() [async]
+-->usb_gadget_udc_stop()
+ -->dwc3_gadget_stop()
+  -->dwc->gadget_driver = NULL
+...
+
+dwc3_suspend_common()
+-->dwc3_gadget_suspend()
+ -->DWC3 halt/stop routine skipped, driver_data == NULL
+
+This leads to a situation where the DWC3 gadget is not properly
+stopped, as the runtime resume would have re-enabled EP0 and event
+interrupts, and since we avoided the DWC3 gadget suspend, these
+resources were never disabled.
+
+Fixes: 77adb8bdf422 ("usb: dwc3: gadget: Allow runtime suspend if UDC unbinded")
+Cc: stable <stable@vger.kernel.org>
+Acked-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
+Link: https://lore.kernel.org/r/1628058245-30692-1-git-send-email-wcheng@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/gadget.c |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -2019,6 +2019,17 @@ static int dwc3_gadget_pullup(struct usb
+       }
+       /*
++       * Avoid issuing a runtime resume if the device is already in the
++       * suspended state during gadget disconnect.  DWC3 gadget was already
++       * halted/stopped during runtime suspend.
++       */
++      if (!is_on) {
++              pm_runtime_barrier(dwc->dev);
++              if (pm_runtime_suspended(dwc->dev))
++                      return 0;
++      }
++
++      /*
+        * Check the return value for successful resume, or error.  For a
+        * successful resume, the DWC3 runtime PM resume routine will handle
+        * the run stop sequence, so avoid duplicate operations here.
diff --git a/queue-5.4/usb-dwc3-gadget-clear-dep-flags-after-stop-transfers-in-ep-disable.patch b/queue-5.4/usb-dwc3-gadget-clear-dep-flags-after-stop-transfers-in-ep-disable.patch
new file mode 100644 (file)
index 0000000..b5eb053
--- /dev/null
@@ -0,0 +1,51 @@
+From foo@baz Fri Aug 13 10:48:08 AM CEST 2021
+From: Sam Protsenko <semen.protsenko@linaro.org>
+Date: Thu, 12 Aug 2021 20:16:50 +0300
+Subject: usb: dwc3: gadget: Clear DEP flags after stop transfers in ep disable
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: stable@vger.kernel.org, Wesley Cheng <wcheng@codeaurora.org>
+Message-ID: <20210812171652.23803-6-semen.protsenko@linaro.org>
+
+From: Wesley Cheng <wcheng@codeaurora.org>
+
+[ Upstream commit 5aef629704ad4d983ecf5c8a25840f16e45b6d59 ]
+
+Ensure that dep->flags are cleared until after stop active transfers
+is completed.  Otherwise, the ENDXFER command will not be executed
+during ep disable.
+
+Fixes: f09ddcfcb8c5 ("usb: dwc3: gadget: Prevent EP queuing while stopping transfers")
+Cc: stable <stable@vger.kernel.org>
+Reported-and-tested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
+Link: https://lore.kernel.org/r/1616610664-16495-1-git-send-email-wcheng@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/gadget.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -754,10 +754,6 @@ static int __dwc3_gadget_ep_disable(stru
+       reg &= ~DWC3_DALEPENA_EP(dep->number);
+       dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
+-      dep->stream_capable = false;
+-      dep->type = 0;
+-      dep->flags = 0;
+-
+       /* Clear out the ep descriptors for non-ep0 */
+       if (dep->number > 1) {
+               dep->endpoint.comp_desc = NULL;
+@@ -766,6 +762,10 @@ static int __dwc3_gadget_ep_disable(stru
+       dwc3_remove_requests(dwc, dep);
++      dep->stream_capable = false;
++      dep->type = 0;
++      dep->flags = 0;
++
+       return 0;
+ }
diff --git a/queue-5.4/usb-dwc3-gadget-disable-gadget-irq-during-pullup-disable.patch b/queue-5.4/usb-dwc3-gadget-disable-gadget-irq-during-pullup-disable.patch
new file mode 100644 (file)
index 0000000..d8e80b5
--- /dev/null
@@ -0,0 +1,60 @@
+From foo@baz Fri Aug 13 10:48:08 AM CEST 2021
+From: Sam Protsenko <semen.protsenko@linaro.org>
+Date: Thu, 12 Aug 2021 20:16:51 +0300
+Subject: usb: dwc3: gadget: Disable gadget IRQ during pullup disable
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: stable@vger.kernel.org, Wesley Cheng <wcheng@codeaurora.org>
+Message-ID: <20210812171652.23803-7-semen.protsenko@linaro.org>
+
+From: Wesley Cheng <wcheng@codeaurora.org>
+
+[ Upstream commit 8212937305f84ef73ea81036dafb80c557583d4b ]
+
+Current sequence utilizes dwc3_gadget_disable_irq() alongside
+synchronize_irq() to ensure that no further DWC3 events are generated.
+However, the dwc3_gadget_disable_irq() API only disables device
+specific events.  Endpoint events can still be generated.  Briefly
+disable the interrupt line, so that the cleanup code can run to
+prevent device and endpoint events. (i.e. __dwc3_gadget_stop() and
+dwc3_stop_active_transfers() respectively)
+
+Without doing so, it can lead to both the interrupt handler and the
+pullup disable routine both writing to the GEVNTCOUNT register, which
+will cause an incorrect count being read from future interrupts.
+
+Fixes: ae7e86108b12 ("usb: dwc3: Stop active transfers before halting the controller")
+Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
+Link: https://lore.kernel.org/r/1621571037-1424-1-git-send-email-wcheng@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/gadget.c |   11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -2030,13 +2030,10 @@ static int dwc3_gadget_pullup(struct usb
+       }
+       /*
+-       * Synchronize any pending event handling before executing the controller
+-       * halt routine.
++       * Synchronize and disable any further event handling while controller
++       * is being enabled/disabled.
+        */
+-      if (!is_on) {
+-              dwc3_gadget_disable_irq(dwc);
+-              synchronize_irq(dwc->irq_gadget);
+-      }
++      disable_irq(dwc->irq_gadget);
+       spin_lock_irqsave(&dwc->lock, flags);
+@@ -2074,6 +2071,8 @@ static int dwc3_gadget_pullup(struct usb
+       ret = dwc3_gadget_run_stop(dwc, is_on, false);
+       spin_unlock_irqrestore(&dwc->lock, flags);
++      enable_irq(dwc->irq_gadget);
++
+       pm_runtime_put(dwc->dev);
+       return ret;
diff --git a/queue-5.4/usb-dwc3-gadget-prevent-ep-queuing-while-stopping-transfers.patch b/queue-5.4/usb-dwc3-gadget-prevent-ep-queuing-while-stopping-transfers.patch
new file mode 100644 (file)
index 0000000..fb8c605
--- /dev/null
@@ -0,0 +1,95 @@
+From foo@baz Fri Aug 13 10:48:08 AM CEST 2021
+From: Sam Protsenko <semen.protsenko@linaro.org>
+Date: Thu, 12 Aug 2021 20:16:49 +0300
+Subject: usb: dwc3: gadget: Prevent EP queuing while stopping transfers
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: stable@vger.kernel.org, Wesley Cheng <wcheng@codeaurora.org>
+Message-ID: <20210812171652.23803-5-semen.protsenko@linaro.org>
+
+From: Wesley Cheng <wcheng@codeaurora.org>
+
+[ Upstream commit f09ddcfcb8c569675066337adac2ac205113471f ]
+
+In the situations where the DWC3 gadget stops active transfers, once
+calling the dwc3_gadget_giveback(), there is a chance where a function
+driver can queue a new USB request in between the time where the dwc3
+lock has been released and re-aquired.  This occurs after we've already
+issued an ENDXFER command.  When the stop active transfers continues
+to remove USB requests from all dep lists, the newly added request will
+also be removed, while controller still has an active TRB for it.
+This can lead to the controller accessing an unmapped memory address.
+
+Fix this by ensuring parameters to prevent EP queuing are set before
+calling the stop active transfers API.
+
+Fixes: ae7e86108b12 ("usb: dwc3: Stop active transfers before halting the controller")
+Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
+Link: https://lore.kernel.org/r/1615507142-23097-1-git-send-email-wcheng@codeaurora.org
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/gadget.c |   11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -746,8 +746,6 @@ static int __dwc3_gadget_ep_disable(stru
+       trace_dwc3_gadget_ep_disable(dep);
+-      dwc3_remove_requests(dwc, dep);
+-
+       /* make sure HW endpoint isn't stalled */
+       if (dep->flags & DWC3_EP_STALL)
+               __dwc3_gadget_ep_set_halt(dep, 0, false);
+@@ -766,6 +764,8 @@ static int __dwc3_gadget_ep_disable(stru
+               dep->endpoint.desc = NULL;
+       }
++      dwc3_remove_requests(dwc, dep);
++
+       return 0;
+ }
+@@ -1511,7 +1511,7 @@ static int __dwc3_gadget_ep_queue(struct
+ {
+       struct dwc3             *dwc = dep->dwc;
+-      if (!dep->endpoint.desc || !dwc->pullups_connected) {
++      if (!dep->endpoint.desc || !dwc->pullups_connected || !dwc->connected) {
+               dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n",
+                               dep->name);
+               return -ESHUTDOWN;
+@@ -2043,6 +2043,7 @@ static int dwc3_gadget_pullup(struct usb
+       if (!is_on) {
+               u32 count;
++              dwc->connected = false;
+               /*
+                * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a
+                * Section 4.1.8 Table 4-7, it states that for a device-initiated
+@@ -2067,7 +2068,6 @@ static int dwc3_gadget_pullup(struct usb
+                       dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) %
+                                               dwc->ev_buf->length;
+               }
+-              dwc->connected = false;
+       } else {
+               __dwc3_gadget_start(dwc);
+       }
+@@ -3057,8 +3057,6 @@ static void dwc3_gadget_reset_interrupt(
+ {
+       u32                     reg;
+-      dwc->connected = true;
+-
+       /*
+        * Ideally, dwc3_reset_gadget() would trigger the function
+        * drivers to stop any active transfers through ep disable.
+@@ -3107,6 +3105,7 @@ static void dwc3_gadget_reset_interrupt(
+        * transfers."
+        */
+       dwc3_stop_active_transfers(dwc);
++      dwc->connected = true;
+       reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+       reg &= ~DWC3_DCTL_TSTCTRL_MASK;
diff --git a/queue-5.4/usb-dwc3-gadget-restart-dwc3-gadget-when-enabling-pullup.patch b/queue-5.4/usb-dwc3-gadget-restart-dwc3-gadget-when-enabling-pullup.patch
new file mode 100644 (file)
index 0000000..fd5c3f3
--- /dev/null
@@ -0,0 +1,72 @@
+From foo@baz Fri Aug 13 10:48:08 AM CEST 2021
+From: Sam Protsenko <semen.protsenko@linaro.org>
+Date: Thu, 12 Aug 2021 20:16:48 +0300
+Subject: usb: dwc3: gadget: Restart DWC3 gadget when enabling pullup
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: stable@vger.kernel.org, Wesley Cheng <wcheng@codeaurora.org>
+Message-ID: <20210812171652.23803-4-semen.protsenko@linaro.org>
+
+From: Wesley Cheng <wcheng@codeaurora.org>
+
+[ Upstream commit a1383b3537a7bea1c213baa7878ccc4ecf4413b5 ]
+
+usb_gadget_deactivate/usb_gadget_activate does not execute the UDC start
+operation, which may leave EP0 disabled and event IRQs disabled when
+re-activating the function. Move the enabling/disabling of USB EP0 and
+device event IRQs to be performed in the pullup routine.
+
+Fixes: ae7e86108b12 ("usb: dwc3: Stop active transfers before halting the controller")
+Tested-by: Michael Tretter <m.tretter@pengutronix.de>
+Cc: stable <stable@vger.kernel.org>
+Reported-by: Michael Tretter <m.tretter@pengutronix.de>
+Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
+Link: https://lore.kernel.org/r/1609282837-21666-1-git-send-email-wcheng@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/gadget.c |   14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1993,6 +1993,7 @@ static int dwc3_gadget_run_stop(struct d
+ static void dwc3_gadget_disable_irq(struct dwc3 *dwc);
+ static void __dwc3_gadget_stop(struct dwc3 *dwc);
++static int __dwc3_gadget_start(struct dwc3 *dwc);
+ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
+ {
+@@ -2067,6 +2068,8 @@ static int dwc3_gadget_pullup(struct usb
+                                               dwc->ev_buf->length;
+               }
+               dwc->connected = false;
++      } else {
++              __dwc3_gadget_start(dwc);
+       }
+       ret = dwc3_gadget_run_stop(dwc, is_on, false);
+@@ -2244,10 +2247,6 @@ static int dwc3_gadget_start(struct usb_
+       }
+       dwc->gadget_driver      = driver;
+-
+-      if (pm_runtime_active(dwc->dev))
+-              __dwc3_gadget_start(dwc);
+-
+       spin_unlock_irqrestore(&dwc->lock, flags);
+       return 0;
+@@ -2273,13 +2272,6 @@ static int dwc3_gadget_stop(struct usb_g
+       unsigned long           flags;
+       spin_lock_irqsave(&dwc->lock, flags);
+-
+-      if (pm_runtime_suspended(dwc->dev))
+-              goto out;
+-
+-      __dwc3_gadget_stop(dwc);
+-
+-out:
+       dwc->gadget_driver      = NULL;
+       spin_unlock_irqrestore(&dwc->lock, flags);
diff --git a/queue-5.4/usb-dwc3-gadget-use-list_replace_init-before-travers.patch b/queue-5.4/usb-dwc3-gadget-use-list_replace_init-before-travers.patch
deleted file mode 100644 (file)
index 1ad9182..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-From 3b6405938fd74df7b35ae997af0f481e0ce80d52 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 29 Jul 2021 00:33:14 -0700
-Subject: usb: dwc3: gadget: Use list_replace_init() before traversing lists
-
-From: Wesley Cheng <wcheng@codeaurora.org>
-
-[ Upstream commit d25d85061bd856d6be221626605319154f9b5043 ]
-
-The list_for_each_entry_safe() macro saves the current item (n) and
-the item after (n+1), so that n can be safely removed without
-corrupting the list.  However, when traversing the list and removing
-items using gadget giveback, the DWC3 lock is briefly released,
-allowing other routines to execute.  There is a situation where, while
-items are being removed from the cancelled_list using
-dwc3_gadget_ep_cleanup_cancelled_requests(), the pullup disable
-routine is running in parallel (due to UDC unbind).  As the cleanup
-routine removes n, and the pullup disable removes n+1, once the
-cleanup retakes the DWC3 lock, it references a request who was already
-removed/handled.  With list debug enabled, this leads to a panic.
-Ensure all instances of the macro are replaced where gadget giveback
-is used.
-
-Example call stack:
-
-Thread#1:
-__dwc3_gadget_ep_set_halt() - CLEAR HALT
-  -> dwc3_gadget_ep_cleanup_cancelled_requests()
-    ->list_for_each_entry_safe()
-    ->dwc3_gadget_giveback(n)
-      ->dwc3_gadget_del_and_unmap_request()- n deleted[cancelled_list]
-      ->spin_unlock
-      ->Thread#2 executes
-      ...
-    ->dwc3_gadget_giveback(n+1)
-      ->Already removed!
-
-Thread#2:
-dwc3_gadget_pullup()
-  ->waiting for dwc3 spin_lock
-  ...
-  ->Thread#1 released lock
-  ->dwc3_stop_active_transfers()
-    ->dwc3_remove_requests()
-      ->fetches n+1 item from cancelled_list (n removed by Thread#1)
-      ->dwc3_gadget_giveback()
-        ->dwc3_gadget_del_and_unmap_request()- n+1
-deleted[cancelled_list]
-        ->spin_unlock
-
-Fix this condition by utilizing list_replace_init(), and traversing
-through a local copy of the current elements in the endpoint lists.
-This will also set the parent list as empty, so if another thread is
-also looping through the list, it will be empty on the next iteration.
-
-Fixes: d4f1afe5e896 ("usb: dwc3: gadget: move requests to cancelled_list")
-Cc: stable <stable@vger.kernel.org>
-Acked-by: Felipe Balbi <balbi@kernel.org>
-Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
-Link: https://lore.kernel.org/r/1627543994-20327-1-git-send-email-wcheng@codeaurora.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/usb/dwc3/gadget.c | 18 ++++++++++++++++--
- 1 file changed, 16 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
-index 9cf66636b19d..dd0aff33c7ca 100644
---- a/drivers/usb/dwc3/gadget.c
-+++ b/drivers/usb/dwc3/gadget.c
-@@ -1623,11 +1623,18 @@ static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep)
- {
-       struct dwc3_request             *req;
-       struct dwc3_request             *tmp;
-+      struct list_head                local;
--      list_for_each_entry_safe(req, tmp, &dep->cancelled_list, list) {
-+restart:
-+      list_replace_init(&dep->cancelled_list, &local);
-+
-+      list_for_each_entry_safe(req, tmp, &local, list) {
-               dwc3_gadget_ep_skip_trbs(dep, req);
-               dwc3_gadget_giveback(dep, req, -ECONNRESET);
-       }
-+
-+      if (!list_empty(&dep->cancelled_list))
-+              goto restart;
- }
- static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
-@@ -2684,8 +2691,12 @@ static void dwc3_gadget_ep_cleanup_completed_requests(struct dwc3_ep *dep,
- {
-       struct dwc3_request     *req;
-       struct dwc3_request     *tmp;
-+      struct list_head        local;
--      list_for_each_entry_safe(req, tmp, &dep->started_list, list) {
-+restart:
-+      list_replace_init(&dep->started_list, &local);
-+
-+      list_for_each_entry_safe(req, tmp, &local, list) {
-               int ret;
-               ret = dwc3_gadget_ep_cleanup_completed_request(dep, event,
-@@ -2693,6 +2704,9 @@ static void dwc3_gadget_ep_cleanup_completed_requests(struct dwc3_ep *dep,
-               if (ret)
-                       break;
-       }
-+
-+      if (!list_empty(&dep->started_list))
-+              goto restart;
- }
- static bool dwc3_gadget_ep_should_continue(struct dwc3_ep *dep)
--- 
-2.30.2
-
diff --git a/queue-5.4/usb-dwc3-stop-active-transfers-before-halting-the-controller.patch b/queue-5.4/usb-dwc3-stop-active-transfers-before-halting-the-controller.patch
new file mode 100644 (file)
index 0000000..71ed819
--- /dev/null
@@ -0,0 +1,143 @@
+From foo@baz Fri Aug 13 10:48:40 AM CEST 2021
+From: Sam Protsenko <semen.protsenko@linaro.org>
+Date: Thu, 12 Aug 2021 20:16:46 +0300
+Subject: usb: dwc3: Stop active transfers before halting the controller
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: stable@vger.kernel.org, Wesley Cheng <wcheng@codeaurora.org>
+Message-ID: <20210812171652.23803-2-semen.protsenko@linaro.org>
+
+From: Wesley Cheng <wcheng@codeaurora.org>
+
+[ Upstream commit ae7e86108b12351028fa7e8796a59f9b2d9e1774 ]
+
+In the DWC3 databook, for a device initiated disconnect or bus reset, the
+driver is required to send dependxfer commands for any pending transfers.
+In addition, before the controller can move to the halted state, the SW
+needs to acknowledge any pending events.  If the controller is not halted
+properly, there is a chance the controller will continue accessing stale or
+freed TRBs and buffers.
+
+Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
+Reviewed-by: Thinh Nguyen <thinhn@synopsys.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/ep0.c    |    2 -
+ drivers/usb/dwc3/gadget.c |   66 +++++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 66 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/dwc3/ep0.c
++++ b/drivers/usb/dwc3/ep0.c
+@@ -197,7 +197,7 @@ int dwc3_gadget_ep0_queue(struct usb_ep
+       int                             ret;
+       spin_lock_irqsave(&dwc->lock, flags);
+-      if (!dep->endpoint.desc) {
++      if (!dep->endpoint.desc || !dwc->pullups_connected) {
+               dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n",
+                               dep->name);
+               ret = -ESHUTDOWN;
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1511,7 +1511,7 @@ static int __dwc3_gadget_ep_queue(struct
+ {
+       struct dwc3             *dwc = dep->dwc;
+-      if (!dep->endpoint.desc) {
++      if (!dep->endpoint.desc || !dwc->pullups_connected) {
+               dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n",
+                               dep->name);
+               return -ESHUTDOWN;
+@@ -1931,6 +1931,21 @@ static int dwc3_gadget_set_selfpowered(s
+       return 0;
+ }
++static void dwc3_stop_active_transfers(struct dwc3 *dwc)
++{
++      u32 epnum;
++
++      for (epnum = 2; epnum < dwc->num_eps; epnum++) {
++              struct dwc3_ep *dep;
++
++              dep = dwc->eps[epnum];
++              if (!dep)
++                      continue;
++
++              dwc3_remove_requests(dwc, dep);
++      }
++}
++
+ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
+ {
+       u32                     reg;
+@@ -1976,6 +1991,9 @@ static int dwc3_gadget_run_stop(struct d
+       return 0;
+ }
++static void dwc3_gadget_disable_irq(struct dwc3 *dwc);
++static void __dwc3_gadget_stop(struct dwc3 *dwc);
++
+ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
+ {
+       struct dwc3             *dwc = gadget_to_dwc(g);
+@@ -1999,7 +2017,46 @@ static int dwc3_gadget_pullup(struct usb
+               }
+       }
++      /*
++       * Synchronize any pending event handling before executing the controller
++       * halt routine.
++       */
++      if (!is_on) {
++              dwc3_gadget_disable_irq(dwc);
++              synchronize_irq(dwc->irq_gadget);
++      }
++
+       spin_lock_irqsave(&dwc->lock, flags);
++
++      if (!is_on) {
++              u32 count;
++
++              /*
++               * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a
++               * Section 4.1.8 Table 4-7, it states that for a device-initiated
++               * disconnect, the SW needs to ensure that it sends "a DEPENDXFER
++               * command for any active transfers" before clearing the RunStop
++               * bit.
++               */
++              dwc3_stop_active_transfers(dwc);
++              __dwc3_gadget_stop(dwc);
++
++              /*
++               * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a
++               * Section 1.3.4, it mentions that for the DEVCTRLHLT bit, the
++               * "software needs to acknowledge the events that are generated
++               * (by writing to GEVNTCOUNTn) while it is waiting for this bit
++               * to be set to '1'."
++               */
++              count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
++              count &= DWC3_GEVNTCOUNT_MASK;
++              if (count > 0) {
++                      dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count);
++                      dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) %
++                                              dwc->ev_buf->length;
++              }
++      }
++
+       ret = dwc3_gadget_run_stop(dwc, is_on, false);
+       spin_unlock_irqrestore(&dwc->lock, flags);
+@@ -3038,6 +3095,13 @@ static void dwc3_gadget_reset_interrupt(
+       }
+       dwc3_reset_gadget(dwc);
++      /*
++       * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a
++       * Section 4.1.2 Table 4-2, it states that during a USB reset, the SW
++       * needs to ensure that it sends "a DEPENDXFER command for any active
++       * transfers."
++       */
++      dwc3_stop_active_transfers(dwc);
+       reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+       reg &= ~DWC3_DCTL_TSTCTRL_MASK;
diff --git a/queue-5.4/usb-ehci-fix-kunpeng920-ehci-hardware-problem.patch b/queue-5.4/usb-ehci-fix-kunpeng920-ehci-hardware-problem.patch
new file mode 100644 (file)
index 0000000..2bb3273
--- /dev/null
@@ -0,0 +1,42 @@
+From 26b75952ca0b8b4b3050adb9582c8e2f44d49687 Mon Sep 17 00:00:00 2001
+From: Longfang Liu <liulongfang@huawei.com>
+Date: Fri, 9 Apr 2021 16:48:01 +0800
+Subject: USB:ehci:fix Kunpeng920 ehci hardware problem
+
+From: Longfang Liu <liulongfang@huawei.com>
+
+commit 26b75952ca0b8b4b3050adb9582c8e2f44d49687 upstream.
+
+Kunpeng920's EHCI controller does not have SBRN register.
+Reading the SBRN register when the controller driver is
+initialized will get 0.
+
+When rebooting the EHCI driver, ehci_shutdown() will be called.
+if the sbrn flag is 0, ehci_shutdown() will return directly.
+The sbrn flag being 0 will cause the EHCI interrupt signal to
+not be turned off after reboot. this interrupt that is not closed
+will cause an exception to the device sharing the interrupt.
+
+Therefore, the EHCI controller of Kunpeng920 needs to skip
+the read operation of the SBRN register.
+
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Longfang Liu <liulongfang@huawei.com>
+Link: https://lore.kernel.org/r/1617958081-17999-1-git-send-email-liulongfang@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/ehci-pci.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/host/ehci-pci.c
++++ b/drivers/usb/host/ehci-pci.c
+@@ -298,6 +298,9 @@ static int ehci_pci_setup(struct usb_hcd
+       if (pdev->vendor == PCI_VENDOR_ID_STMICRO
+           && pdev->device == PCI_DEVICE_ID_STMICRO_USB_HOST)
+               ;       /* ConneXT has no sbrn register */
++      else if (pdev->vendor == PCI_VENDOR_ID_HUAWEI
++                       && pdev->device == 0xa239)
++              ;       /* HUAWEI Kunpeng920 USB EHCI has no sbrn register */
+       else
+               pci_read_config_byte(pdev, 0x60, &ehci->sbrn);