]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 1 Feb 2021 14:23:01 +0000 (15:23 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 1 Feb 2021 14:23:01 +0000 (15:23 +0100)
added patches:
leds-trigger-fix-potential-deadlock-with-libata.patch
mt7601u-fix-kernel-crash-unplugging-the-device.patch
mt7601u-fix-rx-buffer-refcounting.patch

queue-4.14/leds-trigger-fix-potential-deadlock-with-libata.patch [new file with mode: 0644]
queue-4.14/mt7601u-fix-kernel-crash-unplugging-the-device.patch [new file with mode: 0644]
queue-4.14/mt7601u-fix-rx-buffer-refcounting.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/leds-trigger-fix-potential-deadlock-with-libata.patch b/queue-4.14/leds-trigger-fix-potential-deadlock-with-libata.patch
new file mode 100644 (file)
index 0000000..514e9aa
--- /dev/null
@@ -0,0 +1,270 @@
+From 27af8e2c90fba242460b01fa020e6e19ed68c495 Mon Sep 17 00:00:00 2001
+From: Andrea Righi <andrea.righi@canonical.com>
+Date: Wed, 25 Nov 2020 16:18:22 +0100
+Subject: leds: trigger: fix potential deadlock with libata
+
+From: Andrea Righi <andrea.righi@canonical.com>
+
+commit 27af8e2c90fba242460b01fa020e6e19ed68c495 upstream.
+
+We have the following potential deadlock condition:
+
+ ========================================================
+ WARNING: possible irq lock inversion dependency detected
+ 5.10.0-rc2+ #25 Not tainted
+ --------------------------------------------------------
+ swapper/3/0 just changed the state of lock:
+ ffff8880063bd618 (&host->lock){-...}-{2:2}, at: ata_bmdma_interrupt+0x27/0x200
+ but this lock took another, HARDIRQ-READ-unsafe lock in the past:
+  (&trig->leddev_list_lock){.+.?}-{2:2}
+
+ and interrupts could create inverse lock ordering between them.
+
+ other info that might help us debug this:
+  Possible interrupt unsafe locking scenario:
+
+        CPU0                    CPU1
+        ----                    ----
+   lock(&trig->leddev_list_lock);
+                                local_irq_disable();
+                                lock(&host->lock);
+                                lock(&trig->leddev_list_lock);
+   <Interrupt>
+     lock(&host->lock);
+
+  *** DEADLOCK ***
+
+ no locks held by swapper/3/0.
+
+ the shortest dependencies between 2nd lock and 1st lock:
+  -> (&trig->leddev_list_lock){.+.?}-{2:2} ops: 46 {
+     HARDIRQ-ON-R at:
+                       lock_acquire+0x15f/0x420
+                       _raw_read_lock+0x42/0x90
+                       led_trigger_event+0x2b/0x70
+                       rfkill_global_led_trigger_worker+0x94/0xb0
+                       process_one_work+0x240/0x560
+                       worker_thread+0x58/0x3d0
+                       kthread+0x151/0x170
+                       ret_from_fork+0x1f/0x30
+     IN-SOFTIRQ-R at:
+                       lock_acquire+0x15f/0x420
+                       _raw_read_lock+0x42/0x90
+                       led_trigger_event+0x2b/0x70
+                       kbd_bh+0x9e/0xc0
+                       tasklet_action_common.constprop.0+0xe9/0x100
+                       tasklet_action+0x22/0x30
+                       __do_softirq+0xcc/0x46d
+                       run_ksoftirqd+0x3f/0x70
+                       smpboot_thread_fn+0x116/0x1f0
+                       kthread+0x151/0x170
+                       ret_from_fork+0x1f/0x30
+     SOFTIRQ-ON-R at:
+                       lock_acquire+0x15f/0x420
+                       _raw_read_lock+0x42/0x90
+                       led_trigger_event+0x2b/0x70
+                       rfkill_global_led_trigger_worker+0x94/0xb0
+                       process_one_work+0x240/0x560
+                       worker_thread+0x58/0x3d0
+                       kthread+0x151/0x170
+                       ret_from_fork+0x1f/0x30
+     INITIAL READ USE at:
+                           lock_acquire+0x15f/0x420
+                           _raw_read_lock+0x42/0x90
+                           led_trigger_event+0x2b/0x70
+                           rfkill_global_led_trigger_worker+0x94/0xb0
+                           process_one_work+0x240/0x560
+                           worker_thread+0x58/0x3d0
+                           kthread+0x151/0x170
+                           ret_from_fork+0x1f/0x30
+   }
+   ... key      at: [<ffffffff83da4c00>] __key.0+0x0/0x10
+   ... acquired at:
+    _raw_read_lock+0x42/0x90
+    led_trigger_blink_oneshot+0x3b/0x90
+    ledtrig_disk_activity+0x3c/0xa0
+    ata_qc_complete+0x26/0x450
+    ata_do_link_abort+0xa3/0xe0
+    ata_port_freeze+0x2e/0x40
+    ata_hsm_qc_complete+0x94/0xa0
+    ata_sff_hsm_move+0x177/0x7a0
+    ata_sff_pio_task+0xc7/0x1b0
+    process_one_work+0x240/0x560
+    worker_thread+0x58/0x3d0
+    kthread+0x151/0x170
+    ret_from_fork+0x1f/0x30
+
+ -> (&host->lock){-...}-{2:2} ops: 69 {
+    IN-HARDIRQ-W at:
+                     lock_acquire+0x15f/0x420
+                     _raw_spin_lock_irqsave+0x52/0xa0
+                     ata_bmdma_interrupt+0x27/0x200
+                     __handle_irq_event_percpu+0xd5/0x2b0
+                     handle_irq_event+0x57/0xb0
+                     handle_edge_irq+0x8c/0x230
+                     asm_call_irq_on_stack+0xf/0x20
+                     common_interrupt+0x100/0x1c0
+                     asm_common_interrupt+0x1e/0x40
+                     native_safe_halt+0xe/0x10
+                     arch_cpu_idle+0x15/0x20
+                     default_idle_call+0x59/0x1c0
+                     do_idle+0x22c/0x2c0
+                     cpu_startup_entry+0x20/0x30
+                     start_secondary+0x11d/0x150
+                     secondary_startup_64_no_verify+0xa6/0xab
+    INITIAL USE at:
+                    lock_acquire+0x15f/0x420
+                    _raw_spin_lock_irqsave+0x52/0xa0
+                    ata_dev_init+0x54/0xe0
+                    ata_link_init+0x8b/0xd0
+                    ata_port_alloc+0x1f1/0x210
+                    ata_host_alloc+0xf1/0x130
+                    ata_host_alloc_pinfo+0x14/0xb0
+                    ata_pci_sff_prepare_host+0x41/0xa0
+                    ata_pci_bmdma_prepare_host+0x14/0x30
+                    piix_init_one+0x21f/0x600
+                    local_pci_probe+0x48/0x80
+                    pci_device_probe+0x105/0x1c0
+                    really_probe+0x221/0x490
+                    driver_probe_device+0xe9/0x160
+                    device_driver_attach+0xb2/0xc0
+                    __driver_attach+0x91/0x150
+                    bus_for_each_dev+0x81/0xc0
+                    driver_attach+0x1e/0x20
+                    bus_add_driver+0x138/0x1f0
+                    driver_register+0x91/0xf0
+                    __pci_register_driver+0x73/0x80
+                    piix_init+0x1e/0x2e
+                    do_one_initcall+0x5f/0x2d0
+                    kernel_init_freeable+0x26f/0x2cf
+                    kernel_init+0xe/0x113
+                    ret_from_fork+0x1f/0x30
+  }
+  ... key      at: [<ffffffff83d9fdc0>] __key.6+0x0/0x10
+  ... acquired at:
+    __lock_acquire+0x9da/0x2370
+    lock_acquire+0x15f/0x420
+    _raw_spin_lock_irqsave+0x52/0xa0
+    ata_bmdma_interrupt+0x27/0x200
+    __handle_irq_event_percpu+0xd5/0x2b0
+    handle_irq_event+0x57/0xb0
+    handle_edge_irq+0x8c/0x230
+    asm_call_irq_on_stack+0xf/0x20
+    common_interrupt+0x100/0x1c0
+    asm_common_interrupt+0x1e/0x40
+    native_safe_halt+0xe/0x10
+    arch_cpu_idle+0x15/0x20
+    default_idle_call+0x59/0x1c0
+    do_idle+0x22c/0x2c0
+    cpu_startup_entry+0x20/0x30
+    start_secondary+0x11d/0x150
+    secondary_startup_64_no_verify+0xa6/0xab
+
+This lockdep splat is reported after:
+commit e918188611f0 ("locking: More accurate annotations for read_lock()")
+
+To clarify:
+ - read-locks are recursive only in interrupt context (when
+   in_interrupt() returns true)
+ - after acquiring host->lock in CPU1, another cpu (i.e. CPU2) may call
+   write_lock(&trig->leddev_list_lock) that would be blocked by CPU0
+   that holds trig->leddev_list_lock in read-mode
+ - when CPU1 (ata_ac_complete()) tries to read-lock
+   trig->leddev_list_lock, it would be blocked by the write-lock waiter
+   on CPU2 (because we are not in interrupt context, so the read-lock is
+   not recursive)
+ - at this point if an interrupt happens on CPU0 and
+   ata_bmdma_interrupt() is executed it will try to acquire host->lock,
+   that is held by CPU1, that is currently blocked by CPU2, so:
+
+   * CPU0 blocked by CPU1
+   * CPU1 blocked by CPU2
+   * CPU2 blocked by CPU0
+
+     *** DEADLOCK ***
+
+The deadlock scenario is better represented by the following schema
+(thanks to Boqun Feng <boqun.feng@gmail.com> for the schema and the
+detailed explanation of the deadlock condition):
+
+ CPU 0:                          CPU 1:                        CPU 2:
+ -----                           -----                         -----
+ led_trigger_event():
+   read_lock(&trig->leddev_list_lock);
+                               <workqueue>
+                               ata_hsm_qc_complete():
+                                 spin_lock_irqsave(&host->lock);
+                                                               write_lock(&trig->leddev_list_lock);
+                                 ata_port_freeze():
+                                   ata_do_link_abort():
+                                     ata_qc_complete():
+                                       ledtrig_disk_activity():
+                                         led_trigger_blink_oneshot():
+                                           read_lock(&trig->leddev_list_lock);
+                                           // ^ not in in_interrupt() context, so could get blocked by CPU 2
+ <interrupt>
+   ata_bmdma_interrupt():
+     spin_lock_irqsave(&host->lock);
+
+Fix by using read_lock_irqsave/irqrestore() in led_trigger_event(), so
+that no interrupt can happen in between, preventing the deadlock
+condition.
+
+Apply the same change to led_trigger_blink_setup() as well, since the
+same deadlock scenario can also happen in power_supply_update_bat_leds()
+-> led_trigger_blink() -> led_trigger_blink_setup() (workqueue context),
+and potentially prevent other similar usages.
+
+Link: https://lore.kernel.org/lkml/20201101092614.GB3989@xps-13-7390/
+Fixes: eb25cb9956cc ("leds: convert IDE trigger to common disk trigger")
+Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
+Signed-off-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/leds/led-triggers.c |   10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/leds/led-triggers.c
++++ b/drivers/leds/led-triggers.c
+@@ -283,14 +283,15 @@ void led_trigger_event(struct led_trigge
+                       enum led_brightness brightness)
+ {
+       struct led_classdev *led_cdev;
++      unsigned long flags;
+       if (!trig)
+               return;
+-      read_lock(&trig->leddev_list_lock);
++      read_lock_irqsave(&trig->leddev_list_lock, flags);
+       list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list)
+               led_set_brightness(led_cdev, brightness);
+-      read_unlock(&trig->leddev_list_lock);
++      read_unlock_irqrestore(&trig->leddev_list_lock, flags);
+ }
+ EXPORT_SYMBOL_GPL(led_trigger_event);
+@@ -301,11 +302,12 @@ static void led_trigger_blink_setup(stru
+                            int invert)
+ {
+       struct led_classdev *led_cdev;
++      unsigned long flags;
+       if (!trig)
+               return;
+-      read_lock(&trig->leddev_list_lock);
++      read_lock_irqsave(&trig->leddev_list_lock, flags);
+       list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) {
+               if (oneshot)
+                       led_blink_set_oneshot(led_cdev, delay_on, delay_off,
+@@ -313,7 +315,7 @@ static void led_trigger_blink_setup(stru
+               else
+                       led_blink_set(led_cdev, delay_on, delay_off);
+       }
+-      read_unlock(&trig->leddev_list_lock);
++      read_unlock_irqrestore(&trig->leddev_list_lock, flags);
+ }
+ void led_trigger_blink(struct led_trigger *trig,
diff --git a/queue-4.14/mt7601u-fix-kernel-crash-unplugging-the-device.patch b/queue-4.14/mt7601u-fix-kernel-crash-unplugging-the-device.patch
new file mode 100644 (file)
index 0000000..ea5a4ce
--- /dev/null
@@ -0,0 +1,78 @@
+From 0acb20a5438c36e0cf2b8bf255f314b59fcca6ef Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Sun, 17 Jan 2021 22:46:01 +0100
+Subject: mt7601u: fix kernel crash unplugging the device
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+commit 0acb20a5438c36e0cf2b8bf255f314b59fcca6ef upstream.
+
+The following crash log can occur unplugging the usb dongle since,
+after the urb poison in mt7601u_free_tx_queue(), usb_submit_urb() will
+always fail resulting in a skb kfree while the skb has been already
+queued.
+
+Fix the issue enqueuing the skb only if usb_submit_urb() succeed.
+
+Hardware name: Hewlett-Packard 500-539ng/2B2C, BIOS 80.06 04/01/2015
+Workqueue: usb_hub_wq hub_event
+RIP: 0010:skb_trim+0x2c/0x30
+RSP: 0000:ffffb4c88005bba8 EFLAGS: 00010206
+RAX: 000000004ad483ee RBX: ffff9a236625dee0 RCX: 000000000000662f
+RDX: 000000000000000c RSI: 0000000000000000 RDI: ffff9a2343179300
+RBP: ffff9a2343179300 R08: 0000000000000001 R09: 0000000000000000
+R10: ffff9a23748f7840 R11: 0000000000000001 R12: ffff9a236625e4d4
+R13: ffff9a236625dee0 R14: 0000000000001080 R15: 0000000000000008
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007fd410a34ef8 CR3: 00000001416ee001 CR4: 00000000001706f0
+Call Trace:
+ mt7601u_tx_status+0x3e/0xa0 [mt7601u]
+ mt7601u_dma_cleanup+0xca/0x110 [mt7601u]
+ mt7601u_cleanup+0x22/0x30 [mt7601u]
+ mt7601u_disconnect+0x22/0x60 [mt7601u]
+ usb_unbind_interface+0x8a/0x270
+ ? kernfs_find_ns+0x35/0xd0
+ __device_release_driver+0x17a/0x230
+ device_release_driver+0x24/0x30
+ bus_remove_device+0xdb/0x140
+ device_del+0x18b/0x430
+ ? kobject_put+0x98/0x1d0
+ usb_disable_device+0xc6/0x1f0
+ usb_disconnect.cold+0x7e/0x20a
+ hub_event+0xbf3/0x1870
+ process_one_work+0x1b6/0x350
+ worker_thread+0x53/0x3e0
+ ? process_one_work+0x350/0x350
+ kthread+0x11b/0x140
+ ? __kthread_bind_mask+0x60/0x60
+ ret_from_fork+0x22/0x30
+
+Fixes: 23377c200b2eb ("mt7601u: fix possible memory leak when the device is disconnected")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Acked-by: Jakub Kicinski <kubakici@wp.pl>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/3b85219f669a63a8ced1f43686de05915a580489.1610919247.git.lorenzo@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/mediatek/mt7601u/dma.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/mediatek/mt7601u/dma.c
++++ b/drivers/net/wireless/mediatek/mt7601u/dma.c
+@@ -318,7 +318,6 @@ static int mt7601u_dma_submit_tx(struct
+       }
+       e = &q->e[q->end];
+-      e->skb = skb;
+       usb_fill_bulk_urb(e->urb, usb_dev, snd_pipe, skb->data, skb->len,
+                         mt7601u_complete_tx, q);
+       ret = usb_submit_urb(e->urb, GFP_ATOMIC);
+@@ -336,6 +335,7 @@ static int mt7601u_dma_submit_tx(struct
+       q->end = (q->end + 1) % q->entries;
+       q->used++;
++      e->skb = skb;
+       if (q->used >= q->entries)
+               ieee80211_stop_queue(dev->hw, skb_get_queue_mapping(skb));
diff --git a/queue-4.14/mt7601u-fix-rx-buffer-refcounting.patch b/queue-4.14/mt7601u-fix-rx-buffer-refcounting.patch
new file mode 100644 (file)
index 0000000..a9a2cb5
--- /dev/null
@@ -0,0 +1,74 @@
+From d24c790577ef01bfa01da2b131313a38c843a634 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Thu, 14 Jan 2021 18:10:52 +0100
+Subject: mt7601u: fix rx buffer refcounting
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+commit d24c790577ef01bfa01da2b131313a38c843a634 upstream.
+
+Fix the following crash due to erroneous page refcounting:
+
+[   32.445919] BUG: Bad page state in process swapper/1  pfn:11f65a
+[   32.447409] page:00000000938f0632 refcount:0 mapcount:-128 mapping:0000000000000000 index:0x0 pfn:0x11f65a
+[   32.449605] flags: 0x8000000000000000()
+[   32.450421] raw: 8000000000000000 ffffffff825b0148 ffffea00045ae988 0000000000000000
+[   32.451795] raw: 0000000000000000 0000000000000001 00000000ffffff7f 0000000000000000
+[   32.452999] page dumped because: nonzero mapcount
+[   32.453888] Modules linked in:
+[   32.454492] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 5.11.0-rc2+ #1976
+[   32.455695] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.14.0-1.fc33 04/01/2014
+[   32.457157] Call Trace:
+[   32.457636]  <IRQ>
+[   32.457993]  dump_stack+0x77/0x97
+[   32.458576]  bad_page.cold+0x65/0x96
+[   32.459198]  get_page_from_freelist+0x46a/0x11f0
+[   32.460008]  __alloc_pages_nodemask+0x10a/0x2b0
+[   32.460794]  mt7601u_rx_tasklet+0x651/0x720
+[   32.461505]  tasklet_action_common.constprop.0+0x6b/0xd0
+[   32.462343]  __do_softirq+0x152/0x46c
+[   32.462928]  asm_call_irq_on_stack+0x12/0x20
+[   32.463610]  </IRQ>
+[   32.463953]  do_softirq_own_stack+0x5b/0x70
+[   32.464582]  irq_exit_rcu+0x9f/0xe0
+[   32.465028]  common_interrupt+0xae/0x1a0
+[   32.465536]  asm_common_interrupt+0x1e/0x40
+[   32.466071] RIP: 0010:default_idle+0x18/0x20
+[   32.468981] RSP: 0018:ffffc90000077f00 EFLAGS: 00000246
+[   32.469648] RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000000
+[   32.470550] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffff81aac3dd
+[   32.471463] RBP: ffff88810022ab00 R08: 0000000000000001 R09: 0000000000000001
+[   32.472335] R10: 0000000000000046 R11: 0000000000005aa0 R12: 0000000000000000
+[   32.473235] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
+[   32.474139]  ? default_idle_call+0x4d/0x200
+[   32.474681]  default_idle_call+0x74/0x200
+[   32.475192]  do_idle+0x1d5/0x250
+[   32.475612]  cpu_startup_entry+0x19/0x20
+[   32.476114]  secondary_startup_64_no_verify+0xb0/0xbb
+[   32.476765] Disabling lock debugging due to kernel taint
+
+Fixes: c869f77d6abb ("add mt7601u driver")
+Co-developed-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Acked-by: Jakub Kicinski <kubakici@wp.pl>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/62b2380c8c2091834cfad05e1059b55f945bd114.1610643952.git.lorenzo@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/mediatek/mt7601u/dma.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/mediatek/mt7601u/dma.c
++++ b/drivers/net/wireless/mediatek/mt7601u/dma.c
+@@ -160,8 +160,7 @@ mt7601u_rx_process_entry(struct mt7601u_
+       if (new_p) {
+               /* we have one extra ref from the allocator */
+-              __free_pages(e->p, MT_RX_ORDER);
+-
++              put_page(e->p);
+               e->p = new_p;
+       }
+ }
index a1ae0b91f12058dee6384d621def84065fb47d76..93dd3b02d718a117c28dbb9faa8e61597e8b0765 100644 (file)
@@ -8,3 +8,6 @@ drivers-soc-atmel-add-null-entry-at-the-end-of-at91_soc_allowed_list.patch
 kvm-x86-pmu-fix-hw_ref_cpu_cycles-event-pseudo-encoding-in-intel_arch_events.patch
 kvm-x86-get-smi-pending-status-correctly.patch
 xen-fix-xenstore-initialisation-for-xs_local.patch
+leds-trigger-fix-potential-deadlock-with-libata.patch
+mt7601u-fix-kernel-crash-unplugging-the-device.patch
+mt7601u-fix-rx-buffer-refcounting.patch