From: Greg Kroah-Hartman Date: Mon, 21 Jun 2021 10:47:09 +0000 (+0200) Subject: 5.12-stable patches X-Git-Tag: v5.4.128~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a49751ef16a2725df7e1368583a202c3d68eafc9;p=thirdparty%2Fkernel%2Fstable-queue.git 5.12-stable patches added patches: arcv2-save-abi-registers-across-signal-handling.patch btrfs-zoned-fix-negative-space_info-bytes_readonly.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-amd-navi14-gpu-ats-as-broken.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 s390-mcck-fix-invalid-kvm-guest-condition-check.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 --- diff --git a/queue-5.12/arcv2-save-abi-registers-across-signal-handling.patch b/queue-5.12/arcv2-save-abi-registers-across-signal-handling.patch new file mode 100644 index 00000000000..7855dbe3034 --- /dev/null +++ b/queue-5.12/arcv2-save-abi-registers-across-signal-handling.patch @@ -0,0 +1,112 @@ +From 96f1b00138cb8f04c742c82d0a7c460b2202e887 Mon Sep 17 00:00:00 2001 +From: Vineet Gupta +Date: Tue, 8 Jun 2021 19:39:25 -0700 +Subject: ARCv2: save ABI registers across signal handling + +From: Vineet Gupta + +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: +Tested-by: kernel test robot +Reported-by: Vladimir Isaev +Signed-off-by: Vineet Gupta +Signed-off-by: Greg Kroah-Hartman +--- + 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.12/btrfs-zoned-fix-negative-space_info-bytes_readonly.patch b/queue-5.12/btrfs-zoned-fix-negative-space_info-bytes_readonly.patch new file mode 100644 index 00000000000..28916f565e1 --- /dev/null +++ b/queue-5.12/btrfs-zoned-fix-negative-space_info-bytes_readonly.patch @@ -0,0 +1,70 @@ +From f9f28e5bd0baee9708c9011897196f06ae3a2733 Mon Sep 17 00:00:00 2001 +From: Naohiro Aota +Date: Thu, 17 Jun 2021 13:56:18 +0900 +Subject: btrfs: zoned: fix negative space_info->bytes_readonly + +From: Naohiro Aota + +commit f9f28e5bd0baee9708c9011897196f06ae3a2733 upstream. + +Consider we have a using block group on zoned btrfs. + +|<- ZU ->|<- used ->|<---free--->| + `- Alloc offset +ZU: Zone unusable + +Marking the block group read-only will migrate the zone unusable bytes +to the read-only bytes. So, we will have this. + +|<- RO ->|<- used ->|<--- RO --->| + +RO: Read only + +When marking it back to read-write, btrfs_dec_block_group_ro() +subtracts the above "RO" bytes from the +space_info->bytes_readonly. And, it moves the zone unusable bytes back +and again subtracts those bytes from the space_info->bytes_readonly, +leading to negative bytes_readonly. + +This can be observed in the output as eg.: + + Data, single: total=512.00MiB, used=165.21MiB, zone_unusable=16.00EiB + Data, single: total=536870912, used=173256704, zone_unusable=18446744073603186688 + +This commit fixes the issue by reordering the operations. + +Link: https://github.com/naota/linux/issues/37 +Reported-by: David Sterba +Fixes: 169e0da91a21 ("btrfs: zoned: track unusable bytes for zones") +CC: stable@vger.kernel.org # 5.12+ +Reviewed-by: Johannes Thumshirn +Signed-off-by: Naohiro Aota +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/block-group.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/fs/btrfs/block-group.c ++++ b/fs/btrfs/block-group.c +@@ -2347,16 +2347,16 @@ void btrfs_dec_block_group_ro(struct btr + spin_lock(&sinfo->lock); + spin_lock(&cache->lock); + if (!--cache->ro) { +- num_bytes = cache->length - cache->reserved - +- cache->pinned - cache->bytes_super - +- cache->zone_unusable - cache->used; +- sinfo->bytes_readonly -= num_bytes; + if (btrfs_is_zoned(cache->fs_info)) { + /* Migrate zone_unusable bytes back */ + cache->zone_unusable = cache->alloc_offset - cache->used; + sinfo->bytes_zone_unusable += cache->zone_unusable; + sinfo->bytes_readonly -= cache->zone_unusable; + } ++ num_bytes = cache->length - cache->reserved - ++ cache->pinned - cache->bytes_super - ++ cache->zone_unusable - cache->used; ++ sinfo->bytes_readonly -= num_bytes; + list_del_init(&cache->ro_list); + } + spin_unlock(&cache->lock); diff --git a/queue-5.12/can-bcm-fix-infoleak-in-struct-bcm_msg_head.patch b/queue-5.12/can-bcm-fix-infoleak-in-struct-bcm_msg_head.patch new file mode 100644 index 00000000000..504270fa90e --- /dev/null +++ b/queue-5.12/can-bcm-fix-infoleak-in-struct-bcm_msg_head.patch @@ -0,0 +1,51 @@ +From 5e87ddbe3942e27e939bdc02deb8579b0cbd8ecc Mon Sep 17 00:00:00 2001 +From: Norbert Slusarek +Date: Sat, 12 Jun 2021 22:18:54 +0200 +Subject: can: bcm: fix infoleak in struct bcm_msg_head + +From: Norbert Slusarek + +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 +Signed-off-by: Norbert Slusarek +Acked-by: Oliver Hartkopp +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + 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.12/can-bcm-raw-isotp-use-per-module-netdevice-notifier.patch b/queue-5.12/can-bcm-raw-isotp-use-per-module-netdevice-notifier.patch new file mode 100644 index 00000000000..d4df9953ddd --- /dev/null +++ b/queue-5.12/can-bcm-raw-isotp-use-per-module-netdevice-notifier.patch @@ -0,0 +1,429 @@ +From 8d0caedb759683041d9db82069937525999ada53 Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Sat, 5 Jun 2021 19:26:35 +0900 +Subject: can: bcm/raw/isotp: use per module netdevice notifier + +From: Tetsuo Handa + +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 +Reported-by: syzbot +Reported-by: syzbot +Reviewed-by: Kirill Tkhai +Tested-by: syzbot +Tested-by: Oliver Hartkopp +Signed-off-by: Tetsuo Handa +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + 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; +@@ -1013,7 +1017,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); + +@@ -1317,21 +1328,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: +@@ -1357,7 +1363,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; + } + +@@ -1394,8 +1421,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; + } +@@ -1442,6 +1470,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; +@@ -1451,6 +1483,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; + } +@@ -1458,6 +1492,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); + +@@ -889,6 +916,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; +@@ -898,6 +929,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; + } +@@ -905,6 +938,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.12/can-j1939-fix-use-after-free-hold-skb-ref-while-in-use.patch b/queue-5.12/can-j1939-fix-use-after-free-hold-skb-ref-while-in-use.patch new file mode 100644 index 00000000000..f477907bfa6 --- /dev/null +++ b/queue-5.12/can-j1939-fix-use-after-free-hold-skb-ref-while-in-use.patch @@ -0,0 +1,201 @@ +From 2030043e616cab40f510299f09b636285e0a3678 Mon Sep 17 00:00:00 2001 +From: Oleksij Rempel +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 + +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 +Cc: linux-stable +Reported-by: syzbot+220c1a29987a9a490903@syzkaller.appspotmail.com +Reported-by: syzbot+45199c1b73b4013525cf@syzkaller.appspotmail.com +Signed-off-by: Oleksij Rempel +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + 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.12/can-mcba_usb-fix-memory-leak-in-mcba_usb.patch b/queue-5.12/can-mcba_usb-fix-memory-leak-in-mcba_usb.patch new file mode 100644 index 00000000000..451a626d7da --- /dev/null +++ b/queue-5.12/can-mcba_usb-fix-memory-leak-in-mcba_usb.patch @@ -0,0 +1,101 @@ +From 91c02557174be7f72e46ed7311e3bea1939840b0 Mon Sep 17 00:00:00 2001 +From: Pavel Skripkin +Date: Thu, 10 Jun 2021 00:58:33 +0300 +Subject: can: mcba_usb: fix memory leak in mcba_usb + +From: Pavel Skripkin + +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 +Reported-and-tested-by: syzbot+57281c762a3922e14dfe@syzkaller.appspotmail.com +Signed-off-by: Pavel Skripkin +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + 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.12/kvm-x86-fix-x86_emulator-slab-cache-leak.patch b/queue-5.12/kvm-x86-fix-x86_emulator-slab-cache-leak.patch new file mode 100644 index 00000000000..033feadbb6f --- /dev/null +++ b/queue-5.12/kvm-x86-fix-x86_emulator-slab-cache-leak.patch @@ -0,0 +1,40 @@ +From dfdc0a714d241bfbf951886c373cd1ae463fcc25 Mon Sep 17 00:00:00 2001 +From: Wanpeng Li +Date: Thu, 10 Jun 2021 21:59:33 -0700 +Subject: KVM: X86: Fix x86_emulator slab cache leak + +From: Wanpeng Li + +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 +Message-Id: <1623387573-5969-1-git-send-email-wanpengli@tencent.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/x86.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -8150,6 +8150,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); + #ifdef CONFIG_KVM_XEN + static_key_deferred_flush(&kvm_xen_enabled); diff --git a/queue-5.12/kvm-x86-immediately-reset-the-mmu-context-when-the-smm-flag-is-cleared.patch b/queue-5.12/kvm-x86-immediately-reset-the-mmu-context-when-the-smm-flag-is-cleared.patch new file mode 100644 index 00000000000..7d542ee63ff --- /dev/null +++ b/queue-5.12/kvm-x86-immediately-reset-the-mmu-context-when-the-smm-flag-is-cleared.patch @@ -0,0 +1,83 @@ +From 78fcb2c91adfec8ce3a2ba6b4d0dda89f2f4a7c6 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +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 + +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 +Message-Id: <20210609185619.992058-2-seanjc@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -6991,7 +6991,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.12/kvm-x86-mmu-calculate-and-check-full-mmu_role-for-nested-mmu.patch b/queue-5.12/kvm-x86-mmu-calculate-and-check-full-mmu_role-for-nested-mmu.patch new file mode 100644 index 00000000000..35262e4a4ae --- /dev/null +++ b/queue-5.12/kvm-x86-mmu-calculate-and-check-full-mmu_role-for-nested-mmu.patch @@ -0,0 +1,103 @@ +From 654430efde27248be563df9a88631204b5fe2df2 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +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 + +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 +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 +Message-Id: <20210610220026.1364486-1-seanjc@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -4726,9 +4726,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.12/pci-aardvark-fix-kernel-panic-during-pio-transfer.patch b/queue-5.12/pci-aardvark-fix-kernel-panic-during-pio-transfer.patch new file mode 100644 index 00000000000..e213a73e1b0 --- /dev/null +++ b/queue-5.12/pci-aardvark-fix-kernel-panic-during-pio-transfer.patch @@ -0,0 +1,150 @@ +From f18139966d072dab8e4398c95ce955a9742e04f7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +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 + +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 +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Bjorn Helgaas +Reviewed-by: Marek Behún +Cc: stable@vger.kernel.org # 7fbcb5da811b ("PCI: aardvark: Don't rely on jiffies while holding spinlock") +Signed-off-by: Greg Kroah-Hartman +--- + 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.12/pci-add-acs-quirk-for-broadcom-bcm57414-nic.patch b/queue-5.12/pci-add-acs-quirk-for-broadcom-bcm57414-nic.patch new file mode 100644 index 00000000000..bdd5ef67763 --- /dev/null +++ b/queue-5.12/pci-add-acs-quirk-for-broadcom-bcm57414-nic.patch @@ -0,0 +1,40 @@ +From db2f77e2bd99dbd2fb23ddde58f0fae392fe3338 Mon Sep 17 00:00:00 2001 +From: Sriharsha Basavapatna +Date: Fri, 21 May 2021 21:13:17 -0400 +Subject: PCI: Add ACS quirk for Broadcom BCM57414 NIC + +From: Sriharsha Basavapatna + +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 +Signed-off-by: Michael Chan +Signed-off-by: Bjorn Helgaas +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/quirks.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -4786,6 +4786,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.12/pci-mark-amd-navi14-gpu-ats-as-broken.patch b/queue-5.12/pci-mark-amd-navi14-gpu-ats-as-broken.patch new file mode 100644 index 00000000000..ad8ac1892bf --- /dev/null +++ b/queue-5.12/pci-mark-amd-navi14-gpu-ats-as-broken.patch @@ -0,0 +1,52 @@ +From e8946a53e2a698c148b3b3ed732f43c7747fbeb6 Mon Sep 17 00:00:00 2001 +From: Evan Quan +Date: Wed, 2 Jun 2021 10:12:55 +0800 +Subject: PCI: Mark AMD Navi14 GPU ATS as broken +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Evan Quan + +commit e8946a53e2a698c148b3b3ed732f43c7747fbeb6 upstream. + +Observed unexpected GPU hang during runpm stress test on 0x7341 rev 0x00. +Further debugging shows broken ATS is related. + +Disable ATS on this part. Similar issues on other devices: + + a2da5d8cc0b0 ("PCI: Mark AMD Raven iGPU ATS as broken in some platforms") + 45beb31d3afb ("PCI: Mark AMD Navi10 GPU rev 0x00 ATS as broken") + 5e89cd303e3a ("PCI: Mark AMD Navi14 GPU rev 0xc5 ATS as broken") + +Suggested-by: Alex Deucher +Link: https://lore.kernel.org/r/20210602021255.939090-1-evan.quan@amd.com +Signed-off-by: Evan Quan +Signed-off-by: Bjorn Helgaas +Reviewed-by: Krzysztof Wilczyński +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/quirks.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -5187,7 +5187,8 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SE + static void quirk_amd_harvest_no_ats(struct pci_dev *pdev) + { + if ((pdev->device == 0x7312 && pdev->revision != 0x00) || +- (pdev->device == 0x7340 && pdev->revision != 0xc5)) ++ (pdev->device == 0x7340 && pdev->revision != 0xc5) || ++ (pdev->device == 0x7341 && pdev->revision != 0x00)) + return; + + if (pdev->device == 0x15d8) { +@@ -5214,6 +5215,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AT + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7312, quirk_amd_harvest_no_ats); + /* AMD Navi14 dGPU */ + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7340, quirk_amd_harvest_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7341, quirk_amd_harvest_no_ats); + /* AMD Raven platform iGPU */ + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x15d8, quirk_amd_harvest_no_ats); + #endif /* CONFIG_PCI_ATS */ diff --git a/queue-5.12/pci-mark-some-nvidia-gpus-to-avoid-bus-reset.patch b/queue-5.12/pci-mark-some-nvidia-gpus-to-avoid-bus-reset.patch new file mode 100644 index 00000000000..3c80539b37d --- /dev/null +++ b/queue-5.12/pci-mark-some-nvidia-gpus-to-avoid-bus-reset.patch @@ -0,0 +1,48 @@ +From 4c207e7121fa92b66bf1896bf8ccb9edfb0f9731 Mon Sep 17 00:00:00 2001 +From: Shanker Donthineni +Date: Tue, 8 Jun 2021 11:18:56 +0530 +Subject: PCI: Mark some NVIDIA GPUs to avoid bus reset + +From: Shanker Donthineni + +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 +Signed-off-by: Bjorn Helgaas +Reviewed-by: Sinan Kaya +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/quirks.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -3559,6 +3559,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.12/pci-mark-ti-c667x-to-avoid-bus-reset.patch b/queue-5.12/pci-mark-ti-c667x-to-avoid-bus-reset.patch new file mode 100644 index 00000000000..ce5636ce10a --- /dev/null +++ b/queue-5.12/pci-mark-ti-c667x-to-avoid-bus-reset.patch @@ -0,0 +1,48 @@ +From b5cf198e74a91073d12839a3e2db99994a39995d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Antti=20J=C3=A4rvinen?= +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 + +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 +Signed-off-by: Bjorn Helgaas +Reviewed-by: Kishon Vijay Abraham I +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/quirks.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -3578,6 +3578,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.12/pci-work-around-huawei-intelligent-nic-vf-flr-erratum.patch b/queue-5.12/pci-work-around-huawei-intelligent-nic-vf-flr-erratum.patch new file mode 100644 index 00000000000..31426369cd7 --- /dev/null +++ b/queue-5.12/pci-work-around-huawei-intelligent-nic-vf-flr-erratum.patch @@ -0,0 +1,117 @@ +From ce00322c2365e1f7b0312f2f493539c833465d97 Mon Sep 17 00:00:00 2001 +From: Chiqijun +Date: Mon, 24 May 2021 17:44:07 -0500 +Subject: PCI: Work around Huawei Intelligent NIC VF FLR erratum + +From: Chiqijun + +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 +Signed-off-by: Bjorn Helgaas +Reviewed-by: Alex Williamson +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/quirks.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 65 insertions(+) + +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -3935,6 +3935,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 }, +@@ -3946,6 +4009,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.12/s390-ap-fix-hanging-ioctl-caused-by-wrong-msg-counter.patch b/queue-5.12/s390-ap-fix-hanging-ioctl-caused-by-wrong-msg-counter.patch new file mode 100644 index 00000000000..b9e8b6599e0 --- /dev/null +++ b/queue-5.12/s390-ap-fix-hanging-ioctl-caused-by-wrong-msg-counter.patch @@ -0,0 +1,88 @@ +From e73a99f3287a740a07d6618e9470f4d6cb217da8 Mon Sep 17 00:00:00 2001 +From: Harald Freudenberger +Date: Tue, 1 Jun 2021 08:27:29 +0200 +Subject: s390/ap: Fix hanging ioctl caused by wrong msg counter + +From: Harald Freudenberger + +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 +Cc: stable@vger.kernel.org +Signed-off-by: Vasily Gorbik +Signed-off-by: Greg Kroah-Hartman +--- + 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.12/s390-mcck-fix-calculation-of-sie-critical-section-size.patch b/queue-5.12/s390-mcck-fix-calculation-of-sie-critical-section-size.patch new file mode 100644 index 00000000000..214cf053880 --- /dev/null +++ b/queue-5.12/s390-mcck-fix-calculation-of-sie-critical-section-size.patch @@ -0,0 +1,35 @@ +From 5bcbe3285fb614c49db6b238253f7daff7e66312 Mon Sep 17 00:00:00 2001 +From: Alexander Gordeev +Date: Mon, 17 May 2021 08:18:11 +0200 +Subject: s390/mcck: fix calculation of SIE critical section size + +From: Alexander Gordeev + +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: +Signed-off-by: Alexander Gordeev +Reviewed-by: Christian Borntraeger +Signed-off-by: Heiko Carstens +Signed-off-by: Vasily Gorbik +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -651,7 +651,7 @@ ENDPROC(stack_overflow) + .Lcleanup_sie_mcck: + larl %r13,.Lsie_entry + slgr %r9,%r13 +- larl %r13,.Lsie_skip ++ lghi %r13,.Lsie_skip - .Lsie_entry + clgr %r9,%r13 + jhe .Lcleanup_sie_int + oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST diff --git a/queue-5.12/s390-mcck-fix-invalid-kvm-guest-condition-check.patch b/queue-5.12/s390-mcck-fix-invalid-kvm-guest-condition-check.patch new file mode 100644 index 00000000000..2668d7a4478 --- /dev/null +++ b/queue-5.12/s390-mcck-fix-invalid-kvm-guest-condition-check.patch @@ -0,0 +1,37 @@ +From 1874cb13d5d7cafa61ce93a760093ebc5485b6ab Mon Sep 17 00:00:00 2001 +From: Alexander Gordeev +Date: Mon, 17 May 2021 08:18:12 +0200 +Subject: s390/mcck: fix invalid KVM guest condition check + +From: Alexander Gordeev + +commit 1874cb13d5d7cafa61ce93a760093ebc5485b6ab upstream. + +Wrong condition check is used to decide if a machine check hit +while in KVM guest. As result of this check the instruction +following the SIE critical section might be considered as still +in KVM guest and _CIF_MCCK_GUEST CPU flag mistakenly set as +result. + +Fixes: c929500d7a5a ("s390/nmi: s390: New low level handling for machine check happening in guest") +Cc: +Signed-off-by: Alexander Gordeev +Reviewed-by: Christian Borntraeger +Signed-off-by: Heiko Carstens +Signed-off-by: Vasily Gorbik +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -653,7 +653,7 @@ ENDPROC(stack_overflow) + slgr %r9,%r13 + larl %r13,.Lsie_skip + clgr %r9,%r13 +- jh .Lcleanup_sie_int ++ jhe .Lcleanup_sie_int + oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST + .Lcleanup_sie_int: + BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) diff --git a/queue-5.12/series b/queue-5.12/series index 52428273132..1213163cf4d 100644 --- a/queue-5.12/series +++ b/queue-5.12/series @@ -114,3 +114,26 @@ perf-metricgroup-fix-find_evsel_group-event-selector.patch perf-metricgroup-return-error-code-from-metricgroup_.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-mark-amd-navi14-gpu-ats-as-broken.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 +btrfs-zoned-fix-negative-space_info-bytes_readonly.patch +s390-mcck-fix-invalid-kvm-guest-condition-check.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.12/tracing-do-no-increment-trace_clock_global-by-one.patch b/queue-5.12/tracing-do-no-increment-trace_clock_global-by-one.patch new file mode 100644 index 00000000000..4fdc12275b1 --- /dev/null +++ b/queue-5.12/tracing-do-no-increment-trace_clock_global-by-one.patch @@ -0,0 +1,131 @@ +From 89529d8b8f8daf92d9979382b8d2eb39966846ea Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" +Date: Thu, 17 Jun 2021 17:12:35 -0400 +Subject: tracing: Do no increment trace_clock_global() by one + +From: Steven Rostedt (VMware) + +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 ] + + + 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) +Signed-off-by: Greg Kroah-Hartman +--- + 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.12/tracing-do-not-stop-recording-cmdlines-when-tracing-is-off.patch b/queue-5.12/tracing-do-not-stop-recording-cmdlines-when-tracing-is-off.patch new file mode 100644 index 00000000000..96e1cf4537a --- /dev/null +++ b/queue-5.12/tracing-do-not-stop-recording-cmdlines-when-tracing-is-off.patch @@ -0,0 +1,52 @@ +From 85550c83da421fb12dc1816c45012e1e638d2b38 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" +Date: Thu, 17 Jun 2021 13:47:25 -0400 +Subject: tracing: Do not stop recording cmdlines when tracing is off + +From: Steven Rostedt (VMware) + +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) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -2486,8 +2486,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.12/tracing-do-not-stop-recording-comms-if-the-trace-file-is-being-read.patch b/queue-5.12/tracing-do-not-stop-recording-comms-if-the-trace-file-is-being-read.patch new file mode 100644 index 00000000000..bd02987630c --- /dev/null +++ b/queue-5.12/tracing-do-not-stop-recording-comms-if-the-trace-file-is-being-read.patch @@ -0,0 +1,56 @@ +From 4fdd595e4f9a1ff6d93ec702eaecae451cfc6591 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" +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) + +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) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace.c | 9 --------- + 1 file changed, 9 deletions(-) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -2198,9 +2198,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]; +@@ -3740,9 +3737,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; +@@ -3785,9 +3779,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.12/usb-chipidea-imx-fix-battery-charger-1.2-cdp-detection.patch b/queue-5.12/usb-chipidea-imx-fix-battery-charger-1.2-cdp-detection.patch new file mode 100644 index 00000000000..749a6f869fa --- /dev/null +++ b/queue-5.12/usb-chipidea-imx-fix-battery-charger-1.2-cdp-detection.patch @@ -0,0 +1,79 @@ +From c6d580d96f140596d69220f60ce0cfbea4ee5c0f Mon Sep 17 00:00:00 2001 +From: Breno Lima +Date: Mon, 14 Jun 2021 13:50:13 -0400 +Subject: usb: chipidea: imx: Fix Battery Charger 1.2 CDP detection + +From: Breno Lima + +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: +Fixes: 746f316b753a ("usb: chipidea: introduce imx7d USB charger detection") +Signed-off-by: Breno Lima +Signed-off-by: Jun Li +Link: https://lore.kernel.org/r/20210614175013.495808-1-breno.lima@nxp.com +Signed-off-by: Peter Chen +Signed-off-by: Greg Kroah-Hartman +--- + 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.12/usb-core-hub-disable-autosuspend-for-cypress-cy7c65632.patch b/queue-5.12/usb-core-hub-disable-autosuspend-for-cypress-cy7c65632.patch new file mode 100644 index 00000000000..326ac74f19d --- /dev/null +++ b/queue-5.12/usb-core-hub-disable-autosuspend-for-cypress-cy7c65632.patch @@ -0,0 +1,50 @@ +From a7d8d1c7a7f73e780aa9ae74926ae5985b2f895f Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 14 Jun 2021 17:55:23 +0200 +Subject: usb: core: hub: Disable autosuspend for Cypress CY7C65632 + +From: Andrew Lunn + +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 +Link: https://lore.kernel.org/r/20210614155524.2228800-1-andrew@lunn.ch +Signed-off-by: Greg Kroah-Hartman +--- + 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 + +@@ -5645,6 +5647,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,