From 26b206bae3a635e7ab96d43d0ffc42306b273ca8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 27 Jul 2020 15:32:08 +0200 Subject: [PATCH] 4.9-stable patches added patches: ath9k-fix-general-protection-fault-in-ath9k_hif_usb_rx_cb.patch ath9k-fix-regression-with-atheros-9271.patch io-mapping-indicate-mapping-failure.patch mm-memcg-fix-refcount-error-while-moving-and-swapping.patch parisc-add-atomic64_set_release-define-to-avoid-cpu-soft-lockups.patch --- ...tection-fault-in-ath9k_hif_usb_rx_cb.patch | 216 ++++++++++++++++++ ...h9k-fix-regression-with-atheros-9271.patch | 44 ++++ .../io-mapping-indicate-mapping-failure.patch | 73 ++++++ ...ount-error-while-moving-and-swapping.patch | 61 +++++ ...ase-define-to-avoid-cpu-soft-lockups.patch | 84 +++++++ queue-4.9/series | 5 + 6 files changed, 483 insertions(+) create mode 100644 queue-4.9/ath9k-fix-general-protection-fault-in-ath9k_hif_usb_rx_cb.patch create mode 100644 queue-4.9/ath9k-fix-regression-with-atheros-9271.patch create mode 100644 queue-4.9/io-mapping-indicate-mapping-failure.patch create mode 100644 queue-4.9/mm-memcg-fix-refcount-error-while-moving-and-swapping.patch create mode 100644 queue-4.9/parisc-add-atomic64_set_release-define-to-avoid-cpu-soft-lockups.patch diff --git a/queue-4.9/ath9k-fix-general-protection-fault-in-ath9k_hif_usb_rx_cb.patch b/queue-4.9/ath9k-fix-general-protection-fault-in-ath9k_hif_usb_rx_cb.patch new file mode 100644 index 00000000000..4372559241b --- /dev/null +++ b/queue-4.9/ath9k-fix-general-protection-fault-in-ath9k_hif_usb_rx_cb.patch @@ -0,0 +1,216 @@ +From 2bbcaaee1fcbd83272e29f31e2bb7e70d8c49e05 Mon Sep 17 00:00:00 2001 +From: Qiujun Huang +Date: Sat, 4 Apr 2020 12:18:38 +0800 +Subject: ath9k: Fix general protection fault in ath9k_hif_usb_rx_cb + +From: Qiujun Huang + +commit 2bbcaaee1fcbd83272e29f31e2bb7e70d8c49e05 upstream. + +In ath9k_hif_usb_rx_cb interface number is assumed to be 0. +usb_ifnum_to_if(urb->dev, 0) +But it isn't always true. + +The case reported by syzbot: +https://lore.kernel.org/linux-usb/000000000000666c9c05a1c05d12@google.com +usb 2-1: new high-speed USB device number 2 using dummy_hcd +usb 2-1: config 1 has an invalid interface number: 2 but max is 0 +usb 2-1: config 1 has no interface number 0 +usb 2-1: New USB device found, idVendor=0cf3, idProduct=9271, bcdDevice= +1.08 +usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +general protection fault, probably for non-canonical address +0xdffffc0000000015: 0000 [#1] SMP KASAN +KASAN: null-ptr-deref in range [0x00000000000000a8-0x00000000000000af] +CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.6.0-rc5-syzkaller #0 + +Call Trace +__usb_hcd_giveback_urb+0x29a/0x550 drivers/usb/core/hcd.c:1650 +usb_hcd_giveback_urb+0x368/0x420 drivers/usb/core/hcd.c:1716 +dummy_timer+0x1258/0x32ae drivers/usb/gadget/udc/dummy_hcd.c:1966 +call_timer_fn+0x195/0x6f0 kernel/time/timer.c:1404 +expire_timers kernel/time/timer.c:1449 [inline] +__run_timers kernel/time/timer.c:1773 [inline] +__run_timers kernel/time/timer.c:1740 [inline] +run_timer_softirq+0x5f9/0x1500 kernel/time/timer.c:1786 +__do_softirq+0x21e/0x950 kernel/softirq.c:292 +invoke_softirq kernel/softirq.c:373 [inline] +irq_exit+0x178/0x1a0 kernel/softirq.c:413 +exiting_irq arch/x86/include/asm/apic.h:546 [inline] +smp_apic_timer_interrupt+0x141/0x540 arch/x86/kernel/apic/apic.c:1146 +apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:829 + +Reported-and-tested-by: syzbot+40d5d2e8a4680952f042@syzkaller.appspotmail.com +Signed-off-by: Qiujun Huang +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20200404041838.10426-6-hqjagain@gmail.com +Cc: Viktor Jägersküpper +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/hif_usb.c | 48 +++++++++++++++++++++++-------- + drivers/net/wireless/ath/ath9k/hif_usb.h | 5 +++ + 2 files changed, 42 insertions(+), 11 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/hif_usb.c ++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c +@@ -641,9 +641,9 @@ err: + + static void ath9k_hif_usb_rx_cb(struct urb *urb) + { +- struct sk_buff *skb = (struct sk_buff *) urb->context; +- struct hif_device_usb *hif_dev = +- usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); ++ struct rx_buf *rx_buf = (struct rx_buf *)urb->context; ++ struct hif_device_usb *hif_dev = rx_buf->hif_dev; ++ struct sk_buff *skb = rx_buf->skb; + int ret; + + if (!skb) +@@ -683,14 +683,15 @@ resubmit: + return; + free: + kfree_skb(skb); ++ kfree(rx_buf); + } + + static void ath9k_hif_usb_reg_in_cb(struct urb *urb) + { +- struct sk_buff *skb = (struct sk_buff *) urb->context; ++ struct rx_buf *rx_buf = (struct rx_buf *)urb->context; ++ struct hif_device_usb *hif_dev = rx_buf->hif_dev; ++ struct sk_buff *skb = rx_buf->skb; + struct sk_buff *nskb; +- struct hif_device_usb *hif_dev = +- usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); + int ret; + + if (!skb) +@@ -748,6 +749,7 @@ resubmit: + return; + free: + kfree_skb(skb); ++ kfree(rx_buf); + urb->context = NULL; + } + +@@ -793,7 +795,7 @@ static int ath9k_hif_usb_alloc_tx_urbs(s + init_usb_anchor(&hif_dev->mgmt_submitted); + + for (i = 0; i < MAX_TX_URB_NUM; i++) { +- tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL); ++ tx_buf = kzalloc(sizeof(*tx_buf), GFP_KERNEL); + if (!tx_buf) + goto err; + +@@ -830,8 +832,9 @@ static void ath9k_hif_usb_dealloc_rx_urb + + static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev) + { +- struct urb *urb = NULL; ++ struct rx_buf *rx_buf = NULL; + struct sk_buff *skb = NULL; ++ struct urb *urb = NULL; + int i, ret; + + init_usb_anchor(&hif_dev->rx_submitted); +@@ -839,6 +842,12 @@ static int ath9k_hif_usb_alloc_rx_urbs(s + + for (i = 0; i < MAX_RX_URB_NUM; i++) { + ++ rx_buf = kzalloc(sizeof(*rx_buf), GFP_KERNEL); ++ if (!rx_buf) { ++ ret = -ENOMEM; ++ goto err_rxb; ++ } ++ + /* Allocate URB */ + urb = usb_alloc_urb(0, GFP_KERNEL); + if (urb == NULL) { +@@ -853,11 +862,14 @@ static int ath9k_hif_usb_alloc_rx_urbs(s + goto err_skb; + } + ++ rx_buf->hif_dev = hif_dev; ++ rx_buf->skb = skb; ++ + usb_fill_bulk_urb(urb, hif_dev->udev, + usb_rcvbulkpipe(hif_dev->udev, + USB_WLAN_RX_PIPE), + skb->data, MAX_RX_BUF_SIZE, +- ath9k_hif_usb_rx_cb, skb); ++ ath9k_hif_usb_rx_cb, rx_buf); + + /* Anchor URB */ + usb_anchor_urb(urb, &hif_dev->rx_submitted); +@@ -883,6 +895,8 @@ err_submit: + err_skb: + usb_free_urb(urb); + err_urb: ++ kfree(rx_buf); ++err_rxb: + ath9k_hif_usb_dealloc_rx_urbs(hif_dev); + return ret; + } +@@ -894,14 +908,21 @@ static void ath9k_hif_usb_dealloc_reg_in + + static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) + { +- struct urb *urb = NULL; ++ struct rx_buf *rx_buf = NULL; + struct sk_buff *skb = NULL; ++ struct urb *urb = NULL; + int i, ret; + + init_usb_anchor(&hif_dev->reg_in_submitted); + + for (i = 0; i < MAX_REG_IN_URB_NUM; i++) { + ++ rx_buf = kzalloc(sizeof(*rx_buf), GFP_KERNEL); ++ if (!rx_buf) { ++ ret = -ENOMEM; ++ goto err_rxb; ++ } ++ + /* Allocate URB */ + urb = usb_alloc_urb(0, GFP_KERNEL); + if (urb == NULL) { +@@ -916,11 +937,14 @@ static int ath9k_hif_usb_alloc_reg_in_ur + goto err_skb; + } + ++ rx_buf->hif_dev = hif_dev; ++ rx_buf->skb = skb; ++ + usb_fill_int_urb(urb, hif_dev->udev, + usb_rcvintpipe(hif_dev->udev, + USB_REG_IN_PIPE), + skb->data, MAX_REG_IN_BUF_SIZE, +- ath9k_hif_usb_reg_in_cb, skb, 1); ++ ath9k_hif_usb_reg_in_cb, rx_buf, 1); + + /* Anchor URB */ + usb_anchor_urb(urb, &hif_dev->reg_in_submitted); +@@ -946,6 +970,8 @@ err_submit: + err_skb: + usb_free_urb(urb); + err_urb: ++ kfree(rx_buf); ++err_rxb: + ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); + return ret; + } +--- a/drivers/net/wireless/ath/ath9k/hif_usb.h ++++ b/drivers/net/wireless/ath/ath9k/hif_usb.h +@@ -84,6 +84,11 @@ struct tx_buf { + struct list_head list; + }; + ++struct rx_buf { ++ struct sk_buff *skb; ++ struct hif_device_usb *hif_dev; ++}; ++ + #define HIF_USB_TX_STOP BIT(0) + #define HIF_USB_TX_FLUSH BIT(1) + diff --git a/queue-4.9/ath9k-fix-regression-with-atheros-9271.patch b/queue-4.9/ath9k-fix-regression-with-atheros-9271.patch new file mode 100644 index 00000000000..a994343c47d --- /dev/null +++ b/queue-4.9/ath9k-fix-regression-with-atheros-9271.patch @@ -0,0 +1,44 @@ +From 92f53e2fda8bb9a559ad61d57bfb397ce67ed0ab Mon Sep 17 00:00:00 2001 +From: Mark O'Donovan +Date: Sat, 11 Jul 2020 05:33:24 +0100 +Subject: ath9k: Fix regression with Atheros 9271 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mark O'Donovan + +commit 92f53e2fda8bb9a559ad61d57bfb397ce67ed0ab upstream. + +This fix allows ath9k_htc modules to connect to WLAN once again. + +Fixes: 2bbcaaee1fcb ("ath9k: Fix general protection fault in ath9k_hif_usb_rx_cb") +Link: https://bugzilla.kernel.org/show_bug.cgi?id=208251 +Signed-off-by: Mark O'Donovan +Reported-by: Roman Mamedov +Tested-by: Viktor Jägersküpper +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20200711043324.8079-1-shiftee@posteo.net +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/hif_usb.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath9k/hif_usb.c ++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c +@@ -731,11 +731,13 @@ static void ath9k_hif_usb_reg_in_cb(stru + return; + } + ++ rx_buf->skb = nskb; ++ + usb_fill_int_urb(urb, hif_dev->udev, + usb_rcvintpipe(hif_dev->udev, + USB_REG_IN_PIPE), + nskb->data, MAX_REG_IN_BUF_SIZE, +- ath9k_hif_usb_reg_in_cb, nskb, 1); ++ ath9k_hif_usb_reg_in_cb, rx_buf, 1); + } + + resubmit: diff --git a/queue-4.9/io-mapping-indicate-mapping-failure.patch b/queue-4.9/io-mapping-indicate-mapping-failure.patch new file mode 100644 index 00000000000..351bff91c97 --- /dev/null +++ b/queue-4.9/io-mapping-indicate-mapping-failure.patch @@ -0,0 +1,73 @@ +From e0b3e0b1a04367fc15c07f44e78361545b55357c Mon Sep 17 00:00:00 2001 +From: "Michael J. Ruhl" +Date: Thu, 23 Jul 2020 21:15:46 -0700 +Subject: io-mapping: indicate mapping failure + +From: Michael J. Ruhl + +commit e0b3e0b1a04367fc15c07f44e78361545b55357c upstream. + +The !ATOMIC_IOMAP version of io_maping_init_wc will always return +success, even when the ioremap fails. + +Since the ATOMIC_IOMAP version returns NULL when the init fails, and +callers check for a NULL return on error this is unexpected. + +During a device probe, where the ioremap failed, a crash can look like +this: + + BUG: unable to handle page fault for address: 0000000000210000 + #PF: supervisor write access in kernel mode + #PF: error_code(0x0002) - not-present page + Oops: 0002 [#1] PREEMPT SMP + CPU: 0 PID: 177 Comm: + RIP: 0010:fill_page_dma [i915] + gen8_ppgtt_create [i915] + i915_ppgtt_create [i915] + intel_gt_init [i915] + i915_gem_init [i915] + i915_driver_probe [i915] + pci_device_probe + really_probe + driver_probe_device + +The remap failure occurred much earlier in the probe. If it had been +propagated, the driver would have exited with an error. + +Return NULL on ioremap failure. + +[akpm@linux-foundation.org: detect ioremap_wc() errors earlier] + +Fixes: cafaf14a5d8f ("io-mapping: Always create a struct to hold metadata about the io-mapping") +Signed-off-by: Michael J. Ruhl +Signed-off-by: Andrew Morton +Reviewed-by: Andrew Morton +Cc: Mike Rapoport +Cc: Andy Shevchenko +Cc: Chris Wilson +Cc: Daniel Vetter +Cc: +Link: http://lkml.kernel.org/r/20200721171936.81563-1-michael.j.ruhl@intel.com +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/io-mapping.h | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/include/linux/io-mapping.h ++++ b/include/linux/io-mapping.h +@@ -120,9 +120,12 @@ io_mapping_init_wc(struct io_mapping *io + resource_size_t base, + unsigned long size) + { ++ iomap->iomem = ioremap_wc(base, size); ++ if (!iomap->iomem) ++ return NULL; ++ + iomap->base = base; + iomap->size = size; +- iomap->iomem = ioremap_wc(base, size); + #if defined(pgprot_noncached_wc) /* archs can't agree on a name ... */ + iomap->prot = pgprot_noncached_wc(PAGE_KERNEL); + #elif defined(pgprot_writecombine) diff --git a/queue-4.9/mm-memcg-fix-refcount-error-while-moving-and-swapping.patch b/queue-4.9/mm-memcg-fix-refcount-error-while-moving-and-swapping.patch new file mode 100644 index 00000000000..c25f27571c8 --- /dev/null +++ b/queue-4.9/mm-memcg-fix-refcount-error-while-moving-and-swapping.patch @@ -0,0 +1,61 @@ +From 8d22a9351035ef2ff12ef163a1091b8b8cf1e49c Mon Sep 17 00:00:00 2001 +From: Hugh Dickins +Date: Thu, 23 Jul 2020 21:15:24 -0700 +Subject: mm/memcg: fix refcount error while moving and swapping + +From: Hugh Dickins + +commit 8d22a9351035ef2ff12ef163a1091b8b8cf1e49c upstream. + +It was hard to keep a test running, moving tasks between memcgs with +move_charge_at_immigrate, while swapping: mem_cgroup_id_get_many()'s +refcount is discovered to be 0 (supposedly impossible), so it is then +forced to REFCOUNT_SATURATED, and after thousands of warnings in quick +succession, the test is at last put out of misery by being OOM killed. + +This is because of the way moved_swap accounting was saved up until the +task move gets completed in __mem_cgroup_clear_mc(), deferred from when +mem_cgroup_move_swap_account() actually exchanged old and new ids. +Concurrent activity can free up swap quicker than the task is scanned, +bringing id refcount down 0 (which should only be possible when +offlining). + +Just skip that optimization: do that part of the accounting immediately. + +Fixes: 615d66c37c75 ("mm: memcontrol: fix memcg id ref counter on swap charge move") +Signed-off-by: Hugh Dickins +Signed-off-by: Andrew Morton +Reviewed-by: Alex Shi +Cc: Johannes Weiner +Cc: Alex Shi +Cc: Shakeel Butt +Cc: Michal Hocko +Cc: +Link: http://lkml.kernel.org/r/alpine.LSU.2.11.2007071431050.4726@eggly.anvils +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/memcontrol.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -4794,7 +4794,6 @@ static void __mem_cgroup_clear_mc(void) + if (!mem_cgroup_is_root(mc.to)) + page_counter_uncharge(&mc.to->memory, mc.moved_swap); + +- mem_cgroup_id_get_many(mc.to, mc.moved_swap); + css_put_many(&mc.to->css, mc.moved_swap); + + mc.moved_swap = 0; +@@ -4972,7 +4971,8 @@ put: /* get_mctgt_type() gets the page + ent = target.ent; + if (!mem_cgroup_move_swap_account(ent, mc.from, mc.to)) { + mc.precharge--; +- /* we fixup refcnts and charges later. */ ++ mem_cgroup_id_get_many(mc.to, 1); ++ /* we fixup other refcnts and charges later. */ + mc.moved_swap++; + } + break; diff --git a/queue-4.9/parisc-add-atomic64_set_release-define-to-avoid-cpu-soft-lockups.patch b/queue-4.9/parisc-add-atomic64_set_release-define-to-avoid-cpu-soft-lockups.patch new file mode 100644 index 00000000000..166a00a7d8c --- /dev/null +++ b/queue-4.9/parisc-add-atomic64_set_release-define-to-avoid-cpu-soft-lockups.patch @@ -0,0 +1,84 @@ +From be6577af0cef934ccb036445314072e8cb9217b9 Mon Sep 17 00:00:00 2001 +From: John David Anglin +Date: Tue, 21 Jul 2020 07:36:59 -0400 +Subject: parisc: Add atomic64_set_release() define to avoid CPU soft lockups + +From: John David Anglin + +commit be6577af0cef934ccb036445314072e8cb9217b9 upstream. + +Stalls are quite frequent with recent kernels. I enabled +CONFIG_SOFTLOCKUP_DETECTOR and I caught the following stall: + +watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [cc1:22803] +CPU: 0 PID: 22803 Comm: cc1 Not tainted 5.6.17+ #3 +Hardware name: 9000/800/rp3440 + IAOQ[0]: d_alloc_parallel+0x384/0x688 + IAOQ[1]: d_alloc_parallel+0x388/0x688 + RP(r2): d_alloc_parallel+0x134/0x688 +Backtrace: + [<000000004036974c>] __lookup_slow+0xa4/0x200 + [<0000000040369fc8>] walk_component+0x288/0x458 + [<000000004036a9a0>] path_lookupat+0x88/0x198 + [<000000004036e748>] filename_lookup+0xa0/0x168 + [<000000004036e95c>] user_path_at_empty+0x64/0x80 + [<000000004035d93c>] vfs_statx+0x104/0x158 + [<000000004035dfcc>] __do_sys_lstat64+0x44/0x80 + [<000000004035e5a0>] sys_lstat64+0x20/0x38 + [<0000000040180054>] syscall_exit+0x0/0x14 + +The code was stuck in this loop in d_alloc_parallel: + + 4037d414: 0e 00 10 dc ldd 0(r16),ret0 + 4037d418: c7 fc 5f ed bb,< ret0,1f,4037d414 + 4037d41c: 08 00 02 40 nop + +This is the inner loop of bit_spin_lock which is called by hlist_bl_unlock in +d_alloc_parallel: + +static inline void bit_spin_lock(int bitnum, unsigned long *addr) +{ + /* + * Assuming the lock is uncontended, this never enters + * the body of the outer loop. If it is contended, then + * within the inner loop a non-atomic test is used to + * busywait with less bus contention for a good time to + * attempt to acquire the lock bit. + */ + preempt_disable(); +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) + while (unlikely(test_and_set_bit_lock(bitnum, addr))) { + preempt_enable(); + do { + cpu_relax(); + } while (test_bit(bitnum, addr)); + preempt_disable(); + } +#endif + __acquire(bitlock); +} + +After consideration, I realized that we must be losing bit unlocks. +Then, I noticed that we missed defining atomic64_set_release(). +Adding this define fixes the stalls in bit operations. + +Signed-off-by: Dave Anglin +Cc: stable@vger.kernel.org +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/include/asm/atomic.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/parisc/include/asm/atomic.h ++++ b/arch/parisc/include/asm/atomic.h +@@ -255,6 +255,8 @@ atomic64_set(atomic64_t *v, s64 i) + _atomic_spin_unlock_irqrestore(v, flags); + } + ++#define atomic64_set_release(v, i) atomic64_set((v), (i)) ++ + static __inline__ s64 + atomic64_read(const atomic64_t *v) + { diff --git a/queue-4.9/series b/queue-4.9/series index 95636748802..23b83620d1d 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -38,3 +38,8 @@ serial-8250-fix-null-ptr-deref-in-serial8250_start_tx.patch serial-8250_mtk-fix-high-speed-baud-rates-clamping.patch vt-reject-zero-sized-screen-buffer-size.patch makefile-fix-gcc_toolchain_dir-prefix-for-clang-cross-compilation.patch +mm-memcg-fix-refcount-error-while-moving-and-swapping.patch +io-mapping-indicate-mapping-failure.patch +parisc-add-atomic64_set_release-define-to-avoid-cpu-soft-lockups.patch +ath9k-fix-general-protection-fault-in-ath9k_hif_usb_rx_cb.patch +ath9k-fix-regression-with-atheros-9271.patch -- 2.47.3