diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-09-06 10:16:35 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-09-06 10:16:35 +0200 |
commit | 1ac3c6b4f6ee9f94fc9d9ff1f9415aadbdf2593d (patch) | |
tree | 9fd1ae63e6c51f940ff2ff8693bffe18917a81f4 | |
parent | f7a9241155211c41fc84b293c8cd0a52c95b2108 (diff) | |
download | queue-3.18-1ac3c6b4f6ee9f94fc9d9ff1f9415aadbdf2593d.tar.gz |
more patches
9 files changed, 542 insertions, 0 deletions
diff --git a/mac80211-fix-possible-sta-leak.patch b/mac80211-fix-possible-sta-leak.patch new file mode 100644 index 0000000..abda968 --- /dev/null +++ b/mac80211-fix-possible-sta-leak.patch @@ -0,0 +1,47 @@ +From 5fd2f91ad483baffdbe798f8a08f1b41442d1e24 Mon Sep 17 00:00:00 2001 +From: Johannes Berg <johannes.berg@intel.com> +Date: Thu, 1 Aug 2019 09:30:33 +0200 +Subject: mac80211: fix possible sta leak + +From: Johannes Berg <johannes.berg@intel.com> + +commit 5fd2f91ad483baffdbe798f8a08f1b41442d1e24 upstream. + +If TDLS station addition is rejected, the sta memory is leaked. +Avoid this by moving the check before the allocation. + +Cc: stable@vger.kernel.org +Fixes: 7ed5285396c2 ("mac80211: don't initiate TDLS connection if station is not associated to AP") +Link: https://lore.kernel.org/r/20190801073033.7892-1-johannes@sipsolutions.net +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + net/mac80211/cfg.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1179,6 +1179,11 @@ static int ieee80211_add_station(struct + if (is_multicast_ether_addr(mac)) + return -EINVAL; + ++ if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER) && ++ sdata->vif.type == NL80211_IFTYPE_STATION && ++ !sdata->u.mgd.associated) ++ return -EINVAL; ++ + sta = sta_info_alloc(sdata, mac, GFP_KERNEL); + if (!sta) + return -ENOMEM; +@@ -1194,10 +1199,6 @@ static int ieee80211_add_station(struct + sta->sta.tdls = true; + } + +- if (sta->sta.tdls && sdata->vif.type == NL80211_IFTYPE_STATION && +- !sdata->u.mgd.associated) +- return -EINVAL; +- + err = sta_apply_parameters(local, sta, params); + if (err) { + sta_info_free(local, sta); diff --git a/mmc-core-fix-init-of-sd-cards-reporting-an-invalid-vdd-range.patch b/mmc-core-fix-init-of-sd-cards-reporting-an-invalid-vdd-range.patch new file mode 100644 index 0000000..a578f9b --- /dev/null +++ b/mmc-core-fix-init-of-sd-cards-reporting-an-invalid-vdd-range.patch @@ -0,0 +1,48 @@ +From 72741084d903e65e121c27bd29494d941729d4a1 Mon Sep 17 00:00:00 2001 +From: Ulf Hansson <ulf.hansson@linaro.org> +Date: Tue, 27 Aug 2019 10:10:43 +0200 +Subject: mmc: core: Fix init of SD cards reporting an invalid VDD range + +From: Ulf Hansson <ulf.hansson@linaro.org> + +commit 72741084d903e65e121c27bd29494d941729d4a1 upstream. + +The OCR register defines the supported range of VDD voltages for SD cards. +However, it has turned out that some SD cards reports an invalid voltage +range, for example having bit7 set. + +When a host supports MMC_CAP2_FULL_PWR_CYCLE and some of the voltages from +the invalid VDD range, this triggers the core to run a power cycle of the +card to try to initialize it at the lowest common supported voltage. +Obviously this fails, since the card can't support it. + +Let's fix this problem, by clearing invalid bits from the read OCR register +for SD cards, before proceeding with the VDD voltage negotiation. + +Cc: stable@vger.kernel.org +Reported-by: Philip Langdale <philipl@overt.org> +Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> +Reviewed-by: Philip Langdale <philipl@overt.org> +Tested-by: Philip Langdale <philipl@overt.org> +Tested-by: Manuel Presnitz <mail@mpy.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/mmc/core/sd.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/mmc/core/sd.c ++++ b/drivers/mmc/core/sd.c +@@ -1307,6 +1307,12 @@ int mmc_attach_sd(struct mmc_host *host) + goto err; + } + ++ /* ++ * Some SD cards claims an out of spec VDD voltage range. Let's treat ++ * these bits as being in-valid and especially also bit7. ++ */ ++ ocr &= ~0x7FFF; ++ + rocr = mmc_select_voltage(host, ocr); + + /* diff --git a/revert-cfg80211-fix-processing-world-regdomain-when-non-modular.patch b/revert-cfg80211-fix-processing-world-regdomain-when-non-modular.patch new file mode 100644 index 0000000..1bb0e3e --- /dev/null +++ b/revert-cfg80211-fix-processing-world-regdomain-when-non-modular.patch @@ -0,0 +1,63 @@ +From 0d31d4dbf38412f5b8b11b4511d07b840eebe8cb Mon Sep 17 00:00:00 2001 +From: "Hodaszi, Robert" <Robert.Hodaszi@digi.com> +Date: Fri, 14 Jun 2019 13:16:01 +0000 +Subject: Revert "cfg80211: fix processing world regdomain when non modular" + +From: Hodaszi, Robert <Robert.Hodaszi@digi.com> + +commit 0d31d4dbf38412f5b8b11b4511d07b840eebe8cb upstream. + +This reverts commit 96cce12ff6e0 ("cfg80211: fix processing world +regdomain when non modular"). + +Re-triggering a reg_process_hint with the last request on all events, +can make the regulatory domain fail in case of multiple WiFi modules. On +slower boards (espacially with mdev), enumeration of the WiFi modules +can end up in an intersected regulatory domain, and user cannot set it +with 'iw reg set' anymore. + +This is happening, because: +- 1st module enumerates, queues up a regulatory request +- request gets processed by __reg_process_hint_driver(): + - checks if previous was set by CORE -> yes + - checks if regulator domain changed -> yes, from '00' to e.g. 'US' + -> sends request to the 'crda' +- 2nd module enumerates, queues up a regulator request (which triggers + the reg_todo() work) +- reg_todo() -> reg_process_pending_hints() sees, that the last request + is not processed yet, so it tries to process it again. + __reg_process_hint driver() will run again, and: + - checks if the last request's initiator was the core -> no, it was + the driver (1st WiFi module) + - checks, if the previous initiator was the driver -> yes + - checks if the regulator domain changed -> yes, it was '00' (set by + core, and crda call did not return yet), and should be changed to 'US' + +------> __reg_process_hint_driver calls an intersect + +Besides, the reg_process_hint call with the last request is meaningless +since the crda call has a timeout work. If that timeout expires, the +first module's request will lost. + +Cc: stable@vger.kernel.org +Fixes: 96cce12ff6e0 ("cfg80211: fix processing world regdomain when non modular") +Signed-off-by: Robert Hodaszi <robert.hodaszi@digi.com> +Link: https://lore.kernel.org/r/20190614131600.GA13897@a1-hr +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + net/wireless/reg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -1953,7 +1953,7 @@ static void reg_process_pending_hints(vo + + /* When last_request->processed becomes true this will be rescheduled */ + if (lr && !lr->processed) { +- reg_process_hint(lr); ++ pr_debug("Pending regulatory request, waiting for it to be processed...\n"); + return; + } + @@ -7,3 +7,11 @@ alsa-usb-audio-fix-an-oob-bug-in-parse_audio_mixer_unit.patch alsa-seq-fix-potential-concurrent-access-to-the-deleted-pool.patch x86-apic-do-not-initialize-ldr-and-dfr-for-bigsmp.patch x86-apic-include-the-ldr-when-clearing-out-apic-registers.patch +usb-cdc-wdm-fix-race-between-write-and-disconnect-due-to-flag-abuse.patch +usb-host-ohci-fix-a-race-condition-between-shutdown-and-irq.patch +usb-storage-ums-realtek-update-module-parameter-description-for-auto_delink_en.patch +usb-storage-ums-realtek-whitelist-auto-delink-support.patch +mmc-core-fix-init-of-sd-cards-reporting-an-invalid-vdd-range.patch +vmci-release-resource-if-the-work-is-already-queued.patch +revert-cfg80211-fix-processing-world-regdomain-when-non-modular.patch +mac80211-fix-possible-sta-leak.patch diff --git a/usb-cdc-wdm-fix-race-between-write-and-disconnect-due-to-flag-abuse.patch b/usb-cdc-wdm-fix-race-between-write-and-disconnect-due-to-flag-abuse.patch new file mode 100644 index 0000000..be20c77 --- /dev/null +++ b/usb-cdc-wdm-fix-race-between-write-and-disconnect-due-to-flag-abuse.patch @@ -0,0 +1,64 @@ +From 1426bd2c9f7e3126e2678e7469dca9fd9fc6dd3e Mon Sep 17 00:00:00 2001 +From: Oliver Neukum <oneukum@suse.com> +Date: Tue, 27 Aug 2019 12:34:36 +0200 +Subject: USB: cdc-wdm: fix race between write and disconnect due to flag abuse + +From: Oliver Neukum <oneukum@suse.com> + +commit 1426bd2c9f7e3126e2678e7469dca9fd9fc6dd3e upstream. + +In case of a disconnect an ongoing flush() has to be made fail. +Nevertheless we cannot be sure that any pending URB has already +finished, so although they will never succeed, they still must +not be touched. +The clean solution for this is to check for WDM_IN_USE +and WDM_DISCONNECTED in flush(). There is no point in ever +clearing WDM_IN_USE, as no further writes make sense. + +The issue is as old as the driver. + +Fixes: afba937e540c9 ("USB: CDC WDM driver") +Reported-by: syzbot+d232cca6ec42c2edb3fc@syzkaller.appspotmail.com +Signed-off-by: Oliver Neukum <oneukum@suse.com> +Cc: stable <stable@vger.kernel.org> +Link: https://lore.kernel.org/r/20190827103436.21143-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/usb/class/cdc-wdm.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -576,10 +576,20 @@ static int wdm_flush(struct file *file, + { + struct wdm_device *desc = file->private_data; + +- wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags)); ++ wait_event(desc->wait, ++ /* ++ * needs both flags. We cannot do with one ++ * because resetting it would cause a race ++ * with write() yet we need to signal ++ * a disconnect ++ */ ++ !test_bit(WDM_IN_USE, &desc->flags) || ++ test_bit(WDM_DISCONNECTING, &desc->flags)); + + /* cannot dereference desc->intf if WDM_DISCONNECTING */ +- if (desc->werr < 0 && !test_bit(WDM_DISCONNECTING, &desc->flags)) ++ if (test_bit(WDM_DISCONNECTING, &desc->flags)) ++ return -ENODEV; ++ if (desc->werr < 0) + dev_err(&desc->intf->dev, "Error in flush path: %d\n", + desc->werr); + +@@ -969,8 +979,6 @@ static void wdm_disconnect(struct usb_in + spin_lock_irqsave(&desc->iuspin, flags); + set_bit(WDM_DISCONNECTING, &desc->flags); + set_bit(WDM_READ, &desc->flags); +- /* to terminate pending flushes */ +- clear_bit(WDM_IN_USE, &desc->flags); + spin_unlock_irqrestore(&desc->iuspin, flags); + wake_up_all(&desc->wait); + mutex_lock(&desc->rlock); diff --git a/usb-host-ohci-fix-a-race-condition-between-shutdown-and-irq.patch b/usb-host-ohci-fix-a-race-condition-between-shutdown-and-irq.patch new file mode 100644 index 0000000..643a4ed --- /dev/null +++ b/usb-host-ohci-fix-a-race-condition-between-shutdown-and-irq.patch @@ -0,0 +1,134 @@ +From a349b95d7ca0cea71be4a7dac29830703de7eb62 Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 27 Aug 2019 12:51:50 +0900 +Subject: usb: host: ohci: fix a race condition between shutdown and irq + +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> + +commit a349b95d7ca0cea71be4a7dac29830703de7eb62 upstream. + +This patch fixes an issue that the following error is +possible to happen when ohci hardware causes an interruption +and the system is shutting down at the same time. + +[ 34.851754] usb 2-1: USB disconnect, device number 2 +[ 35.166658] irq 156: nobody cared (try booting with the "irqpoll" option) +[ 35.173445] CPU: 0 PID: 22 Comm: kworker/0:1 Not tainted 5.3.0-rc5 #85 +[ 35.179964] Hardware name: Renesas Salvator-X 2nd version board based on r8a77965 (DT) +[ 35.187886] Workqueue: usb_hub_wq hub_event +[ 35.192063] Call trace: +[ 35.194509] dump_backtrace+0x0/0x150 +[ 35.198165] show_stack+0x14/0x20 +[ 35.201475] dump_stack+0xa0/0xc4 +[ 35.204785] __report_bad_irq+0x34/0xe8 +[ 35.208614] note_interrupt+0x2cc/0x318 +[ 35.212446] handle_irq_event_percpu+0x5c/0x88 +[ 35.216883] handle_irq_event+0x48/0x78 +[ 35.220712] handle_fasteoi_irq+0xb4/0x188 +[ 35.224802] generic_handle_irq+0x24/0x38 +[ 35.228804] __handle_domain_irq+0x5c/0xb0 +[ 35.232893] gic_handle_irq+0x58/0xa8 +[ 35.236548] el1_irq+0xb8/0x180 +[ 35.239681] __do_softirq+0x94/0x23c +[ 35.243253] irq_exit+0xd0/0xd8 +[ 35.246387] __handle_domain_irq+0x60/0xb0 +[ 35.250475] gic_handle_irq+0x58/0xa8 +[ 35.254130] el1_irq+0xb8/0x180 +[ 35.257268] kernfs_find_ns+0x5c/0x120 +[ 35.261010] kernfs_find_and_get_ns+0x3c/0x60 +[ 35.265361] sysfs_unmerge_group+0x20/0x68 +[ 35.269454] dpm_sysfs_remove+0x2c/0x68 +[ 35.273284] device_del+0x80/0x370 +[ 35.276683] hid_destroy_device+0x28/0x60 +[ 35.280686] usbhid_disconnect+0x4c/0x80 +[ 35.284602] usb_unbind_interface+0x6c/0x268 +[ 35.288867] device_release_driver_internal+0xe4/0x1b0 +[ 35.293998] device_release_driver+0x14/0x20 +[ 35.298261] bus_remove_device+0x110/0x128 +[ 35.302350] device_del+0x148/0x370 +[ 35.305832] usb_disable_device+0x8c/0x1d0 +[ 35.309921] usb_disconnect+0xc8/0x2d0 +[ 35.313663] hub_event+0x6e0/0x1128 +[ 35.317146] process_one_work+0x1e0/0x320 +[ 35.321148] worker_thread+0x40/0x450 +[ 35.324805] kthread+0x124/0x128 +[ 35.328027] ret_from_fork+0x10/0x18 +[ 35.331594] handlers: +[ 35.333862] [<0000000079300c1d>] usb_hcd_irq +[ 35.338126] [<0000000079300c1d>] usb_hcd_irq +[ 35.342389] Disabling IRQ #156 + +ohci_shutdown() disables all the interrupt and rh_state is set to +OHCI_RH_HALTED. In other hand, ohci_irq() is possible to enable +OHCI_INTR_SF and OHCI_INTR_MIE on ohci_irq(). Note that OHCI_INTR_SF +is possible to be set by start_ed_unlink() which is called: + ohci_irq() + -> process_done_list() + -> takeback_td() + -> start_ed_unlink() + +So, ohci_irq() has the following condition, the issue happens by +&ohci->regs->intrenable = OHCI_INTR_MIE | OHCI_INTR_SF and +ohci->rh_state = OHCI_RH_HALTED: + + /* interrupt for some other device? */ + if (ints == 0 || unlikely(ohci->rh_state == OHCI_RH_HALTED)) + return IRQ_NOTMINE; + +To fix the issue, ohci_shutdown() holds the spin lock while disabling +the interruption and changing the rh_state flag to prevent reenable +the OHCI_INTR_MIE unexpectedly. Note that io_watchdog_func() also +calls the ohci_shutdown() and it already held the spin lock, so that +the patch makes a new function as _ohci_shutdown(). + +This patch is inspired by a Renesas R-Car Gen3 BSP patch +from Tho Vu. + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Cc: stable <stable@vger.kernel.org> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Link: https://lore.kernel.org/r/1566877910-6020-1-git-send-email-yoshihiro.shimoda.uh@renesas.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/usb/host/ohci-hcd.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +--- a/drivers/usb/host/ohci-hcd.c ++++ b/drivers/usb/host/ohci-hcd.c +@@ -414,8 +414,7 @@ static void ohci_usb_reset (struct ohci_ + * other cases where the next software may expect clean state from the + * "firmware". this is bus-neutral, unlike shutdown() methods. + */ +-static void +-ohci_shutdown (struct usb_hcd *hcd) ++static void _ohci_shutdown(struct usb_hcd *hcd) + { + struct ohci_hcd *ohci; + +@@ -431,6 +430,16 @@ ohci_shutdown (struct usb_hcd *hcd) + ohci->rh_state = OHCI_RH_HALTED; + } + ++static void ohci_shutdown(struct usb_hcd *hcd) ++{ ++ struct ohci_hcd *ohci = hcd_to_ohci(hcd); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ohci->lock, flags); ++ _ohci_shutdown(hcd); ++ spin_unlock_irqrestore(&ohci->lock, flags); ++} ++ + /*-------------------------------------------------------------------------* + * HC functions + *-------------------------------------------------------------------------*/ +@@ -749,7 +758,7 @@ static void io_watchdog_func(unsigned lo + died: + usb_hc_died(ohci_to_hcd(ohci)); + ohci_dump(ohci); +- ohci_shutdown(ohci_to_hcd(ohci)); ++ _ohci_shutdown(ohci_to_hcd(ohci)); + goto done; + } else { + /* No write back because the done queue was empty */ diff --git a/usb-storage-ums-realtek-update-module-parameter-description-for-auto_delink_en.patch b/usb-storage-ums-realtek-update-module-parameter-description-for-auto_delink_en.patch new file mode 100644 index 0000000..378e308 --- /dev/null +++ b/usb-storage-ums-realtek-update-module-parameter-description-for-auto_delink_en.patch @@ -0,0 +1,35 @@ +From f6445b6b2f2bb1745080af4a0926049e8bca2617 Mon Sep 17 00:00:00 2001 +From: Kai-Heng Feng <kai.heng.feng@canonical.com> +Date: Wed, 28 Aug 2019 01:34:49 +0800 +Subject: USB: storage: ums-realtek: Update module parameter description for auto_delink_en + +From: Kai-Heng Feng <kai.heng.feng@canonical.com> + +commit f6445b6b2f2bb1745080af4a0926049e8bca2617 upstream. + +The option named "auto_delink_en" is a bit misleading, as setting it to +false doesn't really disable auto-delink but let auto-delink be firmware +controlled. + +Update the description to reflect the real usage of this parameter. + +Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> +Cc: stable <stable@vger.kernel.org> +Link: https://lore.kernel.org/r/20190827173450.13572-1-kai.heng.feng@canonical.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/usb/storage/realtek_cr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/storage/realtek_cr.c ++++ b/drivers/usb/storage/realtek_cr.c +@@ -47,7 +47,7 @@ MODULE_VERSION("1.03"); + + static int auto_delink_en = 1; + module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); +-MODULE_PARM_DESC(auto_delink_en, "enable auto delink"); ++MODULE_PARM_DESC(auto_delink_en, "auto delink mode (0=firmware, 1=software [default])"); + + #ifdef CONFIG_REALTEK_AUTOPM + static int ss_en = 1; diff --git a/usb-storage-ums-realtek-whitelist-auto-delink-support.patch b/usb-storage-ums-realtek-whitelist-auto-delink-support.patch new file mode 100644 index 0000000..12641f8 --- /dev/null +++ b/usb-storage-ums-realtek-whitelist-auto-delink-support.patch @@ -0,0 +1,52 @@ +From 1902a01e2bcc3abd7c9a18dc05e78c7ab4a53c54 Mon Sep 17 00:00:00 2001 +From: Kai-Heng Feng <kai.heng.feng@canonical.com> +Date: Wed, 28 Aug 2019 01:34:50 +0800 +Subject: USB: storage: ums-realtek: Whitelist auto-delink support + +From: Kai-Heng Feng <kai.heng.feng@canonical.com> + +commit 1902a01e2bcc3abd7c9a18dc05e78c7ab4a53c54 upstream. + +Auto-delink requires writing special registers to ums-realtek devices. +Unconditionally enable auto-delink may break newer devices. + +So only enable auto-delink by default for the original three IDs, +0x0138, 0x0158 and 0x0159. + +Realtek is working on a patch to properly support auto-delink for other +IDs. + +BugLink: https://bugs.launchpad.net/bugs/1838886 +Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Cc: stable <stable@vger.kernel.org> +Link: https://lore.kernel.org/r/20190827173450.13572-2-kai.heng.feng@canonical.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/usb/storage/realtek_cr.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/drivers/usb/storage/realtek_cr.c ++++ b/drivers/usb/storage/realtek_cr.c +@@ -1003,12 +1003,15 @@ static int init_realtek_cr(struct us_dat + goto INIT_FAIL; + } + +- if (CHECK_FW_VER(chip, 0x5888) || CHECK_FW_VER(chip, 0x5889) || +- CHECK_FW_VER(chip, 0x5901)) +- SET_AUTO_DELINK(chip); +- if (STATUS_LEN(chip) == 16) { +- if (SUPPORT_AUTO_DELINK(chip)) ++ if (CHECK_PID(chip, 0x0138) || CHECK_PID(chip, 0x0158) || ++ CHECK_PID(chip, 0x0159)) { ++ if (CHECK_FW_VER(chip, 0x5888) || CHECK_FW_VER(chip, 0x5889) || ++ CHECK_FW_VER(chip, 0x5901)) + SET_AUTO_DELINK(chip); ++ if (STATUS_LEN(chip) == 16) { ++ if (SUPPORT_AUTO_DELINK(chip)) ++ SET_AUTO_DELINK(chip); ++ } + } + #ifdef CONFIG_REALTEK_AUTOPM + if (ss_en) diff --git a/vmci-release-resource-if-the-work-is-already-queued.patch b/vmci-release-resource-if-the-work-is-already-queued.patch new file mode 100644 index 0000000..108b4ae --- /dev/null +++ b/vmci-release-resource-if-the-work-is-already-queued.patch @@ -0,0 +1,91 @@ +From ba03a9bbd17b149c373c0ea44017f35fc2cd0f28 Mon Sep 17 00:00:00 2001 +From: Nadav Amit <namit@vmware.com> +Date: Tue, 20 Aug 2019 13:26:38 -0700 +Subject: VMCI: Release resource if the work is already queued + +From: Nadav Amit <namit@vmware.com> + +commit ba03a9bbd17b149c373c0ea44017f35fc2cd0f28 upstream. + +Francois reported that VMware balloon gets stuck after a balloon reset, +when the VMCI doorbell is removed. A similar error can occur when the +balloon driver is removed with the following splat: + +[ 1088.622000] INFO: task modprobe:3565 blocked for more than 120 seconds. +[ 1088.622035] Tainted: G W 5.2.0 #4 +[ 1088.622087] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +[ 1088.622205] modprobe D 0 3565 1450 0x00000000 +[ 1088.622210] Call Trace: +[ 1088.622246] __schedule+0x2a8/0x690 +[ 1088.622248] schedule+0x2d/0x90 +[ 1088.622250] schedule_timeout+0x1d3/0x2f0 +[ 1088.622252] wait_for_completion+0xba/0x140 +[ 1088.622320] ? wake_up_q+0x80/0x80 +[ 1088.622370] vmci_resource_remove+0xb9/0xc0 [vmw_vmci] +[ 1088.622373] vmci_doorbell_destroy+0x9e/0xd0 [vmw_vmci] +[ 1088.622379] vmballoon_vmci_cleanup+0x6e/0xf0 [vmw_balloon] +[ 1088.622381] vmballoon_exit+0x18/0xcc8 [vmw_balloon] +[ 1088.622394] __x64_sys_delete_module+0x146/0x280 +[ 1088.622408] do_syscall_64+0x5a/0x130 +[ 1088.622410] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[ 1088.622415] RIP: 0033:0x7f54f62791b7 +[ 1088.622421] Code: Bad RIP value. +[ 1088.622421] RSP: 002b:00007fff2a949008 EFLAGS: 00000206 ORIG_RAX: 00000000000000b0 +[ 1088.622426] RAX: ffffffffffffffda RBX: 000055dff8b55d00 RCX: 00007f54f62791b7 +[ 1088.622426] RDX: 0000000000000000 RSI: 0000000000000800 RDI: 000055dff8b55d68 +[ 1088.622427] RBP: 000055dff8b55d00 R08: 00007fff2a947fb1 R09: 0000000000000000 +[ 1088.622427] R10: 00007f54f62f5cc0 R11: 0000000000000206 R12: 000055dff8b55d68 +[ 1088.622428] R13: 0000000000000001 R14: 000055dff8b55d68 R15: 00007fff2a94a3f0 + +The cause for the bug is that when the "delayed" doorbell is invoked, it +takes a reference on the doorbell entry and schedules work that is +supposed to run the appropriate code and drop the doorbell entry +reference. The code ignores the fact that if the work is already queued, +it will not be scheduled to run one more time. As a result one of the +references would not be dropped. When the code waits for the reference +to get to zero, during balloon reset or module removal, it gets stuck. + +Fix it. Drop the reference if schedule_work() indicates that the work is +already queued. + +Note that this bug got more apparent (or apparent at all) due to +commit ce664331b248 ("vmw_balloon: VMCI_DOORBELL_SET does not check status"). + +Fixes: 83e2ec765be03 ("VMCI: doorbell implementation.") +Reported-by: Francois Rigault <rigault.francois@gmail.com> +Cc: Jorgen Hansen <jhansen@vmware.com> +Cc: Adit Ranadive <aditr@vmware.com> +Cc: Alexios Zavras <alexios.zavras@intel.com> +Cc: Vishnu DASA <vdasa@vmware.com> +Cc: stable@vger.kernel.org +Signed-off-by: Nadav Amit <namit@vmware.com> +Reviewed-by: Vishnu Dasa <vdasa@vmware.com> +Link: https://lore.kernel.org/r/20190820202638.49003-1-namit@vmware.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/misc/vmw_vmci/vmci_doorbell.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/misc/vmw_vmci/vmci_doorbell.c ++++ b/drivers/misc/vmw_vmci/vmci_doorbell.c +@@ -318,7 +318,8 @@ int vmci_dbell_host_context_notify(u32 s + + entry = container_of(resource, struct dbell_entry, resource); + if (entry->run_delayed) { +- schedule_work(&entry->work); ++ if (!schedule_work(&entry->work)) ++ vmci_resource_put(resource); + } else { + entry->notify_cb(entry->client_data); + vmci_resource_put(resource); +@@ -366,7 +367,8 @@ static void dbell_fire_entries(u32 notif + atomic_read(&dbell->active) == 1) { + if (dbell->run_delayed) { + vmci_resource_get(&dbell->resource); +- schedule_work(&dbell->work); ++ if (!schedule_work(&dbell->work)) ++ vmci_resource_put(&dbell->resource); + } else { + dbell->notify_cb(dbell->client_data); + } |