From: Greg Kroah-Hartman Date: Mon, 1 Feb 2021 14:23:01 +0000 (+0100) Subject: 4.14-stable patches X-Git-Tag: v4.4.255~33 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=eae3e30ee467db69d1e18a75480512882b5a61eb;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: leds-trigger-fix-potential-deadlock-with-libata.patch mt7601u-fix-kernel-crash-unplugging-the-device.patch mt7601u-fix-rx-buffer-refcounting.patch --- 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 index 00000000000..514e9aaa5c4 --- /dev/null +++ b/queue-4.14/leds-trigger-fix-potential-deadlock-with-libata.patch @@ -0,0 +1,270 @@ +From 27af8e2c90fba242460b01fa020e6e19ed68c495 Mon Sep 17 00:00:00 2001 +From: Andrea Righi +Date: Wed, 25 Nov 2020 16:18:22 +0100 +Subject: leds: trigger: fix potential deadlock with libata + +From: Andrea Righi + +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); + + 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: [] __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: [] __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 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); + + 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 + + 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 +Signed-off-by: Pavel Machek +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..ea5a4ce670c --- /dev/null +++ b/queue-4.14/mt7601u-fix-kernel-crash-unplugging-the-device.patch @@ -0,0 +1,78 @@ +From 0acb20a5438c36e0cf2b8bf255f314b59fcca6ef Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Sun, 17 Jan 2021 22:46:01 +0100 +Subject: mt7601u: fix kernel crash unplugging the device + +From: Lorenzo Bianconi + +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 +Acked-by: Jakub Kicinski +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/3b85219f669a63a8ced1f43686de05915a580489.1610919247.git.lorenzo@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a9a2cb5c0fc --- /dev/null +++ b/queue-4.14/mt7601u-fix-rx-buffer-refcounting.patch @@ -0,0 +1,74 @@ +From d24c790577ef01bfa01da2b131313a38c843a634 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 14 Jan 2021 18:10:52 +0100 +Subject: mt7601u: fix rx buffer refcounting + +From: Lorenzo Bianconi + +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] +[ 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] +[ 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 +Signed-off-by: Felix Fietkau +Signed-off-by: Lorenzo Bianconi +Acked-by: Jakub Kicinski +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/62b2380c8c2091834cfad05e1059b55f945bd114.1610643952.git.lorenzo@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } + } diff --git a/queue-4.14/series b/queue-4.14/series index a1ae0b91f12..93dd3b02d71 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -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