]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 21 Jun 2021 10:49:52 +0000 (12:49 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 21 Jun 2021 10:49:52 +0000 (12:49 +0200)
added patches:
arcv2-save-abi-registers-across-signal-handling.patch
can-bcm-fix-infoleak-in-struct-bcm_msg_head.patch
can-bcm-raw-isotp-use-per-module-netdevice-notifier.patch
can-j1939-fix-use-after-free-hold-skb-ref-while-in-use.patch
can-mcba_usb-fix-memory-leak-in-mcba_usb.patch
kvm-x86-fix-x86_emulator-slab-cache-leak.patch
kvm-x86-immediately-reset-the-mmu-context-when-the-smm-flag-is-cleared.patch
kvm-x86-mmu-calculate-and-check-full-mmu_role-for-nested-mmu.patch
pci-aardvark-fix-kernel-panic-during-pio-transfer.patch
pci-add-acs-quirk-for-broadcom-bcm57414-nic.patch
pci-mark-some-nvidia-gpus-to-avoid-bus-reset.patch
pci-mark-ti-c667x-to-avoid-bus-reset.patch
pci-work-around-huawei-intelligent-nic-vf-flr-erratum.patch
s390-ap-fix-hanging-ioctl-caused-by-wrong-msg-counter.patch
s390-mcck-fix-calculation-of-sie-critical-section-size.patch
tracing-do-no-increment-trace_clock_global-by-one.patch
tracing-do-not-stop-recording-cmdlines-when-tracing-is-off.patch
tracing-do-not-stop-recording-comms-if-the-trace-file-is-being-read.patch
usb-chipidea-imx-fix-battery-charger-1.2-cdp-detection.patch
usb-core-hub-disable-autosuspend-for-cypress-cy7c65632.patch

21 files changed:
queue-5.10/arcv2-save-abi-registers-across-signal-handling.patch [new file with mode: 0644]
queue-5.10/can-bcm-fix-infoleak-in-struct-bcm_msg_head.patch [new file with mode: 0644]
queue-5.10/can-bcm-raw-isotp-use-per-module-netdevice-notifier.patch [new file with mode: 0644]
queue-5.10/can-j1939-fix-use-after-free-hold-skb-ref-while-in-use.patch [new file with mode: 0644]
queue-5.10/can-mcba_usb-fix-memory-leak-in-mcba_usb.patch [new file with mode: 0644]
queue-5.10/kvm-x86-fix-x86_emulator-slab-cache-leak.patch [new file with mode: 0644]
queue-5.10/kvm-x86-immediately-reset-the-mmu-context-when-the-smm-flag-is-cleared.patch [new file with mode: 0644]
queue-5.10/kvm-x86-mmu-calculate-and-check-full-mmu_role-for-nested-mmu.patch [new file with mode: 0644]
queue-5.10/pci-aardvark-fix-kernel-panic-during-pio-transfer.patch [new file with mode: 0644]
queue-5.10/pci-add-acs-quirk-for-broadcom-bcm57414-nic.patch [new file with mode: 0644]
queue-5.10/pci-mark-some-nvidia-gpus-to-avoid-bus-reset.patch [new file with mode: 0644]
queue-5.10/pci-mark-ti-c667x-to-avoid-bus-reset.patch [new file with mode: 0644]
queue-5.10/pci-work-around-huawei-intelligent-nic-vf-flr-erratum.patch [new file with mode: 0644]
queue-5.10/s390-ap-fix-hanging-ioctl-caused-by-wrong-msg-counter.patch [new file with mode: 0644]
queue-5.10/s390-mcck-fix-calculation-of-sie-critical-section-size.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/tracing-do-no-increment-trace_clock_global-by-one.patch [new file with mode: 0644]
queue-5.10/tracing-do-not-stop-recording-cmdlines-when-tracing-is-off.patch [new file with mode: 0644]
queue-5.10/tracing-do-not-stop-recording-comms-if-the-trace-file-is-being-read.patch [new file with mode: 0644]
queue-5.10/usb-chipidea-imx-fix-battery-charger-1.2-cdp-detection.patch [new file with mode: 0644]
queue-5.10/usb-core-hub-disable-autosuspend-for-cypress-cy7c65632.patch [new file with mode: 0644]

diff --git a/queue-5.10/arcv2-save-abi-registers-across-signal-handling.patch b/queue-5.10/arcv2-save-abi-registers-across-signal-handling.patch
new file mode 100644 (file)
index 0000000..7855dbe
--- /dev/null
@@ -0,0 +1,112 @@
+From 96f1b00138cb8f04c742c82d0a7c460b2202e887 Mon Sep 17 00:00:00 2001
+From: Vineet Gupta <vgupta@synopsys.com>
+Date: Tue, 8 Jun 2021 19:39:25 -0700
+Subject: ARCv2: save ABI registers across signal handling
+
+From: Vineet Gupta <vgupta@synopsys.com>
+
+commit 96f1b00138cb8f04c742c82d0a7c460b2202e887 upstream.
+
+ARCv2 has some configuration dependent registers (r30, r58, r59) which
+could be targetted by the compiler. To keep the ABI stable, these were
+unconditionally part of the glibc ABI
+(sysdeps/unix/sysv/linux/arc/sys/ucontext.h:mcontext_t) however we
+missed populating them (by saving/restoring them across signal
+handling).
+
+This patch fixes the issue by
+ - adding arcv2 ABI regs to kernel struct sigcontext
+ - populating them during signal handling
+
+Change to struct sigcontext might seem like a glibc ABI change (although
+it primarily uses ucontext_t:mcontext_t) but the fact is
+ - it has only been extended (existing fields are not touched)
+ - the old sigcontext was ABI incomplete to begin with anyways
+
+Fixes: https://github.com/foss-for-synopsys-dwc-arc-processors/linux/issues/53
+Cc: <stable@vger.kernel.org>
+Tested-by: kernel test robot <lkp@intel.com>
+Reported-by: Vladimir Isaev <isaev@synopsys.com>
+Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arc/include/uapi/asm/sigcontext.h |    1 
+ arch/arc/kernel/signal.c               |   43 +++++++++++++++++++++++++++++++++
+ 2 files changed, 44 insertions(+)
+
+--- a/arch/arc/include/uapi/asm/sigcontext.h
++++ b/arch/arc/include/uapi/asm/sigcontext.h
+@@ -18,6 +18,7 @@
+  */
+ struct sigcontext {
+       struct user_regs_struct regs;
++      struct user_regs_arcv2 v2abi;
+ };
+ #endif /* _ASM_ARC_SIGCONTEXT_H */
+--- a/arch/arc/kernel/signal.c
++++ b/arch/arc/kernel/signal.c
+@@ -61,6 +61,41 @@ struct rt_sigframe {
+       unsigned int sigret_magic;
+ };
++static int save_arcv2_regs(struct sigcontext *mctx, struct pt_regs *regs)
++{
++      int err = 0;
++#ifndef CONFIG_ISA_ARCOMPACT
++      struct user_regs_arcv2 v2abi;
++
++      v2abi.r30 = regs->r30;
++#ifdef CONFIG_ARC_HAS_ACCL_REGS
++      v2abi.r58 = regs->r58;
++      v2abi.r59 = regs->r59;
++#else
++      v2abi.r58 = v2abi.r59 = 0;
++#endif
++      err = __copy_to_user(&mctx->v2abi, &v2abi, sizeof(v2abi));
++#endif
++      return err;
++}
++
++static int restore_arcv2_regs(struct sigcontext *mctx, struct pt_regs *regs)
++{
++      int err = 0;
++#ifndef CONFIG_ISA_ARCOMPACT
++      struct user_regs_arcv2 v2abi;
++
++      err = __copy_from_user(&v2abi, &mctx->v2abi, sizeof(v2abi));
++
++      regs->r30 = v2abi.r30;
++#ifdef CONFIG_ARC_HAS_ACCL_REGS
++      regs->r58 = v2abi.r58;
++      regs->r59 = v2abi.r59;
++#endif
++#endif
++      return err;
++}
++
+ static int
+ stash_usr_regs(struct rt_sigframe __user *sf, struct pt_regs *regs,
+              sigset_t *set)
+@@ -94,6 +129,10 @@ stash_usr_regs(struct rt_sigframe __user
+       err = __copy_to_user(&(sf->uc.uc_mcontext.regs.scratch), &uregs.scratch,
+                            sizeof(sf->uc.uc_mcontext.regs.scratch));
++
++      if (is_isa_arcv2())
++              err |= save_arcv2_regs(&(sf->uc.uc_mcontext), regs);
++
+       err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(sigset_t));
+       return err ? -EFAULT : 0;
+@@ -109,6 +148,10 @@ static int restore_usr_regs(struct pt_re
+       err |= __copy_from_user(&uregs.scratch,
+                               &(sf->uc.uc_mcontext.regs.scratch),
+                               sizeof(sf->uc.uc_mcontext.regs.scratch));
++
++      if (is_isa_arcv2())
++              err |= restore_arcv2_regs(&(sf->uc.uc_mcontext), regs);
++
+       if (err)
+               return -EFAULT;
diff --git a/queue-5.10/can-bcm-fix-infoleak-in-struct-bcm_msg_head.patch b/queue-5.10/can-bcm-fix-infoleak-in-struct-bcm_msg_head.patch
new file mode 100644 (file)
index 0000000..504270f
--- /dev/null
@@ -0,0 +1,51 @@
+From 5e87ddbe3942e27e939bdc02deb8579b0cbd8ecc Mon Sep 17 00:00:00 2001
+From: Norbert Slusarek <nslusarek@gmx.net>
+Date: Sat, 12 Jun 2021 22:18:54 +0200
+Subject: can: bcm: fix infoleak in struct bcm_msg_head
+
+From: Norbert Slusarek <nslusarek@gmx.net>
+
+commit 5e87ddbe3942e27e939bdc02deb8579b0cbd8ecc upstream.
+
+On 64-bit systems, struct bcm_msg_head has an added padding of 4 bytes between
+struct members count and ival1. Even though all struct members are initialized,
+the 4-byte hole will contain data from the kernel stack. This patch zeroes out
+struct bcm_msg_head before usage, preventing infoleaks to userspace.
+
+Fixes: ffd980f976e7 ("[CAN]: Add broadcast manager (bcm) protocol")
+Link: https://lore.kernel.org/r/trinity-7c1b2e82-e34f-4885-8060-2cd7a13769ce-1623532166177@3c-app-gmx-bs52
+Cc: linux-stable <stable@vger.kernel.org>
+Signed-off-by: Norbert Slusarek <nslusarek@gmx.net>
+Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/can/bcm.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/can/bcm.c
++++ b/net/can/bcm.c
+@@ -402,6 +402,7 @@ static enum hrtimer_restart bcm_tx_timeo
+               if (!op->count && (op->flags & TX_COUNTEVT)) {
+                       /* create notification to user */
++                      memset(&msg_head, 0, sizeof(msg_head));
+                       msg_head.opcode  = TX_EXPIRED;
+                       msg_head.flags   = op->flags;
+                       msg_head.count   = op->count;
+@@ -439,6 +440,7 @@ static void bcm_rx_changed(struct bcm_op
+       /* this element is not throttled anymore */
+       data->flags &= (BCM_CAN_FLAGS_MASK|RX_RECV);
++      memset(&head, 0, sizeof(head));
+       head.opcode  = RX_CHANGED;
+       head.flags   = op->flags;
+       head.count   = op->count;
+@@ -560,6 +562,7 @@ static enum hrtimer_restart bcm_rx_timeo
+       }
+       /* create notification to user */
++      memset(&msg_head, 0, sizeof(msg_head));
+       msg_head.opcode  = RX_TIMEOUT;
+       msg_head.flags   = op->flags;
+       msg_head.count   = op->count;
diff --git a/queue-5.10/can-bcm-raw-isotp-use-per-module-netdevice-notifier.patch b/queue-5.10/can-bcm-raw-isotp-use-per-module-netdevice-notifier.patch
new file mode 100644 (file)
index 0000000..dbb4544
--- /dev/null
@@ -0,0 +1,429 @@
+From 8d0caedb759683041d9db82069937525999ada53 Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
+Date: Sat, 5 Jun 2021 19:26:35 +0900
+Subject: can: bcm/raw/isotp: use per module netdevice notifier
+
+From: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
+
+commit 8d0caedb759683041d9db82069937525999ada53 upstream.
+
+syzbot is reporting hung task at register_netdevice_notifier() [1] and
+unregister_netdevice_notifier() [2], for cleanup_net() might perform
+time consuming operations while CAN driver's raw/bcm/isotp modules are
+calling {register,unregister}_netdevice_notifier() on each socket.
+
+Change raw/bcm/isotp modules to call register_netdevice_notifier() from
+module's __init function and call unregister_netdevice_notifier() from
+module's __exit function, as with gw/j1939 modules are doing.
+
+Link: https://syzkaller.appspot.com/bug?id=391b9498827788b3cc6830226d4ff5be87107c30 [1]
+Link: https://syzkaller.appspot.com/bug?id=1724d278c83ca6e6df100a2e320c10d991cf2bce [2]
+Link: https://lore.kernel.org/r/54a5f451-05ed-f977-8534-79e7aa2bcc8f@i-love.sakura.ne.jp
+Cc: linux-stable <stable@vger.kernel.org>
+Reported-by: syzbot <syzbot+355f8edb2ff45d5f95fa@syzkaller.appspotmail.com>
+Reported-by: syzbot <syzbot+0f1827363a305f74996f@syzkaller.appspotmail.com>
+Reviewed-by: Kirill Tkhai <ktkhai@virtuozzo.com>
+Tested-by: syzbot <syzbot+355f8edb2ff45d5f95fa@syzkaller.appspotmail.com>
+Tested-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/can/bcm.c   |   59 +++++++++++++++++++++++++++++++++++++++++------------
+ net/can/isotp.c |   61 +++++++++++++++++++++++++++++++++++++++++++------------
+ net/can/raw.c   |   62 +++++++++++++++++++++++++++++++++++++++++++-------------
+ 3 files changed, 142 insertions(+), 40 deletions(-)
+
+--- a/net/can/bcm.c
++++ b/net/can/bcm.c
+@@ -125,7 +125,7 @@ struct bcm_sock {
+       struct sock sk;
+       int bound;
+       int ifindex;
+-      struct notifier_block notifier;
++      struct list_head notifier;
+       struct list_head rx_ops;
+       struct list_head tx_ops;
+       unsigned long dropped_usr_msgs;
+@@ -133,6 +133,10 @@ struct bcm_sock {
+       char procname [32]; /* inode number in decimal with \0 */
+ };
++static LIST_HEAD(bcm_notifier_list);
++static DEFINE_SPINLOCK(bcm_notifier_lock);
++static struct bcm_sock *bcm_busy_notifier;
++
+ static inline struct bcm_sock *bcm_sk(const struct sock *sk)
+ {
+       return (struct bcm_sock *)sk;
+@@ -1381,20 +1385,15 @@ static int bcm_sendmsg(struct socket *so
+ /*
+  * notification handler for netdevice status changes
+  */
+-static int bcm_notifier(struct notifier_block *nb, unsigned long msg,
+-                      void *ptr)
++static void bcm_notify(struct bcm_sock *bo, unsigned long msg,
++                     struct net_device *dev)
+ {
+-      struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+-      struct bcm_sock *bo = container_of(nb, struct bcm_sock, notifier);
+       struct sock *sk = &bo->sk;
+       struct bcm_op *op;
+       int notify_enodev = 0;
+       if (!net_eq(dev_net(dev), sock_net(sk)))
+-              return NOTIFY_DONE;
+-
+-      if (dev->type != ARPHRD_CAN)
+-              return NOTIFY_DONE;
++              return;
+       switch (msg) {
+@@ -1429,7 +1428,28 @@ static int bcm_notifier(struct notifier_
+                               sk->sk_error_report(sk);
+               }
+       }
++}
++static int bcm_notifier(struct notifier_block *nb, unsigned long msg,
++                      void *ptr)
++{
++      struct net_device *dev = netdev_notifier_info_to_dev(ptr);
++
++      if (dev->type != ARPHRD_CAN)
++              return NOTIFY_DONE;
++      if (msg != NETDEV_UNREGISTER && msg != NETDEV_DOWN)
++              return NOTIFY_DONE;
++      if (unlikely(bcm_busy_notifier)) /* Check for reentrant bug. */
++              return NOTIFY_DONE;
++
++      spin_lock(&bcm_notifier_lock);
++      list_for_each_entry(bcm_busy_notifier, &bcm_notifier_list, notifier) {
++              spin_unlock(&bcm_notifier_lock);
++              bcm_notify(bcm_busy_notifier, msg, dev);
++              spin_lock(&bcm_notifier_lock);
++      }
++      bcm_busy_notifier = NULL;
++      spin_unlock(&bcm_notifier_lock);
+       return NOTIFY_DONE;
+ }
+@@ -1449,9 +1469,9 @@ static int bcm_init(struct sock *sk)
+       INIT_LIST_HEAD(&bo->rx_ops);
+       /* set notifier */
+-      bo->notifier.notifier_call = bcm_notifier;
+-
+-      register_netdevice_notifier(&bo->notifier);
++      spin_lock(&bcm_notifier_lock);
++      list_add_tail(&bo->notifier, &bcm_notifier_list);
++      spin_unlock(&bcm_notifier_lock);
+       return 0;
+ }
+@@ -1474,7 +1494,14 @@ static int bcm_release(struct socket *so
+       /* remove bcm_ops, timer, rx_unregister(), etc. */
+-      unregister_netdevice_notifier(&bo->notifier);
++      spin_lock(&bcm_notifier_lock);
++      while (bcm_busy_notifier == bo) {
++              spin_unlock(&bcm_notifier_lock);
++              schedule_timeout_uninterruptible(1);
++              spin_lock(&bcm_notifier_lock);
++      }
++      list_del(&bo->notifier);
++      spin_unlock(&bcm_notifier_lock);
+       lock_sock(sk);
+@@ -1695,6 +1722,10 @@ static struct pernet_operations canbcm_p
+       .exit = canbcm_pernet_exit,
+ };
++static struct notifier_block canbcm_notifier = {
++      .notifier_call = bcm_notifier
++};
++
+ static int __init bcm_module_init(void)
+ {
+       int err;
+@@ -1708,12 +1739,14 @@ static int __init bcm_module_init(void)
+       }
+       register_pernet_subsys(&canbcm_pernet_ops);
++      register_netdevice_notifier(&canbcm_notifier);
+       return 0;
+ }
+ static void __exit bcm_module_exit(void)
+ {
+       can_proto_unregister(&bcm_can_proto);
++      unregister_netdevice_notifier(&canbcm_notifier);
+       unregister_pernet_subsys(&canbcm_pernet_ops);
+ }
+--- a/net/can/isotp.c
++++ b/net/can/isotp.c
+@@ -143,10 +143,14 @@ struct isotp_sock {
+       u32 force_tx_stmin;
+       u32 force_rx_stmin;
+       struct tpcon rx, tx;
+-      struct notifier_block notifier;
++      struct list_head notifier;
+       wait_queue_head_t wait;
+ };
++static LIST_HEAD(isotp_notifier_list);
++static DEFINE_SPINLOCK(isotp_notifier_lock);
++static struct isotp_sock *isotp_busy_notifier;
++
+ static inline struct isotp_sock *isotp_sk(const struct sock *sk)
+ {
+       return (struct isotp_sock *)sk;
+@@ -1008,7 +1012,14 @@ static int isotp_release(struct socket *
+       /* wait for complete transmission of current pdu */
+       wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
+-      unregister_netdevice_notifier(&so->notifier);
++      spin_lock(&isotp_notifier_lock);
++      while (isotp_busy_notifier == so) {
++              spin_unlock(&isotp_notifier_lock);
++              schedule_timeout_uninterruptible(1);
++              spin_lock(&isotp_notifier_lock);
++      }
++      list_del(&so->notifier);
++      spin_unlock(&isotp_notifier_lock);
+       lock_sock(sk);
+@@ -1284,21 +1295,16 @@ static int isotp_getsockopt(struct socke
+       return 0;
+ }
+-static int isotp_notifier(struct notifier_block *nb, unsigned long msg,
+-                        void *ptr)
++static void isotp_notify(struct isotp_sock *so, unsigned long msg,
++                       struct net_device *dev)
+ {
+-      struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+-      struct isotp_sock *so = container_of(nb, struct isotp_sock, notifier);
+       struct sock *sk = &so->sk;
+       if (!net_eq(dev_net(dev), sock_net(sk)))
+-              return NOTIFY_DONE;
+-
+-      if (dev->type != ARPHRD_CAN)
+-              return NOTIFY_DONE;
++              return;
+       if (so->ifindex != dev->ifindex)
+-              return NOTIFY_DONE;
++              return;
+       switch (msg) {
+       case NETDEV_UNREGISTER:
+@@ -1324,7 +1330,28 @@ static int isotp_notifier(struct notifie
+                       sk->sk_error_report(sk);
+               break;
+       }
++}
++static int isotp_notifier(struct notifier_block *nb, unsigned long msg,
++                        void *ptr)
++{
++      struct net_device *dev = netdev_notifier_info_to_dev(ptr);
++
++      if (dev->type != ARPHRD_CAN)
++              return NOTIFY_DONE;
++      if (msg != NETDEV_UNREGISTER && msg != NETDEV_DOWN)
++              return NOTIFY_DONE;
++      if (unlikely(isotp_busy_notifier)) /* Check for reentrant bug. */
++              return NOTIFY_DONE;
++
++      spin_lock(&isotp_notifier_lock);
++      list_for_each_entry(isotp_busy_notifier, &isotp_notifier_list, notifier) {
++              spin_unlock(&isotp_notifier_lock);
++              isotp_notify(isotp_busy_notifier, msg, dev);
++              spin_lock(&isotp_notifier_lock);
++      }
++      isotp_busy_notifier = NULL;
++      spin_unlock(&isotp_notifier_lock);
+       return NOTIFY_DONE;
+ }
+@@ -1361,8 +1388,9 @@ static int isotp_init(struct sock *sk)
+       init_waitqueue_head(&so->wait);
+-      so->notifier.notifier_call = isotp_notifier;
+-      register_netdevice_notifier(&so->notifier);
++      spin_lock(&isotp_notifier_lock);
++      list_add_tail(&so->notifier, &isotp_notifier_list);
++      spin_unlock(&isotp_notifier_lock);
+       return 0;
+ }
+@@ -1409,6 +1437,10 @@ static const struct can_proto isotp_can_
+       .prot = &isotp_proto,
+ };
++static struct notifier_block canisotp_notifier = {
++      .notifier_call = isotp_notifier
++};
++
+ static __init int isotp_module_init(void)
+ {
+       int err;
+@@ -1418,6 +1450,8 @@ static __init int isotp_module_init(void
+       err = can_proto_register(&isotp_can_proto);
+       if (err < 0)
+               pr_err("can: registration of isotp protocol failed\n");
++      else
++              register_netdevice_notifier(&canisotp_notifier);
+       return err;
+ }
+@@ -1425,6 +1459,7 @@ static __init int isotp_module_init(void
+ static __exit void isotp_module_exit(void)
+ {
+       can_proto_unregister(&isotp_can_proto);
++      unregister_netdevice_notifier(&canisotp_notifier);
+ }
+ module_init(isotp_module_init);
+--- a/net/can/raw.c
++++ b/net/can/raw.c
+@@ -83,7 +83,7 @@ struct raw_sock {
+       struct sock sk;
+       int bound;
+       int ifindex;
+-      struct notifier_block notifier;
++      struct list_head notifier;
+       int loopback;
+       int recv_own_msgs;
+       int fd_frames;
+@@ -95,6 +95,10 @@ struct raw_sock {
+       struct uniqframe __percpu *uniq;
+ };
++static LIST_HEAD(raw_notifier_list);
++static DEFINE_SPINLOCK(raw_notifier_lock);
++static struct raw_sock *raw_busy_notifier;
++
+ /* Return pointer to store the extra msg flags for raw_recvmsg().
+  * We use the space of one unsigned int beyond the 'struct sockaddr_can'
+  * in skb->cb.
+@@ -263,21 +267,16 @@ static int raw_enable_allfilters(struct
+       return err;
+ }
+-static int raw_notifier(struct notifier_block *nb,
+-                      unsigned long msg, void *ptr)
++static void raw_notify(struct raw_sock *ro, unsigned long msg,
++                     struct net_device *dev)
+ {
+-      struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+-      struct raw_sock *ro = container_of(nb, struct raw_sock, notifier);
+       struct sock *sk = &ro->sk;
+       if (!net_eq(dev_net(dev), sock_net(sk)))
+-              return NOTIFY_DONE;
+-
+-      if (dev->type != ARPHRD_CAN)
+-              return NOTIFY_DONE;
++              return;
+       if (ro->ifindex != dev->ifindex)
+-              return NOTIFY_DONE;
++              return;
+       switch (msg) {
+       case NETDEV_UNREGISTER:
+@@ -305,7 +304,28 @@ static int raw_notifier(struct notifier_
+                       sk->sk_error_report(sk);
+               break;
+       }
++}
++
++static int raw_notifier(struct notifier_block *nb, unsigned long msg,
++                      void *ptr)
++{
++      struct net_device *dev = netdev_notifier_info_to_dev(ptr);
++
++      if (dev->type != ARPHRD_CAN)
++              return NOTIFY_DONE;
++      if (msg != NETDEV_UNREGISTER && msg != NETDEV_DOWN)
++              return NOTIFY_DONE;
++      if (unlikely(raw_busy_notifier)) /* Check for reentrant bug. */
++              return NOTIFY_DONE;
++      spin_lock(&raw_notifier_lock);
++      list_for_each_entry(raw_busy_notifier, &raw_notifier_list, notifier) {
++              spin_unlock(&raw_notifier_lock);
++              raw_notify(raw_busy_notifier, msg, dev);
++              spin_lock(&raw_notifier_lock);
++      }
++      raw_busy_notifier = NULL;
++      spin_unlock(&raw_notifier_lock);
+       return NOTIFY_DONE;
+ }
+@@ -334,9 +354,9 @@ static int raw_init(struct sock *sk)
+               return -ENOMEM;
+       /* set notifier */
+-      ro->notifier.notifier_call = raw_notifier;
+-
+-      register_netdevice_notifier(&ro->notifier);
++      spin_lock(&raw_notifier_lock);
++      list_add_tail(&ro->notifier, &raw_notifier_list);
++      spin_unlock(&raw_notifier_lock);
+       return 0;
+ }
+@@ -351,7 +371,14 @@ static int raw_release(struct socket *so
+       ro = raw_sk(sk);
+-      unregister_netdevice_notifier(&ro->notifier);
++      spin_lock(&raw_notifier_lock);
++      while (raw_busy_notifier == ro) {
++              spin_unlock(&raw_notifier_lock);
++              schedule_timeout_uninterruptible(1);
++              spin_lock(&raw_notifier_lock);
++      }
++      list_del(&ro->notifier);
++      spin_unlock(&raw_notifier_lock);
+       lock_sock(sk);
+@@ -881,6 +908,10 @@ static const struct can_proto raw_can_pr
+       .prot       = &raw_proto,
+ };
++static struct notifier_block canraw_notifier = {
++      .notifier_call = raw_notifier
++};
++
+ static __init int raw_module_init(void)
+ {
+       int err;
+@@ -890,6 +921,8 @@ static __init int raw_module_init(void)
+       err = can_proto_register(&raw_can_proto);
+       if (err < 0)
+               pr_err("can: registration of raw protocol failed\n");
++      else
++              register_netdevice_notifier(&canraw_notifier);
+       return err;
+ }
+@@ -897,6 +930,7 @@ static __init int raw_module_init(void)
+ static __exit void raw_module_exit(void)
+ {
+       can_proto_unregister(&raw_can_proto);
++      unregister_netdevice_notifier(&canraw_notifier);
+ }
+ module_init(raw_module_init);
diff --git a/queue-5.10/can-j1939-fix-use-after-free-hold-skb-ref-while-in-use.patch b/queue-5.10/can-j1939-fix-use-after-free-hold-skb-ref-while-in-use.patch
new file mode 100644 (file)
index 0000000..f477907
--- /dev/null
@@ -0,0 +1,201 @@
+From 2030043e616cab40f510299f09b636285e0a3678 Mon Sep 17 00:00:00 2001
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+Date: Fri, 21 May 2021 13:57:20 +0200
+Subject: can: j1939: fix Use-after-Free, hold skb ref while in use
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+commit 2030043e616cab40f510299f09b636285e0a3678 upstream.
+
+This patch fixes a Use-after-Free found by the syzbot.
+
+The problem is that a skb is taken from the per-session skb queue,
+without incrementing the ref count. This leads to a Use-after-Free if
+the skb is taken concurrently from the session queue due to a CTS.
+
+Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol")
+Link: https://lore.kernel.org/r/20210521115720.7533-1-o.rempel@pengutronix.de
+Cc: Hillf Danton <hdanton@sina.com>
+Cc: linux-stable <stable@vger.kernel.org>
+Reported-by: syzbot+220c1a29987a9a490903@syzkaller.appspotmail.com
+Reported-by: syzbot+45199c1b73b4013525cf@syzkaller.appspotmail.com
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/can/j1939/transport.c |   54 ++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 40 insertions(+), 14 deletions(-)
+
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -330,6 +330,9 @@ static void j1939_session_skb_drop_old(s
+       if ((do_skcb->offset + do_skb->len) < offset_start) {
+               __skb_unlink(do_skb, &session->skb_queue);
++              /* drop ref taken in j1939_session_skb_queue() */
++              skb_unref(do_skb);
++
+               kfree_skb(do_skb);
+       }
+       spin_unlock_irqrestore(&session->skb_queue.lock, flags);
+@@ -349,12 +352,13 @@ void j1939_session_skb_queue(struct j193
+       skcb->flags |= J1939_ECU_LOCAL_SRC;
++      skb_get(skb);
+       skb_queue_tail(&session->skb_queue, skb);
+ }
+ static struct
+-sk_buff *j1939_session_skb_find_by_offset(struct j1939_session *session,
+-                                        unsigned int offset_start)
++sk_buff *j1939_session_skb_get_by_offset(struct j1939_session *session,
++                                       unsigned int offset_start)
+ {
+       struct j1939_priv *priv = session->priv;
+       struct j1939_sk_buff_cb *do_skcb;
+@@ -371,6 +375,10 @@ sk_buff *j1939_session_skb_find_by_offse
+                       skb = do_skb;
+               }
+       }
++
++      if (skb)
++              skb_get(skb);
++
+       spin_unlock_irqrestore(&session->skb_queue.lock, flags);
+       if (!skb)
+@@ -381,12 +389,12 @@ sk_buff *j1939_session_skb_find_by_offse
+       return skb;
+ }
+-static struct sk_buff *j1939_session_skb_find(struct j1939_session *session)
++static struct sk_buff *j1939_session_skb_get(struct j1939_session *session)
+ {
+       unsigned int offset_start;
+       offset_start = session->pkt.dpo * 7;
+-      return j1939_session_skb_find_by_offset(session, offset_start);
++      return j1939_session_skb_get_by_offset(session, offset_start);
+ }
+ /* see if we are receiver
+@@ -776,7 +784,7 @@ static int j1939_session_tx_dat(struct j
+       int ret = 0;
+       u8 dat[8];
+-      se_skb = j1939_session_skb_find_by_offset(session, session->pkt.tx * 7);
++      se_skb = j1939_session_skb_get_by_offset(session, session->pkt.tx * 7);
+       if (!se_skb)
+               return -ENOBUFS;
+@@ -801,7 +809,8 @@ static int j1939_session_tx_dat(struct j
+                       netdev_err_once(priv->ndev,
+                                       "%s: 0x%p: requested data outside of queued buffer: offset %i, len %i, pkt.tx: %i\n",
+                                       __func__, session, skcb->offset, se_skb->len , session->pkt.tx);
+-                      return -EOVERFLOW;
++                      ret = -EOVERFLOW;
++                      goto out_free;
+               }
+               if (!len) {
+@@ -835,6 +844,12 @@ static int j1939_session_tx_dat(struct j
+       if (pkt_done)
+               j1939_tp_set_rxtimeout(session, 250);
++ out_free:
++      if (ret)
++              kfree_skb(se_skb);
++      else
++              consume_skb(se_skb);
++
+       return ret;
+ }
+@@ -1007,7 +1022,7 @@ static int j1939_xtp_txnext_receiver(str
+ static int j1939_simple_txnext(struct j1939_session *session)
+ {
+       struct j1939_priv *priv = session->priv;
+-      struct sk_buff *se_skb = j1939_session_skb_find(session);
++      struct sk_buff *se_skb = j1939_session_skb_get(session);
+       struct sk_buff *skb;
+       int ret;
+@@ -1015,8 +1030,10 @@ static int j1939_simple_txnext(struct j1
+               return 0;
+       skb = skb_clone(se_skb, GFP_ATOMIC);
+-      if (!skb)
+-              return -ENOMEM;
++      if (!skb) {
++              ret = -ENOMEM;
++              goto out_free;
++      }
+       can_skb_set_owner(skb, se_skb->sk);
+@@ -1024,12 +1041,18 @@ static int j1939_simple_txnext(struct j1
+       ret = j1939_send_one(priv, skb);
+       if (ret)
+-              return ret;
++              goto out_free;
+       j1939_sk_errqueue(session, J1939_ERRQUEUE_SCHED);
+       j1939_sk_queue_activate_next(session);
+-      return 0;
++ out_free:
++      if (ret)
++              kfree_skb(se_skb);
++      else
++              consume_skb(se_skb);
++
++      return ret;
+ }
+ static bool j1939_session_deactivate_locked(struct j1939_session *session)
+@@ -1170,9 +1193,10 @@ static void j1939_session_completed(stru
+       struct sk_buff *skb;
+       if (!session->transmission) {
+-              skb = j1939_session_skb_find(session);
++              skb = j1939_session_skb_get(session);
+               /* distribute among j1939 receivers */
+               j1939_sk_recv(session->priv, skb);
++              consume_skb(skb);
+       }
+       j1939_session_deactivate_activate_next(session);
+@@ -1744,7 +1768,7 @@ static void j1939_xtp_rx_dat_one(struct
+ {
+       struct j1939_priv *priv = session->priv;
+       struct j1939_sk_buff_cb *skcb;
+-      struct sk_buff *se_skb;
++      struct sk_buff *se_skb = NULL;
+       const u8 *dat;
+       u8 *tpdat;
+       int offset;
+@@ -1786,7 +1810,7 @@ static void j1939_xtp_rx_dat_one(struct
+               goto out_session_cancel;
+       }
+-      se_skb = j1939_session_skb_find_by_offset(session, packet * 7);
++      se_skb = j1939_session_skb_get_by_offset(session, packet * 7);
+       if (!se_skb) {
+               netdev_warn(priv->ndev, "%s: 0x%p: no skb found\n", __func__,
+                           session);
+@@ -1848,11 +1872,13 @@ static void j1939_xtp_rx_dat_one(struct
+               j1939_tp_set_rxtimeout(session, 250);
+       }
+       session->last_cmd = 0xff;
++      consume_skb(se_skb);
+       j1939_session_put(session);
+       return;
+  out_session_cancel:
++      kfree_skb(se_skb);
+       j1939_session_timers_cancel(session);
+       j1939_session_cancel(session, J1939_XTP_ABORT_FAULT);
+       j1939_session_put(session);
diff --git a/queue-5.10/can-mcba_usb-fix-memory-leak-in-mcba_usb.patch b/queue-5.10/can-mcba_usb-fix-memory-leak-in-mcba_usb.patch
new file mode 100644 (file)
index 0000000..451a626
--- /dev/null
@@ -0,0 +1,101 @@
+From 91c02557174be7f72e46ed7311e3bea1939840b0 Mon Sep 17 00:00:00 2001
+From: Pavel Skripkin <paskripkin@gmail.com>
+Date: Thu, 10 Jun 2021 00:58:33 +0300
+Subject: can: mcba_usb: fix memory leak in mcba_usb
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+commit 91c02557174be7f72e46ed7311e3bea1939840b0 upstream.
+
+Syzbot reported memory leak in SocketCAN driver for Microchip CAN BUS
+Analyzer Tool. The problem was in unfreed usb_coherent.
+
+In mcba_usb_start() 20 coherent buffers are allocated and there is
+nothing, that frees them:
+
+1) In callback function the urb is resubmitted and that's all
+2) In disconnect function urbs are simply killed, but URB_FREE_BUFFER
+   is not set (see mcba_usb_start) and this flag cannot be used with
+   coherent buffers.
+
+Fail log:
+| [ 1354.053291][ T8413] mcba_usb 1-1:0.0 can0: device disconnected
+| [ 1367.059384][ T8420] kmemleak: 20 new suspected memory leaks (see /sys/kernel/debug/kmem)
+
+So, all allocated buffers should be freed with usb_free_coherent()
+explicitly
+
+NOTE:
+The same pattern for allocating and freeing coherent buffers
+is used in drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+
+Fixes: 51f3baad7de9 ("can: mcba_usb: Add support for Microchip CAN BUS Analyzer")
+Link: https://lore.kernel.org/r/20210609215833.30393-1-paskripkin@gmail.com
+Cc: linux-stable <stable@vger.kernel.org>
+Reported-and-tested-by: syzbot+57281c762a3922e14dfe@syzkaller.appspotmail.com
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/usb/mcba_usb.c |   17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/can/usb/mcba_usb.c
++++ b/drivers/net/can/usb/mcba_usb.c
+@@ -82,6 +82,8 @@ struct mcba_priv {
+       bool can_ka_first_pass;
+       bool can_speed_check;
+       atomic_t free_ctx_cnt;
++      void *rxbuf[MCBA_MAX_RX_URBS];
++      dma_addr_t rxbuf_dma[MCBA_MAX_RX_URBS];
+ };
+ /* CAN frame */
+@@ -633,6 +635,7 @@ static int mcba_usb_start(struct mcba_pr
+       for (i = 0; i < MCBA_MAX_RX_URBS; i++) {
+               struct urb *urb = NULL;
+               u8 *buf;
++              dma_addr_t buf_dma;
+               /* create a URB, and a buffer for it */
+               urb = usb_alloc_urb(0, GFP_KERNEL);
+@@ -642,7 +645,7 @@ static int mcba_usb_start(struct mcba_pr
+               }
+               buf = usb_alloc_coherent(priv->udev, MCBA_USB_RX_BUFF_SIZE,
+-                                       GFP_KERNEL, &urb->transfer_dma);
++                                       GFP_KERNEL, &buf_dma);
+               if (!buf) {
+                       netdev_err(netdev, "No memory left for USB buffer\n");
+                       usb_free_urb(urb);
+@@ -661,11 +664,14 @@ static int mcba_usb_start(struct mcba_pr
+               if (err) {
+                       usb_unanchor_urb(urb);
+                       usb_free_coherent(priv->udev, MCBA_USB_RX_BUFF_SIZE,
+-                                        buf, urb->transfer_dma);
++                                        buf, buf_dma);
+                       usb_free_urb(urb);
+                       break;
+               }
++              priv->rxbuf[i] = buf;
++              priv->rxbuf_dma[i] = buf_dma;
++
+               /* Drop reference, USB core will take care of freeing it */
+               usb_free_urb(urb);
+       }
+@@ -708,7 +714,14 @@ static int mcba_usb_open(struct net_devi
+ static void mcba_urb_unlink(struct mcba_priv *priv)
+ {
++      int i;
++
+       usb_kill_anchored_urbs(&priv->rx_submitted);
++
++      for (i = 0; i < MCBA_MAX_RX_URBS; ++i)
++              usb_free_coherent(priv->udev, MCBA_USB_RX_BUFF_SIZE,
++                                priv->rxbuf[i], priv->rxbuf_dma[i]);
++
+       usb_kill_anchored_urbs(&priv->tx_submitted);
+ }
diff --git a/queue-5.10/kvm-x86-fix-x86_emulator-slab-cache-leak.patch b/queue-5.10/kvm-x86-fix-x86_emulator-slab-cache-leak.patch
new file mode 100644 (file)
index 0000000..813cc29
--- /dev/null
@@ -0,0 +1,40 @@
+From dfdc0a714d241bfbf951886c373cd1ae463fcc25 Mon Sep 17 00:00:00 2001
+From: Wanpeng Li <wanpengli@tencent.com>
+Date: Thu, 10 Jun 2021 21:59:33 -0700
+Subject: KVM: X86: Fix x86_emulator slab cache leak
+
+From: Wanpeng Li <wanpengli@tencent.com>
+
+commit dfdc0a714d241bfbf951886c373cd1ae463fcc25 upstream.
+
+Commit c9b8b07cded58 (KVM: x86: Dynamically allocate per-vCPU emulation context)
+tries to allocate per-vCPU emulation context dynamically, however, the
+x86_emulator slab cache is still exiting after the kvm module is unload
+as below after destroying the VM and unloading the kvm module.
+
+grep x86_emulator /proc/slabinfo
+x86_emulator          36     36   2672   12    8 : tunables    0    0    0 : slabdata      3      3      0
+
+This patch fixes this slab cache leak by destroying the x86_emulator slab cache
+when the kvm module is unloaded.
+
+Fixes: c9b8b07cded58 (KVM: x86: Dynamically allocate per-vCPU emulation context)
+Cc: stable@vger.kernel.org
+Signed-off-by: Wanpeng Li <wanpengli@tencent.com>
+Message-Id: <1623387573-5969-1-git-send-email-wanpengli@tencent.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/x86.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -8021,6 +8021,7 @@ void kvm_arch_exit(void)
+       kvm_x86_ops.hardware_enable = NULL;
+       kvm_mmu_module_exit();
+       free_percpu(user_return_msrs);
++      kmem_cache_destroy(x86_emulator_cache);
+       kmem_cache_destroy(x86_fpu_cache);
+ }
diff --git a/queue-5.10/kvm-x86-immediately-reset-the-mmu-context-when-the-smm-flag-is-cleared.patch b/queue-5.10/kvm-x86-immediately-reset-the-mmu-context-when-the-smm-flag-is-cleared.patch
new file mode 100644 (file)
index 0000000..7c81eec
--- /dev/null
@@ -0,0 +1,83 @@
+From 78fcb2c91adfec8ce3a2ba6b4d0dda89f2f4a7c6 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Wed, 9 Jun 2021 11:56:11 -0700
+Subject: KVM: x86: Immediately reset the MMU context when the SMM flag is cleared
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit 78fcb2c91adfec8ce3a2ba6b4d0dda89f2f4a7c6 upstream.
+
+Immediately reset the MMU context when the vCPU's SMM flag is cleared so
+that the SMM flag in the MMU role is always synchronized with the vCPU's
+flag.  If RSM fails (which isn't correctly emulated), KVM will bail
+without calling post_leave_smm() and leave the MMU in a bad state.
+
+The bad MMU role can lead to a NULL pointer dereference when grabbing a
+shadow page's rmap for a page fault as the initial lookups for the gfn
+will happen with the vCPU's SMM flag (=0), whereas the rmap lookup will
+use the shadow page's SMM flag, which comes from the MMU (=1).  SMM has
+an entirely different set of memslots, and so the initial lookup can find
+a memslot (SMM=0) and then explode on the rmap memslot lookup (SMM=1).
+
+  general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN
+  KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
+  CPU: 1 PID: 8410 Comm: syz-executor382 Not tainted 5.13.0-rc5-syzkaller #0
+  Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+  RIP: 0010:__gfn_to_rmap arch/x86/kvm/mmu/mmu.c:935 [inline]
+  RIP: 0010:gfn_to_rmap+0x2b0/0x4d0 arch/x86/kvm/mmu/mmu.c:947
+  Code: <42> 80 3c 20 00 74 08 4c 89 ff e8 f1 79 a9 00 4c 89 fb 4d 8b 37 44
+  RSP: 0018:ffffc90000ffef98 EFLAGS: 00010246
+  RAX: 0000000000000000 RBX: ffff888015b9f414 RCX: ffff888019669c40
+  RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000001
+  RBP: 0000000000000001 R08: ffffffff811d9cdb R09: ffffed10065a6002
+  R10: ffffed10065a6002 R11: 0000000000000000 R12: dffffc0000000000
+  R13: 0000000000000003 R14: 0000000000000001 R15: 0000000000000000
+  FS:  000000000124b300(0000) GS:ffff8880b9b00000(0000) knlGS:0000000000000000
+  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+  CR2: 0000000000000000 CR3: 0000000028e31000 CR4: 00000000001526e0
+  DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+  DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+  Call Trace:
+   rmap_add arch/x86/kvm/mmu/mmu.c:965 [inline]
+   mmu_set_spte+0x862/0xe60 arch/x86/kvm/mmu/mmu.c:2604
+   __direct_map arch/x86/kvm/mmu/mmu.c:2862 [inline]
+   direct_page_fault+0x1f74/0x2b70 arch/x86/kvm/mmu/mmu.c:3769
+   kvm_mmu_do_page_fault arch/x86/kvm/mmu.h:124 [inline]
+   kvm_mmu_page_fault+0x199/0x1440 arch/x86/kvm/mmu/mmu.c:5065
+   vmx_handle_exit+0x26/0x160 arch/x86/kvm/vmx/vmx.c:6122
+   vcpu_enter_guest+0x3bdd/0x9630 arch/x86/kvm/x86.c:9428
+   vcpu_run+0x416/0xc20 arch/x86/kvm/x86.c:9494
+   kvm_arch_vcpu_ioctl_run+0x4e8/0xa40 arch/x86/kvm/x86.c:9722
+   kvm_vcpu_ioctl+0x70f/0xbb0 arch/x86/kvm/../../../virt/kvm/kvm_main.c:3460
+   vfs_ioctl fs/ioctl.c:51 [inline]
+   __do_sys_ioctl fs/ioctl.c:1069 [inline]
+   __se_sys_ioctl+0xfb/0x170 fs/ioctl.c:1055
+   do_syscall_64+0x3f/0xb0 arch/x86/entry/common.c:47
+   entry_SYSCALL_64_after_hwframe+0x44/0xae
+  RIP: 0033:0x440ce9
+
+Cc: stable@vger.kernel.org
+Reported-by: syzbot+fb0b6a7e8713aeb0319c@syzkaller.appspotmail.com
+Fixes: 9ec19493fb86 ("KVM: x86: clear SMM flags before loading state while leaving SMM")
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20210609185619.992058-2-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/x86.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -6876,7 +6876,10 @@ static unsigned emulator_get_hflags(stru
+ static void emulator_set_hflags(struct x86_emulate_ctxt *ctxt, unsigned emul_flags)
+ {
+-      emul_to_vcpu(ctxt)->arch.hflags = emul_flags;
++      struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
++
++      vcpu->arch.hflags = emul_flags;
++      kvm_mmu_reset_context(vcpu);
+ }
+ static int emulator_pre_leave_smm(struct x86_emulate_ctxt *ctxt,
diff --git a/queue-5.10/kvm-x86-mmu-calculate-and-check-full-mmu_role-for-nested-mmu.patch b/queue-5.10/kvm-x86-mmu-calculate-and-check-full-mmu_role-for-nested-mmu.patch
new file mode 100644 (file)
index 0000000..328af03
--- /dev/null
@@ -0,0 +1,103 @@
+From 654430efde27248be563df9a88631204b5fe2df2 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Thu, 10 Jun 2021 15:00:26 -0700
+Subject: KVM: x86/mmu: Calculate and check "full" mmu_role for nested MMU
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit 654430efde27248be563df9a88631204b5fe2df2 upstream.
+
+Calculate and check the full mmu_role when initializing the MMU context
+for the nested MMU, where "full" means the bits and pieces of the role
+that aren't handled by kvm_calc_mmu_role_common().  While the nested MMU
+isn't used for shadow paging, things like the number of levels in the
+guest's page tables are surprisingly important when walking the guest
+page tables.  Failure to reinitialize the nested MMU context if L2's
+paging mode changes can result in unexpected and/or missed page faults,
+and likely other explosions.
+
+E.g. if an L1 vCPU is running both a 32-bit PAE L2 and a 64-bit L2, the
+"common" role calculation will yield the same role for both L2s.  If the
+64-bit L2 is run after the 32-bit PAE L2, L0 will fail to reinitialize
+the nested MMU context, ultimately resulting in a bad walk of L2's page
+tables as the MMU will still have a guest root_level of PT32E_ROOT_LEVEL.
+
+  WARNING: CPU: 4 PID: 167334 at arch/x86/kvm/vmx/vmx.c:3075 ept_save_pdptrs+0x15/0xe0 [kvm_intel]
+  Modules linked in: kvm_intel]
+  CPU: 4 PID: 167334 Comm: CPU 3/KVM Not tainted 5.13.0-rc1-d849817d5673-reqs #185
+  Hardware name: ASUS Q87M-E/Q87M-E, BIOS 1102 03/03/2014
+  RIP: 0010:ept_save_pdptrs+0x15/0xe0 [kvm_intel]
+  Code: <0f> 0b c3 f6 87 d8 02 00f
+  RSP: 0018:ffffbba702dbba00 EFLAGS: 00010202
+  RAX: 0000000000000011 RBX: 0000000000000002 RCX: ffffffff810a2c08
+  RDX: ffff91d7bc30acc0 RSI: 0000000000000011 RDI: ffff91d7bc30a600
+  RBP: ffff91d7bc30a600 R08: 0000000000000010 R09: 0000000000000007
+  R10: 0000000000000000 R11: 0000000000000000 R12: ffff91d7bc30a600
+  R13: ffff91d7bc30acc0 R14: ffff91d67c123460 R15: 0000000115d7e005
+  FS:  00007fe8e9ffb700(0000) GS:ffff91d90fb00000(0000) knlGS:0000000000000000
+  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+  CR2: 0000000000000000 CR3: 000000029f15a001 CR4: 00000000001726e0
+  Call Trace:
+   kvm_pdptr_read+0x3a/0x40 [kvm]
+   paging64_walk_addr_generic+0x327/0x6a0 [kvm]
+   paging64_gva_to_gpa_nested+0x3f/0xb0 [kvm]
+   kvm_fetch_guest_virt+0x4c/0xb0 [kvm]
+   __do_insn_fetch_bytes+0x11a/0x1f0 [kvm]
+   x86_decode_insn+0x787/0x1490 [kvm]
+   x86_decode_emulated_instruction+0x58/0x1e0 [kvm]
+   x86_emulate_instruction+0x122/0x4f0 [kvm]
+   vmx_handle_exit+0x120/0x660 [kvm_intel]
+   kvm_arch_vcpu_ioctl_run+0xe25/0x1cb0 [kvm]
+   kvm_vcpu_ioctl+0x211/0x5a0 [kvm]
+   __x64_sys_ioctl+0x83/0xb0
+   do_syscall_64+0x40/0xb0
+   entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
+Cc: stable@vger.kernel.org
+Fixes: bf627a928837 ("x86/kvm/mmu: check if MMU reconfiguration is needed in init_kvm_nested_mmu()")
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20210610220026.1364486-1-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/mmu/mmu.c |   26 +++++++++++++++++++++++++-
+ 1 file changed, 25 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kvm/mmu/mmu.c
++++ b/arch/x86/kvm/mmu/mmu.c
+@@ -4705,9 +4705,33 @@ static void init_kvm_softmmu(struct kvm_
+       context->inject_page_fault = kvm_inject_page_fault;
+ }
++static union kvm_mmu_role kvm_calc_nested_mmu_role(struct kvm_vcpu *vcpu)
++{
++      union kvm_mmu_role role = kvm_calc_shadow_root_page_role_common(vcpu, false);
++
++      /*
++       * Nested MMUs are used only for walking L2's gva->gpa, they never have
++       * shadow pages of their own and so "direct" has no meaning.   Set it
++       * to "true" to try to detect bogus usage of the nested MMU.
++       */
++      role.base.direct = true;
++
++      if (!is_paging(vcpu))
++              role.base.level = 0;
++      else if (is_long_mode(vcpu))
++              role.base.level = is_la57_mode(vcpu) ? PT64_ROOT_5LEVEL :
++                                                     PT64_ROOT_4LEVEL;
++      else if (is_pae(vcpu))
++              role.base.level = PT32E_ROOT_LEVEL;
++      else
++              role.base.level = PT32_ROOT_LEVEL;
++
++      return role;
++}
++
+ static void init_kvm_nested_mmu(struct kvm_vcpu *vcpu)
+ {
+-      union kvm_mmu_role new_role = kvm_calc_mmu_role_common(vcpu, false);
++      union kvm_mmu_role new_role = kvm_calc_nested_mmu_role(vcpu);
+       struct kvm_mmu *g_context = &vcpu->arch.nested_mmu;
+       if (new_role.as_u64 == g_context->mmu_role.as_u64)
diff --git a/queue-5.10/pci-aardvark-fix-kernel-panic-during-pio-transfer.patch b/queue-5.10/pci-aardvark-fix-kernel-panic-during-pio-transfer.patch
new file mode 100644 (file)
index 0000000..e213a73
--- /dev/null
@@ -0,0 +1,150 @@
+From f18139966d072dab8e4398c95ce955a9742e04f7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
+Date: Tue, 8 Jun 2021 22:36:55 +0200
+Subject: PCI: aardvark: Fix kernel panic during PIO transfer
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+commit f18139966d072dab8e4398c95ce955a9742e04f7 upstream.
+
+Trying to start a new PIO transfer by writing value 0 in PIO_START register
+when previous transfer has not yet completed (which is indicated by value 1
+in PIO_START) causes an External Abort on CPU, which results in kernel
+panic:
+
+    SError Interrupt on CPU0, code 0xbf000002 -- SError
+    Kernel panic - not syncing: Asynchronous SError Interrupt
+
+To prevent kernel panic, it is required to reject a new PIO transfer when
+previous one has not finished yet.
+
+If previous PIO transfer is not finished yet, the kernel may issue a new
+PIO request only if the previous PIO transfer timed out.
+
+In the past the root cause of this issue was incorrectly identified (as it
+often happens during link retraining or after link down event) and special
+hack was implemented in Trusted Firmware to catch all SError events in EL3,
+to ignore errors with code 0xbf000002 and not forwarding any other errors
+to kernel and instead throw panic from EL3 Trusted Firmware handler.
+
+Links to discussion and patches about this issue:
+https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=3c7dcdac5c50
+https://lore.kernel.org/linux-pci/20190316161243.29517-1-repk@triplefau.lt/
+https://lore.kernel.org/linux-pci/971be151d24312cc533989a64bd454b4@www.loen.fr/
+https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/1541
+
+But the real cause was the fact that during link retraining or after link
+down event the PIO transfer may take longer time, up to the 1.44s until it
+times out. This increased probability that a new PIO transfer would be
+issued by kernel while previous one has not finished yet.
+
+After applying this change into the kernel, it is possible to revert the
+mentioned TF-A hack and SError events do not have to be caught in TF-A EL3.
+
+Link: https://lore.kernel.org/r/20210608203655.31228-1-pali@kernel.org
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Marek Behún <kabel@kernel.org>
+Cc: stable@vger.kernel.org # 7fbcb5da811b ("PCI: aardvark: Don't rely on jiffies while holding spinlock")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/pci-aardvark.c |   49 +++++++++++++++++++++++++++-------
+ 1 file changed, 40 insertions(+), 9 deletions(-)
+
+--- a/drivers/pci/controller/pci-aardvark.c
++++ b/drivers/pci/controller/pci-aardvark.c
+@@ -514,7 +514,7 @@ static int advk_pcie_wait_pio(struct adv
+               udelay(PIO_RETRY_DELAY);
+       }
+-      dev_err(dev, "config read/write timed out\n");
++      dev_err(dev, "PIO read/write transfer time out\n");
+       return -ETIMEDOUT;
+ }
+@@ -657,6 +657,35 @@ static bool advk_pcie_valid_device(struc
+       return true;
+ }
++static bool advk_pcie_pio_is_running(struct advk_pcie *pcie)
++{
++      struct device *dev = &pcie->pdev->dev;
++
++      /*
++       * Trying to start a new PIO transfer when previous has not completed
++       * cause External Abort on CPU which results in kernel panic:
++       *
++       *     SError Interrupt on CPU0, code 0xbf000002 -- SError
++       *     Kernel panic - not syncing: Asynchronous SError Interrupt
++       *
++       * Functions advk_pcie_rd_conf() and advk_pcie_wr_conf() are protected
++       * by raw_spin_lock_irqsave() at pci_lock_config() level to prevent
++       * concurrent calls at the same time. But because PIO transfer may take
++       * about 1.5s when link is down or card is disconnected, it means that
++       * advk_pcie_wait_pio() does not always have to wait for completion.
++       *
++       * Some versions of ARM Trusted Firmware handles this External Abort at
++       * EL3 level and mask it to prevent kernel panic. Relevant TF-A commit:
++       * https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=3c7dcdac5c50
++       */
++      if (advk_readl(pcie, PIO_START)) {
++              dev_err(dev, "Previous PIO read/write transfer is still running\n");
++              return true;
++      }
++
++      return false;
++}
++
+ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn,
+                            int where, int size, u32 *val)
+ {
+@@ -673,9 +702,10 @@ static int advk_pcie_rd_conf(struct pci_
+               return pci_bridge_emul_conf_read(&pcie->bridge, where,
+                                                size, val);
+-      /* Start PIO */
+-      advk_writel(pcie, 0, PIO_START);
+-      advk_writel(pcie, 1, PIO_ISR);
++      if (advk_pcie_pio_is_running(pcie)) {
++              *val = 0xffffffff;
++              return PCIBIOS_SET_FAILED;
++      }
+       /* Program the control register */
+       reg = advk_readl(pcie, PIO_CTRL);
+@@ -694,7 +724,8 @@ static int advk_pcie_rd_conf(struct pci_
+       /* Program the data strobe */
+       advk_writel(pcie, 0xf, PIO_WR_DATA_STRB);
+-      /* Start the transfer */
++      /* Clear PIO DONE ISR and start the transfer */
++      advk_writel(pcie, 1, PIO_ISR);
+       advk_writel(pcie, 1, PIO_START);
+       ret = advk_pcie_wait_pio(pcie);
+@@ -734,9 +765,8 @@ static int advk_pcie_wr_conf(struct pci_
+       if (where % size)
+               return PCIBIOS_SET_FAILED;
+-      /* Start PIO */
+-      advk_writel(pcie, 0, PIO_START);
+-      advk_writel(pcie, 1, PIO_ISR);
++      if (advk_pcie_pio_is_running(pcie))
++              return PCIBIOS_SET_FAILED;
+       /* Program the control register */
+       reg = advk_readl(pcie, PIO_CTRL);
+@@ -763,7 +793,8 @@ static int advk_pcie_wr_conf(struct pci_
+       /* Program the data strobe */
+       advk_writel(pcie, data_strobe, PIO_WR_DATA_STRB);
+-      /* Start the transfer */
++      /* Clear PIO DONE ISR and start the transfer */
++      advk_writel(pcie, 1, PIO_ISR);
+       advk_writel(pcie, 1, PIO_START);
+       ret = advk_pcie_wait_pio(pcie);
diff --git a/queue-5.10/pci-add-acs-quirk-for-broadcom-bcm57414-nic.patch b/queue-5.10/pci-add-acs-quirk-for-broadcom-bcm57414-nic.patch
new file mode 100644 (file)
index 0000000..4725290
--- /dev/null
@@ -0,0 +1,40 @@
+From db2f77e2bd99dbd2fb23ddde58f0fae392fe3338 Mon Sep 17 00:00:00 2001
+From: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
+Date: Fri, 21 May 2021 21:13:17 -0400
+Subject: PCI: Add ACS quirk for Broadcom BCM57414 NIC
+
+From: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
+
+commit db2f77e2bd99dbd2fb23ddde58f0fae392fe3338 upstream.
+
+The Broadcom BCM57414 NIC may be a multi-function device.  While it does
+not advertise an ACS capability, peer-to-peer transactions are not possible
+between the individual functions, so it is safe to treat them as fully
+isolated.
+
+Add an ACS quirk for this device so the functions can be in independent
+IOMMU groups and attached individually to userspace applications using
+VFIO.
+
+[bhelgaas: commit log]
+Link: https://lore.kernel.org/r/1621645997-16251-1-git-send-email-michael.chan@broadcom.com
+Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/quirks.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -4785,6 +4785,8 @@ static const struct pci_dev_acs_enabled
+       { PCI_VENDOR_ID_AMPERE, 0xE00A, pci_quirk_xgene_acs },
+       { PCI_VENDOR_ID_AMPERE, 0xE00B, pci_quirk_xgene_acs },
+       { PCI_VENDOR_ID_AMPERE, 0xE00C, pci_quirk_xgene_acs },
++      /* Broadcom multi-function device */
++      { PCI_VENDOR_ID_BROADCOM, 0x16D7, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_BROADCOM, 0xD714, pci_quirk_brcm_acs },
+       /* Amazon Annapurna Labs */
+       { PCI_VENDOR_ID_AMAZON_ANNAPURNA_LABS, 0x0031, pci_quirk_al_acs },
diff --git a/queue-5.10/pci-mark-some-nvidia-gpus-to-avoid-bus-reset.patch b/queue-5.10/pci-mark-some-nvidia-gpus-to-avoid-bus-reset.patch
new file mode 100644 (file)
index 0000000..3cf1a5a
--- /dev/null
@@ -0,0 +1,48 @@
+From 4c207e7121fa92b66bf1896bf8ccb9edfb0f9731 Mon Sep 17 00:00:00 2001
+From: Shanker Donthineni <sdonthineni@nvidia.com>
+Date: Tue, 8 Jun 2021 11:18:56 +0530
+Subject: PCI: Mark some NVIDIA GPUs to avoid bus reset
+
+From: Shanker Donthineni <sdonthineni@nvidia.com>
+
+commit 4c207e7121fa92b66bf1896bf8ccb9edfb0f9731 upstream.
+
+Some NVIDIA GPU devices do not work with SBR.  Triggering SBR leaves the
+device inoperable for the current system boot. It requires a system
+hard-reboot to get the GPU device back to normal operating condition
+post-SBR. For the affected devices, enable NO_BUS_RESET quirk to avoid the
+issue.
+
+This issue will be fixed in the next generation of hardware.
+
+Link: https://lore.kernel.org/r/20210608054857.18963-8-ameynarkhede03@gmail.com
+Signed-off-by: Shanker Donthineni <sdonthineni@nvidia.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Sinan Kaya <okaya@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/quirks.c |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -3558,6 +3558,18 @@ static void quirk_no_bus_reset(struct pc
+ }
+ /*
++ * Some NVIDIA GPU devices do not work with bus reset, SBR needs to be
++ * prevented for those affected devices.
++ */
++static void quirk_nvidia_no_bus_reset(struct pci_dev *dev)
++{
++      if ((dev->device & 0xffc0) == 0x2340)
++              quirk_no_bus_reset(dev);
++}
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
++                       quirk_nvidia_no_bus_reset);
++
++/*
+  * Some Atheros AR9xxx and QCA988x chips do not behave after a bus reset.
+  * The device will throw a Link Down error on AER-capable systems and
+  * regardless of AER, config space of the device is never accessible again
diff --git a/queue-5.10/pci-mark-ti-c667x-to-avoid-bus-reset.patch b/queue-5.10/pci-mark-ti-c667x-to-avoid-bus-reset.patch
new file mode 100644 (file)
index 0000000..32c9e4f
--- /dev/null
@@ -0,0 +1,48 @@
+From b5cf198e74a91073d12839a3e2db99994a39995d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Antti=20J=C3=A4rvinen?= <antti.jarvinen@gmail.com>
+Date: Mon, 15 Mar 2021 10:26:06 +0000
+Subject: PCI: Mark TI C667X to avoid bus reset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Antti Järvinen <antti.jarvinen@gmail.com>
+
+commit b5cf198e74a91073d12839a3e2db99994a39995d upstream.
+
+Some TI KeyStone C667X devices do not support bus/hot reset.  The PCIESS
+automatically disables LTSSM when Secondary Bus Reset is received and
+device stops working.  Prevent bus reset for these devices.  With this
+change, the device can be assigned to VMs with VFIO, but it will leak state
+between VMs.
+
+Reference: https://e2e.ti.com/support/processors/f/791/t/954382
+Link: https://lore.kernel.org/r/20210315102606.17153-1-antti.jarvinen@gmail.com
+Signed-off-by: Antti Järvinen <antti.jarvinen@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Kishon Vijay Abraham I <kishon@ti.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/quirks.c |   10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -3577,6 +3577,16 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_A
+  */
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CAVIUM, 0xa100, quirk_no_bus_reset);
++/*
++ * Some TI KeyStone C667X devices do not support bus/hot reset.  The PCIESS
++ * automatically disables LTSSM when Secondary Bus Reset is received and
++ * the device stops working.  Prevent bus reset for these devices.  With
++ * this change, the device can be assigned to VMs with VFIO, but it will
++ * leak state between VMs.  Reference
++ * https://e2e.ti.com/support/processors/f/791/t/954382
++ */
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, 0xb005, quirk_no_bus_reset);
++
+ static void quirk_no_pm_reset(struct pci_dev *dev)
+ {
+       /*
diff --git a/queue-5.10/pci-work-around-huawei-intelligent-nic-vf-flr-erratum.patch b/queue-5.10/pci-work-around-huawei-intelligent-nic-vf-flr-erratum.patch
new file mode 100644 (file)
index 0000000..fc97114
--- /dev/null
@@ -0,0 +1,117 @@
+From ce00322c2365e1f7b0312f2f493539c833465d97 Mon Sep 17 00:00:00 2001
+From: Chiqijun <chiqijun@huawei.com>
+Date: Mon, 24 May 2021 17:44:07 -0500
+Subject: PCI: Work around Huawei Intelligent NIC VF FLR erratum
+
+From: Chiqijun <chiqijun@huawei.com>
+
+commit ce00322c2365e1f7b0312f2f493539c833465d97 upstream.
+
+pcie_flr() starts a Function Level Reset (FLR), waits 100ms (the maximum
+time allowed for FLR completion by PCIe r5.0, sec 6.6.2), and waits for the
+FLR to complete.  It assumes the FLR is complete when a config read returns
+valid data.
+
+When we do an FLR on several Huawei Intelligent NIC VFs at the same time,
+firmware on the NIC processes them serially.  The VF may respond to config
+reads before the firmware has completed its reset processing.  If we bind a
+driver to the VF (e.g., by assigning the VF to a virtual machine) in the
+interval between the successful config read and completion of the firmware
+reset processing, the NIC VF driver may fail to load.
+
+Prevent this driver failure by waiting for the NIC firmware to complete its
+reset processing.  Not all NIC firmware supports this feature.
+
+[bhelgaas: commit log]
+Link: https://support.huawei.com/enterprise/en/doc/EDOC1100063073/87950645/vm-oss-occasionally-fail-to-load-the-in200-driver-when-the-vf-performs-flr
+Link: https://lore.kernel.org/r/20210414132301.1793-1-chiqijun@huawei.com
+Signed-off-by: Chiqijun <chiqijun@huawei.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/quirks.c |   65 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 65 insertions(+)
+
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -3934,6 +3934,69 @@ static int delay_250ms_after_flr(struct
+       return 0;
+ }
++#define PCI_DEVICE_ID_HINIC_VF      0x375E
++#define HINIC_VF_FLR_TYPE           0x1000
++#define HINIC_VF_FLR_CAP_BIT        (1UL << 30)
++#define HINIC_VF_OP                 0xE80
++#define HINIC_VF_FLR_PROC_BIT       (1UL << 18)
++#define HINIC_OPERATION_TIMEOUT     15000     /* 15 seconds */
++
++/* Device-specific reset method for Huawei Intelligent NIC virtual functions */
++static int reset_hinic_vf_dev(struct pci_dev *pdev, int probe)
++{
++      unsigned long timeout;
++      void __iomem *bar;
++      u32 val;
++
++      if (probe)
++              return 0;
++
++      bar = pci_iomap(pdev, 0, 0);
++      if (!bar)
++              return -ENOTTY;
++
++      /* Get and check firmware capabilities */
++      val = ioread32be(bar + HINIC_VF_FLR_TYPE);
++      if (!(val & HINIC_VF_FLR_CAP_BIT)) {
++              pci_iounmap(pdev, bar);
++              return -ENOTTY;
++      }
++
++      /* Set HINIC_VF_FLR_PROC_BIT for the start of FLR */
++      val = ioread32be(bar + HINIC_VF_OP);
++      val = val | HINIC_VF_FLR_PROC_BIT;
++      iowrite32be(val, bar + HINIC_VF_OP);
++
++      pcie_flr(pdev);
++
++      /*
++       * The device must recapture its Bus and Device Numbers after FLR
++       * in order generate Completions.  Issue a config write to let the
++       * device capture this information.
++       */
++      pci_write_config_word(pdev, PCI_VENDOR_ID, 0);
++
++      /* Firmware clears HINIC_VF_FLR_PROC_BIT when reset is complete */
++      timeout = jiffies + msecs_to_jiffies(HINIC_OPERATION_TIMEOUT);
++      do {
++              val = ioread32be(bar + HINIC_VF_OP);
++              if (!(val & HINIC_VF_FLR_PROC_BIT))
++                      goto reset_complete;
++              msleep(20);
++      } while (time_before(jiffies, timeout));
++
++      val = ioread32be(bar + HINIC_VF_OP);
++      if (!(val & HINIC_VF_FLR_PROC_BIT))
++              goto reset_complete;
++
++      pci_warn(pdev, "Reset dev timeout, FLR ack reg: %#010x\n", val);
++
++reset_complete:
++      pci_iounmap(pdev, bar);
++
++      return 0;
++}
++
+ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF,
+                reset_intel_82599_sfp_virtfn },
+@@ -3945,6 +4008,8 @@ static const struct pci_dev_reset_method
+       { PCI_VENDOR_ID_INTEL, 0x0953, delay_250ms_after_flr },
+       { PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID,
+               reset_chelsio_generic_dev },
++      { PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HINIC_VF,
++              reset_hinic_vf_dev },
+       { 0 }
+ };
diff --git a/queue-5.10/s390-ap-fix-hanging-ioctl-caused-by-wrong-msg-counter.patch b/queue-5.10/s390-ap-fix-hanging-ioctl-caused-by-wrong-msg-counter.patch
new file mode 100644 (file)
index 0000000..b9e8b65
--- /dev/null
@@ -0,0 +1,88 @@
+From e73a99f3287a740a07d6618e9470f4d6cb217da8 Mon Sep 17 00:00:00 2001
+From: Harald Freudenberger <freude@linux.ibm.com>
+Date: Tue, 1 Jun 2021 08:27:29 +0200
+Subject: s390/ap: Fix hanging ioctl caused by wrong msg counter
+
+From: Harald Freudenberger <freude@linux.ibm.com>
+
+commit e73a99f3287a740a07d6618e9470f4d6cb217da8 upstream.
+
+When a AP queue is switched to soft offline, all pending
+requests are purged out of the pending requests list and
+'received' by the upper layer like zcrypt device drivers.
+This is also done for requests which are already enqueued
+into the firmware queue. A request in a firmware queue
+may eventually produce an response message, but there is
+no waiting process any more. However, the response was
+counted with the queue_counter and as this counter was
+reset to 0 with the offline switch, the pending response
+caused the queue_counter to get negative. The next request
+increased this counter to 0 (instead of 1) which caused
+the ap code to assume there is nothing to receive and so
+the response for this valid request was never tried to
+fetch from the firmware queue.
+
+This all caused a queue to not work properly after a
+switch offline/online and in the end processes to hang
+forever when trying to send a crypto request after an
+queue offline/online switch cicle.
+
+Fixed by a) making sure the counter does not drop below 0
+and b) on a successful enqueue of a message has at least
+a value of 1.
+
+Additionally a warning is emitted, when a reply can't get
+assigned to a waiting process. This may be normal operation
+(process had timeout or has been killed) but may give a
+hint that something unexpected happened (like this odd
+behavior described above).
+
+Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/s390/crypto/ap_queue.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/s390/crypto/ap_queue.c
++++ b/drivers/s390/crypto/ap_queue.c
+@@ -135,12 +135,13 @@ static struct ap_queue_status ap_sm_recv
+ {
+       struct ap_queue_status status;
+       struct ap_message *ap_msg;
++      bool found = false;
+       status = ap_dqap(aq->qid, &aq->reply->psmid,
+                        aq->reply->msg, aq->reply->len);
+       switch (status.response_code) {
+       case AP_RESPONSE_NORMAL:
+-              aq->queue_count--;
++              aq->queue_count = max_t(int, 0, aq->queue_count - 1);
+               if (aq->queue_count > 0)
+                       mod_timer(&aq->timeout,
+                                 jiffies + aq->request_timeout);
+@@ -150,8 +151,14 @@ static struct ap_queue_status ap_sm_recv
+                       list_del_init(&ap_msg->list);
+                       aq->pendingq_count--;
+                       ap_msg->receive(aq, ap_msg, aq->reply);
++                      found = true;
+                       break;
+               }
++              if (!found) {
++                      AP_DBF_WARN("%s unassociated reply psmid=0x%016llx on 0x%02x.%04x\n",
++                                  __func__, aq->reply->psmid,
++                                  AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid));
++              }
+               fallthrough;
+       case AP_RESPONSE_NO_PENDING_REPLY:
+               if (!status.queue_empty || aq->queue_count <= 0)
+@@ -232,7 +239,7 @@ static enum ap_sm_wait ap_sm_write(struc
+                          ap_msg->flags & AP_MSG_FLAG_SPECIAL);
+       switch (status.response_code) {
+       case AP_RESPONSE_NORMAL:
+-              aq->queue_count++;
++              aq->queue_count = max_t(int, 1, aq->queue_count + 1);
+               if (aq->queue_count == 1)
+                       mod_timer(&aq->timeout, jiffies + aq->request_timeout);
+               list_move_tail(&ap_msg->list, &aq->pendingq);
diff --git a/queue-5.10/s390-mcck-fix-calculation-of-sie-critical-section-size.patch b/queue-5.10/s390-mcck-fix-calculation-of-sie-critical-section-size.patch
new file mode 100644 (file)
index 0000000..8f00a1b
--- /dev/null
@@ -0,0 +1,35 @@
+From 5bcbe3285fb614c49db6b238253f7daff7e66312 Mon Sep 17 00:00:00 2001
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+Date: Mon, 17 May 2021 08:18:11 +0200
+Subject: s390/mcck: fix calculation of SIE critical section size
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+commit 5bcbe3285fb614c49db6b238253f7daff7e66312 upstream.
+
+The size of SIE critical section is calculated wrongly
+as result of a missed subtraction in commit 0b0ed657fe00
+("s390: remove critical section cleanup from entry.S")
+
+Fixes: 0b0ed657fe00 ("s390: remove critical section cleanup from entry.S")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/kernel/entry.S |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/s390/kernel/entry.S
++++ b/arch/s390/kernel/entry.S
+@@ -1284,7 +1284,7 @@ ENDPROC(stack_overflow)
+       je      1f
+       larl    %r13,.Lsie_entry
+       slgr    %r9,%r13
+-      larl    %r13,.Lsie_skip
++      lghi    %r13,.Lsie_skip - .Lsie_entry
+       clgr    %r9,%r13
+       jh      1f
+       oi      __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
index f108441724b778c070acbe3909bb38d4133da310..464623d31c57342e3793d1b352c79cccde0e8ac3 100644 (file)
@@ -95,3 +95,23 @@ irqchip-gic-v3-workaround-inconsistent-pmr-setting-o.patch
 sched-fair-correctly-insert-cfs_rq-s-to-list-on-unth.patch
 bpf-inherit-expanded-patched-seen-count-from-old-aux.patch
 bpf-do-not-mark-insn-as-seen-under-speculative-path-.patch
+can-bcm-fix-infoleak-in-struct-bcm_msg_head.patch
+can-bcm-raw-isotp-use-per-module-netdevice-notifier.patch
+can-j1939-fix-use-after-free-hold-skb-ref-while-in-use.patch
+can-mcba_usb-fix-memory-leak-in-mcba_usb.patch
+usb-core-hub-disable-autosuspend-for-cypress-cy7c65632.patch
+usb-chipidea-imx-fix-battery-charger-1.2-cdp-detection.patch
+tracing-do-not-stop-recording-cmdlines-when-tracing-is-off.patch
+tracing-do-not-stop-recording-comms-if-the-trace-file-is-being-read.patch
+tracing-do-no-increment-trace_clock_global-by-one.patch
+pci-mark-ti-c667x-to-avoid-bus-reset.patch
+pci-mark-some-nvidia-gpus-to-avoid-bus-reset.patch
+pci-aardvark-fix-kernel-panic-during-pio-transfer.patch
+pci-add-acs-quirk-for-broadcom-bcm57414-nic.patch
+pci-work-around-huawei-intelligent-nic-vf-flr-erratum.patch
+kvm-x86-immediately-reset-the-mmu-context-when-the-smm-flag-is-cleared.patch
+kvm-x86-mmu-calculate-and-check-full-mmu_role-for-nested-mmu.patch
+kvm-x86-fix-x86_emulator-slab-cache-leak.patch
+s390-mcck-fix-calculation-of-sie-critical-section-size.patch
+s390-ap-fix-hanging-ioctl-caused-by-wrong-msg-counter.patch
+arcv2-save-abi-registers-across-signal-handling.patch
diff --git a/queue-5.10/tracing-do-no-increment-trace_clock_global-by-one.patch b/queue-5.10/tracing-do-no-increment-trace_clock_global-by-one.patch
new file mode 100644 (file)
index 0000000..4fdc122
--- /dev/null
@@ -0,0 +1,131 @@
+From 89529d8b8f8daf92d9979382b8d2eb39966846ea Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
+Date: Thu, 17 Jun 2021 17:12:35 -0400
+Subject: tracing: Do no increment trace_clock_global() by one
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+commit 89529d8b8f8daf92d9979382b8d2eb39966846ea upstream.
+
+The trace_clock_global() tries to make sure the events between CPUs is
+somewhat in order. A global value is used and updated by the latest read
+of a clock. If one CPU is ahead by a little, and is read by another CPU, a
+lock is taken, and if the timestamp of the other CPU is behind, it will
+simply use the other CPUs timestamp.
+
+The lock is also only taken with a "trylock" due to tracing, and strange
+recursions can happen. The lock is not taken at all in NMI context.
+
+In the case where the lock is not able to be taken, the non synced
+timestamp is returned. But it will not be less than the saved global
+timestamp.
+
+The problem arises because when the time goes "backwards" the time
+returned is the saved timestamp plus 1. If the lock is not taken, and the
+plus one to the timestamp is returned, there's a small race that can cause
+the time to go backwards!
+
+       CPU0                            CPU1
+       ----                            ----
+                               trace_clock_global() {
+                                   ts = clock() [ 1000 ]
+                                   trylock(clock_lock) [ success ]
+                                   global_ts = ts; [ 1000 ]
+
+                                   <interrupted by NMI>
+ trace_clock_global() {
+    ts = clock() [ 999 ]
+    if (ts < global_ts)
+       ts = global_ts + 1 [ 1001 ]
+
+    trylock(clock_lock) [ fail ]
+
+    return ts [ 1001]
+ }
+                                   unlock(clock_lock);
+                                   return ts; [ 1000 ]
+                               }
+
+ trace_clock_global() {
+    ts = clock() [ 1000 ]
+    if (ts < global_ts) [ false 1000 == 1000 ]
+
+    trylock(clock_lock) [ success ]
+    global_ts = ts; [ 1000 ]
+    unlock(clock_lock)
+
+    return ts; [ 1000 ]
+ }
+
+The above case shows to reads of trace_clock_global() on the same CPU, but
+the second read returns one less than the first read. That is, time when
+backwards, and this is not what is allowed by trace_clock_global().
+
+This was triggered by heavy tracing and the ring buffer checker that tests
+for the clock going backwards:
+
+ Ring buffer clock went backwards: 20613921464 -> 20613921463
+ ------------[ cut here ]------------
+ WARNING: CPU: 2 PID: 0 at kernel/trace/ring_buffer.c:3412 check_buffer+0x1b9/0x1c0
+ Modules linked in:
+ [..]
+ [CPU: 2]TIME DOES NOT MATCH expected:20620711698 actual:20620711697 delta:6790234 before:20613921463 after:20613921463
+   [20613915818] PAGE TIME STAMP
+   [20613915818] delta:0
+   [20613915819] delta:1
+   [20613916035] delta:216
+   [20613916465] delta:430
+   [20613916575] delta:110
+   [20613916749] delta:174
+   [20613917248] delta:499
+   [20613917333] delta:85
+   [20613917775] delta:442
+   [20613917921] delta:146
+   [20613918321] delta:400
+   [20613918568] delta:247
+   [20613918768] delta:200
+   [20613919306] delta:538
+   [20613919353] delta:47
+   [20613919980] delta:627
+   [20613920296] delta:316
+   [20613920571] delta:275
+   [20613920862] delta:291
+   [20613921152] delta:290
+   [20613921464] delta:312
+   [20613921464] delta:0 TIME EXTEND
+   [20613921464] delta:0
+
+This happened more than once, and always for an off by one result. It also
+started happening after commit aafe104aa9096 was added.
+
+Cc: stable@vger.kernel.org
+Fixes: aafe104aa9096 ("tracing: Restructure trace_clock_global() to never block")
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace_clock.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/kernel/trace/trace_clock.c
++++ b/kernel/trace/trace_clock.c
+@@ -115,9 +115,9 @@ u64 notrace trace_clock_global(void)
+       prev_time = READ_ONCE(trace_clock_struct.prev_time);
+       now = sched_clock_cpu(this_cpu);
+-      /* Make sure that now is always greater than prev_time */
++      /* Make sure that now is always greater than or equal to prev_time */
+       if ((s64)(now - prev_time) < 0)
+-              now = prev_time + 1;
++              now = prev_time;
+       /*
+        * If in an NMI context then dont risk lockups and simply return
+@@ -131,7 +131,7 @@ u64 notrace trace_clock_global(void)
+               /* Reread prev_time in case it was already updated */
+               prev_time = READ_ONCE(trace_clock_struct.prev_time);
+               if ((s64)(now - prev_time) < 0)
+-                      now = prev_time + 1;
++                      now = prev_time;
+               trace_clock_struct.prev_time = now;
diff --git a/queue-5.10/tracing-do-not-stop-recording-cmdlines-when-tracing-is-off.patch b/queue-5.10/tracing-do-not-stop-recording-cmdlines-when-tracing-is-off.patch
new file mode 100644 (file)
index 0000000..b1e7e8e
--- /dev/null
@@ -0,0 +1,52 @@
+From 85550c83da421fb12dc1816c45012e1e638d2b38 Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
+Date: Thu, 17 Jun 2021 13:47:25 -0400
+Subject: tracing: Do not stop recording cmdlines when tracing is off
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+commit 85550c83da421fb12dc1816c45012e1e638d2b38 upstream.
+
+The saved_cmdlines is used to map pids to the task name, such that the
+output of the tracing does not just show pids, but also gives a human
+readable name for the task.
+
+If the name is not mapped, the output looks like this:
+
+    <...>-1316          [005] ...2   132.044039: ...
+
+Instead of this:
+
+    gnome-shell-1316    [005] ...2   132.044039: ...
+
+The names are updated when tracing is running, but are skipped if tracing
+is stopped. Unfortunately, this stops the recording of the names if the
+top level tracer is stopped, and not if there's other tracers active.
+
+The recording of a name only happens when a new event is written into a
+ring buffer, so there is no need to test if tracing is on or not. If
+tracing is off, then no event is written and no need to test if tracing is
+off or not.
+
+Remove the check, as it hides the names of tasks for events in the
+instance buffers.
+
+Cc: stable@vger.kernel.org
+Fixes: 7ffbd48d5cab2 ("tracing: Cache comms only after an event occurred")
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -2483,8 +2483,6 @@ static bool tracing_record_taskinfo_skip
+ {
+       if (unlikely(!(flags & (TRACE_RECORD_CMDLINE | TRACE_RECORD_TGID))))
+               return true;
+-      if (atomic_read(&trace_record_taskinfo_disabled) || !tracing_is_on())
+-              return true;
+       if (!__this_cpu_read(trace_taskinfo_save))
+               return true;
+       return false;
diff --git a/queue-5.10/tracing-do-not-stop-recording-comms-if-the-trace-file-is-being-read.patch b/queue-5.10/tracing-do-not-stop-recording-comms-if-the-trace-file-is-being-read.patch
new file mode 100644 (file)
index 0000000..053ddd9
--- /dev/null
@@ -0,0 +1,56 @@
+From 4fdd595e4f9a1ff6d93ec702eaecae451cfc6591 Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
+Date: Thu, 17 Jun 2021 14:32:34 -0400
+Subject: tracing: Do not stop recording comms if the trace file is being read
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+commit 4fdd595e4f9a1ff6d93ec702eaecae451cfc6591 upstream.
+
+A while ago, when the "trace" file was opened, tracing was stopped, and
+code was added to stop recording the comms to saved_cmdlines, for mapping
+of the pids to the task name.
+
+Code has been added that only records the comm if a trace event occurred,
+and there's no reason to not trace it if the trace file is opened.
+
+Cc: stable@vger.kernel.org
+Fixes: 7ffbd48d5cab2 ("tracing: Cache comms only after an event occurred")
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace.c |    9 ---------
+ 1 file changed, 9 deletions(-)
+
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -2195,9 +2195,6 @@ struct saved_cmdlines_buffer {
+ };
+ static struct saved_cmdlines_buffer *savedcmd;
+-/* temporary disable recording */
+-static atomic_t trace_record_taskinfo_disabled __read_mostly;
+-
+ static inline char *get_saved_cmdlines(int idx)
+ {
+       return &savedcmd->saved_cmdlines[idx * TASK_COMM_LEN];
+@@ -3683,9 +3680,6 @@ static void *s_start(struct seq_file *m,
+               return ERR_PTR(-EBUSY);
+ #endif
+-      if (!iter->snapshot)
+-              atomic_inc(&trace_record_taskinfo_disabled);
+-
+       if (*pos != iter->pos) {
+               iter->ent = NULL;
+               iter->cpu = 0;
+@@ -3728,9 +3722,6 @@ static void s_stop(struct seq_file *m, v
+               return;
+ #endif
+-      if (!iter->snapshot)
+-              atomic_dec(&trace_record_taskinfo_disabled);
+-
+       trace_access_unlock(iter->cpu_file);
+       trace_event_read_unlock();
+ }
diff --git a/queue-5.10/usb-chipidea-imx-fix-battery-charger-1.2-cdp-detection.patch b/queue-5.10/usb-chipidea-imx-fix-battery-charger-1.2-cdp-detection.patch
new file mode 100644 (file)
index 0000000..749a6f8
--- /dev/null
@@ -0,0 +1,79 @@
+From c6d580d96f140596d69220f60ce0cfbea4ee5c0f Mon Sep 17 00:00:00 2001
+From: Breno Lima <breno.lima@nxp.com>
+Date: Mon, 14 Jun 2021 13:50:13 -0400
+Subject: usb: chipidea: imx: Fix Battery Charger 1.2 CDP detection
+
+From: Breno Lima <breno.lima@nxp.com>
+
+commit c6d580d96f140596d69220f60ce0cfbea4ee5c0f upstream.
+
+i.MX8MM cannot detect certain CDP USB HUBs. usbmisc_imx.c driver is not
+following CDP timing requirements defined by USB BC 1.2 specification
+and section 3.2.4 Detection Timing CDP.
+
+During Primary Detection the i.MX device should turn on VDP_SRC and
+IDM_SINK for a minimum of 40ms (TVDPSRC_ON). After a time of TVDPSRC_ON,
+the i.MX is allowed to check the status of the D- line. Current
+implementation is waiting between 1ms and 2ms, and certain BC 1.2
+complaint USB HUBs cannot be detected. Increase delay to 40ms allowing
+enough time for primary detection.
+
+During secondary detection the i.MX is required to disable VDP_SRC and
+IDM_SNK, and enable VDM_SRC and IDP_SINK for at least 40ms (TVDMSRC_ON).
+
+Current implementation is not disabling VDP_SRC and IDM_SNK, introduce
+disable sequence in imx7d_charger_secondary_detection() function.
+
+VDM_SRC and IDP_SINK should be enabled for at least 40ms (TVDMSRC_ON).
+Increase delay allowing enough time for detection.
+
+Cc: <stable@vger.kernel.org>
+Fixes: 746f316b753a ("usb: chipidea: introduce imx7d USB charger detection")
+Signed-off-by: Breno Lima <breno.lima@nxp.com>
+Signed-off-by: Jun Li <jun.li@nxp.com>
+Link: https://lore.kernel.org/r/20210614175013.495808-1-breno.lima@nxp.com
+Signed-off-by: Peter Chen <peter.chen@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/chipidea/usbmisc_imx.c |   16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/chipidea/usbmisc_imx.c
++++ b/drivers/usb/chipidea/usbmisc_imx.c
+@@ -686,6 +686,16 @@ static int imx7d_charger_secondary_detec
+       int val;
+       unsigned long flags;
++      /* Clear VDATSRCENB0 to disable VDP_SRC and IDM_SNK required by BC 1.2 spec */
++      spin_lock_irqsave(&usbmisc->lock, flags);
++      val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
++      val &= ~MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0;
++      writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
++      spin_unlock_irqrestore(&usbmisc->lock, flags);
++
++      /* TVDMSRC_DIS */
++      msleep(20);
++
+       /* VDM_SRC is connected to D- and IDP_SINK is connected to D+ */
+       spin_lock_irqsave(&usbmisc->lock, flags);
+       val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
+@@ -695,7 +705,8 @@ static int imx7d_charger_secondary_detec
+                               usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
+       spin_unlock_irqrestore(&usbmisc->lock, flags);
+-      usleep_range(1000, 2000);
++      /* TVDMSRC_ON */
++      msleep(40);
+       /*
+        * Per BC 1.2, check voltage of D+:
+@@ -798,7 +809,8 @@ static int imx7d_charger_primary_detecti
+                               usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
+       spin_unlock_irqrestore(&usbmisc->lock, flags);
+-      usleep_range(1000, 2000);
++      /* TVDPSRC_ON */
++      msleep(40);
+       /* Check if D- is less than VDAT_REF to determine an SDP per BC 1.2 */
+       val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS);
diff --git a/queue-5.10/usb-core-hub-disable-autosuspend-for-cypress-cy7c65632.patch b/queue-5.10/usb-core-hub-disable-autosuspend-for-cypress-cy7c65632.patch
new file mode 100644 (file)
index 0000000..74094f2
--- /dev/null
@@ -0,0 +1,50 @@
+From a7d8d1c7a7f73e780aa9ae74926ae5985b2f895f Mon Sep 17 00:00:00 2001
+From: Andrew Lunn <andrew@lunn.ch>
+Date: Mon, 14 Jun 2021 17:55:23 +0200
+Subject: usb: core: hub: Disable autosuspend for Cypress CY7C65632
+
+From: Andrew Lunn <andrew@lunn.ch>
+
+commit a7d8d1c7a7f73e780aa9ae74926ae5985b2f895f upstream.
+
+The Cypress CY7C65632 appears to have an issue with auto suspend and
+detecting devices, not too dissimilar to the SMSC 5534B hub. It is
+easiest to reproduce by connecting multiple mass storage devices to
+the hub at the same time. On a Lenovo Yoga, around 1 in 3 attempts
+result in the devices not being detected. It is however possible to
+make them appear using lsusb -v.
+
+Disabling autosuspend for this hub resolves the issue.
+
+Fixes: 1208f9e1d758 ("USB: hub: Fix the broken detection of USB3 device in SMSC hub")
+Cc: stable@vger.kernel.org
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/20210614155524.2228800-1-andrew@lunn.ch
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/hub.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -40,6 +40,8 @@
+ #define USB_VENDOR_GENESYS_LOGIC              0x05e3
+ #define USB_VENDOR_SMSC                               0x0424
+ #define USB_PRODUCT_USB5534B                  0x5534
++#define USB_VENDOR_CYPRESS                    0x04b4
++#define USB_PRODUCT_CY7C65632                 0x6570
+ #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND      0x01
+ #define HUB_QUIRK_DISABLE_AUTOSUSPEND         0x02
+@@ -5644,6 +5646,11 @@ static const struct usb_device_id hub_id
+       .bInterfaceClass = USB_CLASS_HUB,
+       .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND},
+     { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
++                   | USB_DEVICE_ID_MATCH_PRODUCT,
++      .idVendor = USB_VENDOR_CYPRESS,
++      .idProduct = USB_PRODUCT_CY7C65632,
++      .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND},
++    { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+                       | USB_DEVICE_ID_MATCH_INT_CLASS,
+       .idVendor = USB_VENDOR_GENESYS_LOGIC,
+       .bInterfaceClass = USB_CLASS_HUB,