]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.19
authorSasha Levin <sashal@kernel.org>
Sun, 24 May 2020 13:51:25 +0000 (09:51 -0400)
committerSasha Levin <sashal@kernel.org>
Sun, 24 May 2020 14:15:27 +0000 (10:15 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
18 files changed:
queue-4.19/brcmfmac-abort-and-release-host-after-error.patch [new file with mode: 0644]
queue-4.19/cxgb4-cxgb4vf-fix-mac_hlist-initialization-and-free.patch [new file with mode: 0644]
queue-4.19/cxgb4-free-mac_hlist-properly.patch [new file with mode: 0644]
queue-4.19/edac-ghes-fix-locking-and-memory-barrier-issues.patch [new file with mode: 0644]
queue-4.19/edac-ghes-use-cper-module-handles-to-locate-dimms.patch [new file with mode: 0644]
queue-4.19/libnvdimm-btt-fix-lba-masking-during-free-list-popul.patch [new file with mode: 0644]
queue-4.19/libnvdimm-btt-remove-unnecessary-code-in-btt_freelis.patch [new file with mode: 0644]
queue-4.19/media-fdp1-fix-r-car-m3-n-naming-in-debug-message.patch [new file with mode: 0644]
queue-4.19/net-bcmgenet-abort-suspend-on-error.patch [new file with mode: 0644]
queue-4.19/net-bcmgenet-code-movement.patch [new file with mode: 0644]
queue-4.19/nfit-add-hyper-v-nvdimm-dsm-command-set-to-white-lis.patch [new file with mode: 0644]
queue-4.19/ppp-mppe-revert-ppp-mppe-add-softdep-to-arc4.patch [new file with mode: 0644]
queue-4.19/revert-gfs2-don-t-demote-a-glock-until-its-revokes-a.patch [new file with mode: 0644]
queue-4.19/revert-net-ibmvnic-fix-eoi-when-running-in-xive-mode.patch [new file with mode: 0644]
queue-4.19/series
queue-4.19/staging-most-core-replace-strcpy-by-strscpy.patch [new file with mode: 0644]
queue-4.19/thunderbolt-drop-duplicated-get_switch_at_route.patch [new file with mode: 0644]
queue-4.19/tty-serial-qcom_geni_serial-fix-wrap-around-of-tx-bu.patch [new file with mode: 0644]

diff --git a/queue-4.19/brcmfmac-abort-and-release-host-after-error.patch b/queue-4.19/brcmfmac-abort-and-release-host-after-error.patch
new file mode 100644 (file)
index 0000000..189ab5d
--- /dev/null
@@ -0,0 +1,57 @@
+From f20547486d3dff0d1905f4778d049e6f96580618 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jan 2020 14:14:57 -0800
+Subject: brcmfmac: abort and release host after error
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 863844ee3bd38219c88e82966d1df36a77716f3e ]
+
+With commit 216b44000ada ("brcmfmac: Fix use after free in
+brcmf_sdio_readframes()") applied, we see locking timeouts in
+brcmf_sdio_watchdog_thread().
+
+brcmfmac: brcmf_escan_timeout: timer expired
+INFO: task brcmf_wdog/mmc1:621 blocked for more than 120 seconds.
+Not tainted 4.19.94-07984-g24ff99a0f713 #1
+"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+brcmf_wdog/mmc1 D    0   621      2 0x00000000 last_sleep: 2440793077.  last_runnable: 2440766827
+[<c0aa1e60>] (__schedule) from [<c0aa2100>] (schedule+0x98/0xc4)
+[<c0aa2100>] (schedule) from [<c0853830>] (__mmc_claim_host+0x154/0x274)
+[<c0853830>] (__mmc_claim_host) from [<bf10c5b8>] (brcmf_sdio_watchdog_thread+0x1b0/0x1f8 [brcmfmac])
+[<bf10c5b8>] (brcmf_sdio_watchdog_thread [brcmfmac]) from [<c02570b8>] (kthread+0x178/0x180)
+
+In addition to restarting or exiting the loop, it is also necessary to
+abort the command and to release the host.
+
+Fixes: 216b44000ada ("brcmfmac: Fix use after free in brcmf_sdio_readframes()")
+Cc: Dan Carpenter <dan.carpenter@oracle.com>
+Cc: Matthias Kaehlcke <mka@chromium.org>
+Cc: Brian Norris <briannorris@chromium.org>
+Cc: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Acked-by: franky.lin@broadcom.com
+Acked-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+index e0211321fe9e..96870d1b3b73 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -1933,6 +1933,8 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
+                       if (brcmf_sdio_hdparse(bus, bus->rxhdr, &rd_new,
+                                              BRCMF_SDIO_FT_NORMAL)) {
+                               rd->len = 0;
++                              brcmf_sdio_rxfail(bus, true, true);
++                              sdio_release_host(bus->sdiodev->func1);
+                               brcmu_pkt_buf_free_skb(pkt);
+                               continue;
+                       }
+-- 
+2.25.1
+
diff --git a/queue-4.19/cxgb4-cxgb4vf-fix-mac_hlist-initialization-and-free.patch b/queue-4.19/cxgb4-cxgb4vf-fix-mac_hlist-initialization-and-free.patch
new file mode 100644 (file)
index 0000000..3c128eb
--- /dev/null
@@ -0,0 +1,116 @@
+From e212d6737da4d99294953d11f69e7decc2559da6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Nov 2018 12:11:39 +0530
+Subject: cxgb4/cxgb4vf: Fix mac_hlist initialization and free
+
+From: Arjun Vynipadath <arjun@chelsio.com>
+
+[ Upstream commit b539ea60f5043b9acd7562f04fa2117f18776cbb ]
+
+Null pointer dereference seen when cxgb4vf driver is unloaded
+without bringing up any interfaces, moving mac_hlist initialization
+to driver probe and free the mac_hlist in remove to fix the issue.
+
+Fixes: 24357e06ba51 ("cxgb4vf: fix memleak in mac_hlist initialization")
+Signed-off-by: Arjun Vynipadath <arjun@chelsio.com>
+Signed-off-by: Casey Leedom <leedom@chelsio.com>
+Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/chelsio/cxgb4/cxgb4_main.c   | 19 ++++++++++---------
+ .../ethernet/chelsio/cxgb4vf/cxgb4vf_main.c   |  6 +++---
+ 2 files changed, 13 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+index c334b6206871..9d1d77125826 100644
+--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+@@ -2281,8 +2281,6 @@ static int cxgb_up(struct adapter *adap)
+ #if IS_ENABLED(CONFIG_IPV6)
+       update_clip(adap);
+ #endif
+-      /* Initialize hash mac addr list*/
+-      INIT_LIST_HEAD(&adap->mac_hlist);
+       return err;
+  irq_err:
+@@ -2296,8 +2294,6 @@ static int cxgb_up(struct adapter *adap)
+ static void cxgb_down(struct adapter *adapter)
+ {
+-      struct hash_mac_addr *entry, *tmp;
+-
+       cancel_work_sync(&adapter->tid_release_task);
+       cancel_work_sync(&adapter->db_full_task);
+       cancel_work_sync(&adapter->db_drop_task);
+@@ -2307,11 +2303,6 @@ static void cxgb_down(struct adapter *adapter)
+       t4_sge_stop(adapter);
+       t4_free_sge_resources(adapter);
+-      list_for_each_entry_safe(entry, tmp, &adapter->mac_hlist, list) {
+-              list_del(&entry->list);
+-              kfree(entry);
+-      }
+-
+       adapter->flags &= ~FULL_INIT_DONE;
+ }
+@@ -5610,6 +5601,9 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+                            (is_t5(adapter->params.chip) ? STATMODE_V(0) :
+                             T6_STATMODE_V(0)));
++      /* Initialize hash mac addr list */
++      INIT_LIST_HEAD(&adapter->mac_hlist);
++
+       for_each_port(adapter, i) {
+               netdev = alloc_etherdev_mq(sizeof(struct port_info),
+                                          MAX_ETH_QSETS);
+@@ -5884,6 +5878,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ static void remove_one(struct pci_dev *pdev)
+ {
+       struct adapter *adapter = pci_get_drvdata(pdev);
++      struct hash_mac_addr *entry, *tmp;
+       if (!adapter) {
+               pci_release_regions(pdev);
+@@ -5931,6 +5926,12 @@ static void remove_one(struct pci_dev *pdev)
+               if (adapter->num_uld || adapter->num_ofld_uld)
+                       t4_uld_mem_free(adapter);
+               free_some_resources(adapter);
++              list_for_each_entry_safe(entry, tmp, &adapter->mac_hlist,
++                                       list) {
++                      list_del(&entry->list);
++                      kfree(entry);
++              }
++
+ #if IS_ENABLED(CONFIG_IPV6)
+               t4_cleanup_clip_tbl(adapter);
+ #endif
+diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+index 972dc7bd721d..15029a5e62b9 100644
+--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
++++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+@@ -723,9 +723,6 @@ static int adapter_up(struct adapter *adapter)
+               if (adapter->flags & USING_MSIX)
+                       name_msix_vecs(adapter);
+-              /* Initialize hash mac addr list*/
+-              INIT_LIST_HEAD(&adapter->mac_hlist);
+-
+               adapter->flags |= FULL_INIT_DONE;
+       }
+@@ -3038,6 +3035,9 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
+       if (err)
+               goto err_unmap_bar;
++      /* Initialize hash mac addr list */
++      INIT_LIST_HEAD(&adapter->mac_hlist);
++
+       /*
+        * Allocate our "adapter ports" and stitch everything together.
+        */
+-- 
+2.25.1
+
diff --git a/queue-4.19/cxgb4-free-mac_hlist-properly.patch b/queue-4.19/cxgb4-free-mac_hlist-properly.patch
new file mode 100644 (file)
index 0000000..2258e9d
--- /dev/null
@@ -0,0 +1,49 @@
+From 6535fe7b7166cb98416265bbba8b7acea148aadd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Nov 2018 14:50:25 +0530
+Subject: cxgb4: free mac_hlist properly
+
+From: Arjun Vynipadath <arjun@chelsio.com>
+
+[ Upstream commit 2a8d84bf513823ba398f4b2dec41b8decf4041af ]
+
+The locally maintained list for tracking hash mac table was
+not freed during driver remove.
+
+Signed-off-by: Arjun Vynipadath <arjun@chelsio.com>
+Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+index c81d6c330548..c334b6206871 100644
+--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+@@ -2296,6 +2296,8 @@ static int cxgb_up(struct adapter *adap)
+ static void cxgb_down(struct adapter *adapter)
+ {
++      struct hash_mac_addr *entry, *tmp;
++
+       cancel_work_sync(&adapter->tid_release_task);
+       cancel_work_sync(&adapter->db_full_task);
+       cancel_work_sync(&adapter->db_drop_task);
+@@ -2304,6 +2306,12 @@ static void cxgb_down(struct adapter *adapter)
+       t4_sge_stop(adapter);
+       t4_free_sge_resources(adapter);
++
++      list_for_each_entry_safe(entry, tmp, &adapter->mac_hlist, list) {
++              list_del(&entry->list);
++              kfree(entry);
++      }
++
+       adapter->flags &= ~FULL_INIT_DONE;
+ }
+-- 
+2.25.1
+
diff --git a/queue-4.19/edac-ghes-fix-locking-and-memory-barrier-issues.patch b/queue-4.19/edac-ghes-fix-locking-and-memory-barrier-issues.patch
new file mode 100644 (file)
index 0000000..b6db092
--- /dev/null
@@ -0,0 +1,265 @@
+From d3ff24263fd0320ccf2a5292cfe8c8a8343813e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2019 20:07:51 +0000
+Subject: EDAC/ghes: Fix locking and memory barrier issues
+
+From: Robert Richter <rrichter@marvell.com>
+
+[ Upstream commit 23f61b9fc5cc10d87f66e50518707eec2a0fbda1 ]
+
+The ghes registration and refcount is broken in several ways:
+
+ * ghes_edac_register() returns with success for a 2nd instance
+   even if a first instance's registration is still running. This is
+   not correct as the first instance may fail later. A subsequent
+   registration may not finish before the first. Parallel registrations
+   must be avoided.
+
+ * The refcount was increased even if a registration failed. This
+   leads to stale counters preventing the device from being released.
+
+ * The ghes refcount may not be decremented properly on unregistration.
+   Always decrement the refcount once ghes_edac_unregister() is called to
+   keep the refcount sane.
+
+ * The ghes_pvt pointer is handed to the irq handler before registration
+   finished.
+
+ * The mci structure could be freed while the irq handler is running.
+
+Fix this by adding a mutex to ghes_edac_register(). This mutex
+serializes instances to register and unregister. The refcount is only
+increased if the registration succeeded. This makes sure the refcount is
+in a consistent state after registering or unregistering a device.
+
+Note: A spinlock cannot be used here as the code section may sleep.
+
+The ghes_pvt is protected by ghes_lock now. This ensures the pointer is
+not updated before registration was finished or while the irq handler is
+running. It is unset before unregistering the device including necessary
+(implicit) memory barriers making the changes visible to other CPUs.
+Thus, the device can not be used anymore by an interrupt.
+
+Also, rename ghes_init to ghes_refcount for better readability and
+switch to refcount API.
+
+A refcount is needed because there can be multiple GHES structures being
+defined (see ACPI 6.3 specification, 18.3.2.7 Generic Hardware Error
+Source, "Some platforms may describe multiple Generic Hardware Error
+Source structures with different notification types, ...").
+
+Another approach to use the mci's device refcount (get_device()) and
+have a release function does not work here. A release function will be
+called only for device_release() with the last put_device() call. The
+device must be deleted *before* that with device_del(). This is only
+possible by maintaining an own refcount.
+
+ [ bp: touchups. ]
+
+Fixes: 0fe5f281f749 ("EDAC, ghes: Model a single, logical memory controller")
+Fixes: 1e72e673b9d1 ("EDAC/ghes: Fix Use after free in ghes_edac remove path")
+Co-developed-by: James Morse <james.morse@arm.com>
+Signed-off-by: James Morse <james.morse@arm.com>
+Co-developed-by: Borislav Petkov <bp@suse.de>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Signed-off-by: Robert Richter <rrichter@marvell.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: "linux-edac@vger.kernel.org" <linux-edac@vger.kernel.org>
+Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
+Cc: Tony Luck <tony.luck@intel.com>
+Link: https://lkml.kernel.org/r/20191105200732.3053-1-rrichter@marvell.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/ghes_edac.c | 90 +++++++++++++++++++++++++++++-----------
+ 1 file changed, 66 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c
+index 02a7134ad75b..209b5cc32bd2 100644
+--- a/drivers/edac/ghes_edac.c
++++ b/drivers/edac/ghes_edac.c
+@@ -28,9 +28,18 @@ struct ghes_edac_pvt {
+       char msg[80];
+ };
+-static atomic_t ghes_init = ATOMIC_INIT(0);
++static refcount_t ghes_refcount = REFCOUNT_INIT(0);
++
++/*
++ * Access to ghes_pvt must be protected by ghes_lock. The spinlock
++ * also provides the necessary (implicit) memory barrier for the SMP
++ * case to make the pointer visible on another CPU.
++ */
+ static struct ghes_edac_pvt *ghes_pvt;
++/* GHES registration mutex */
++static DEFINE_MUTEX(ghes_reg_mutex);
++
+ /*
+  * Sync with other, potentially concurrent callers of
+  * ghes_edac_report_mem_error(). We don't know what the
+@@ -81,9 +90,8 @@ static void ghes_edac_count_dimms(const struct dmi_header *dh, void *arg)
+               (*num_dimm)++;
+ }
+-static int get_dimm_smbios_index(u16 handle)
++static int get_dimm_smbios_index(struct mem_ctl_info *mci, u16 handle)
+ {
+-      struct mem_ctl_info *mci = ghes_pvt->mci;
+       int i;
+       for (i = 0; i < mci->tot_dimms; i++) {
+@@ -200,14 +208,11 @@ void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
+       enum hw_event_mc_err_type type;
+       struct edac_raw_error_desc *e;
+       struct mem_ctl_info *mci;
+-      struct ghes_edac_pvt *pvt = ghes_pvt;
++      struct ghes_edac_pvt *pvt;
+       unsigned long flags;
+       char *p;
+       u8 grain_bits;
+-      if (!pvt)
+-              return;
+-
+       /*
+        * We can do the locking below because GHES defers error processing
+        * from NMI to IRQ context. Whenever that changes, we'd at least
+@@ -218,6 +223,10 @@ void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
+       spin_lock_irqsave(&ghes_lock, flags);
++      pvt = ghes_pvt;
++      if (!pvt)
++              goto unlock;
++
+       mci = pvt->mci;
+       e = &mci->error_desc;
+@@ -351,7 +360,7 @@ void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
+                       p += sprintf(p, "DIMM DMI handle: 0x%.4x ",
+                                    mem_err->mem_dev_handle);
+-              index = get_dimm_smbios_index(mem_err->mem_dev_handle);
++              index = get_dimm_smbios_index(mci, mem_err->mem_dev_handle);
+               if (index >= 0) {
+                       e->top_layer = index;
+                       e->enable_per_layer_report = true;
+@@ -451,6 +460,8 @@ void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
+                      grain_bits, e->syndrome, pvt->detail_location);
+       edac_raw_mc_handle_error(type, mci, e);
++
++unlock:
+       spin_unlock_irqrestore(&ghes_lock, flags);
+ }
+@@ -465,10 +476,12 @@ static struct acpi_platform_list plat_list[] = {
+ int ghes_edac_register(struct ghes *ghes, struct device *dev)
+ {
+       bool fake = false;
+-      int rc, num_dimm = 0;
++      int rc = 0, num_dimm = 0;
+       struct mem_ctl_info *mci;
++      struct ghes_edac_pvt *pvt;
+       struct edac_mc_layer layers[1];
+       struct ghes_edac_dimm_fill dimm_fill;
++      unsigned long flags;
+       int idx = -1;
+       if (IS_ENABLED(CONFIG_X86)) {
+@@ -480,11 +493,14 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev)
+               idx = 0;
+       }
++      /* finish another registration/unregistration instance first */
++      mutex_lock(&ghes_reg_mutex);
++
+       /*
+        * We have only one logical memory controller to which all DIMMs belong.
+        */
+-      if (atomic_inc_return(&ghes_init) > 1)
+-              return 0;
++      if (refcount_inc_not_zero(&ghes_refcount))
++              goto unlock;
+       /* Get the number of DIMMs */
+       dmi_walk(ghes_edac_count_dimms, &num_dimm);
+@@ -502,12 +518,13 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev)
+       mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, sizeof(struct ghes_edac_pvt));
+       if (!mci) {
+               pr_info("Can't allocate memory for EDAC data\n");
+-              return -ENOMEM;
++              rc = -ENOMEM;
++              goto unlock;
+       }
+-      ghes_pvt        = mci->pvt_info;
+-      ghes_pvt->ghes  = ghes;
+-      ghes_pvt->mci   = mci;
++      pvt             = mci->pvt_info;
++      pvt->ghes       = ghes;
++      pvt->mci        = mci;
+       mci->pdev = dev;
+       mci->mtype_cap = MEM_FLAG_EMPTY;
+@@ -549,23 +566,48 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev)
+       if (rc < 0) {
+               pr_info("Can't register at EDAC core\n");
+               edac_mc_free(mci);
+-              return -ENODEV;
++              rc = -ENODEV;
++              goto unlock;
+       }
+-      return 0;
++
++      spin_lock_irqsave(&ghes_lock, flags);
++      ghes_pvt = pvt;
++      spin_unlock_irqrestore(&ghes_lock, flags);
++
++      /* only increment on success */
++      refcount_inc(&ghes_refcount);
++
++unlock:
++      mutex_unlock(&ghes_reg_mutex);
++
++      return rc;
+ }
+ void ghes_edac_unregister(struct ghes *ghes)
+ {
+       struct mem_ctl_info *mci;
++      unsigned long flags;
+-      if (!ghes_pvt)
+-              return;
++      mutex_lock(&ghes_reg_mutex);
+-      if (atomic_dec_return(&ghes_init))
+-              return;
++      if (!refcount_dec_and_test(&ghes_refcount))
++              goto unlock;
+-      mci = ghes_pvt->mci;
++      /*
++       * Wait for the irq handler being finished.
++       */
++      spin_lock_irqsave(&ghes_lock, flags);
++      mci = ghes_pvt ? ghes_pvt->mci : NULL;
+       ghes_pvt = NULL;
+-      edac_mc_del_mc(mci->pdev);
+-      edac_mc_free(mci);
++      spin_unlock_irqrestore(&ghes_lock, flags);
++
++      if (!mci)
++              goto unlock;
++
++      mci = edac_mc_del_mc(mci->pdev);
++      if (mci)
++              edac_mc_free(mci);
++
++unlock:
++      mutex_unlock(&ghes_reg_mutex);
+ }
+-- 
+2.25.1
+
diff --git a/queue-4.19/edac-ghes-use-cper-module-handles-to-locate-dimms.patch b/queue-4.19/edac-ghes-use-cper-module-handles-to-locate-dimms.patch
new file mode 100644 (file)
index 0000000..dc38a77
--- /dev/null
@@ -0,0 +1,104 @@
+From 957d981cb18842bcc33767199e5a83635c0e233d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Sep 2018 01:59:00 +0000
+Subject: EDAC, ghes: Use CPER module handles to locate DIMMs
+
+From: Fan Wu <wufan@codeaurora.org>
+
+[ Upstream commit c798c88f3962ddff89c7aa818986caeecd46ab4c ]
+
+Use SMBIOS module handle type 17, on platforms which provide valid
+ones, to locate the corresponding DIMM and thus have per-DIMM error
+counter updates.
+
+Signed-off-by: Fan Wu <wufan@codeaurora.org>
+[ Massage commit message. ]
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Tyler Baicar <baicar.tyler@gmail.com>
+Reviewed-by: James Morse <james.morse@arm.com>
+Tested-by: Toshi Kani <toshi.kani@hpe.com>
+Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
+Cc: baicar.tyler@gmail.com
+Cc: john.garry@huawei.com
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: linux-edac <linux-edac@vger.kernel.org>
+Cc: shiju.jose@huawei.com
+Cc: tanxiaofei@huawei.com
+Cc: wanghuiqiang@huawei.com
+Link: http://lkml.kernel.org/r/1537322340-1860-1-git-send-email-wufan@codeaurora.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/ghes_edac.c | 23 +++++++++++++++++++++++
+ include/linux/edac.h     |  2 ++
+ 2 files changed, 25 insertions(+)
+
+diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c
+index 78c339da19b5..02a7134ad75b 100644
+--- a/drivers/edac/ghes_edac.c
++++ b/drivers/edac/ghes_edac.c
+@@ -81,6 +81,18 @@ static void ghes_edac_count_dimms(const struct dmi_header *dh, void *arg)
+               (*num_dimm)++;
+ }
++static int get_dimm_smbios_index(u16 handle)
++{
++      struct mem_ctl_info *mci = ghes_pvt->mci;
++      int i;
++
++      for (i = 0; i < mci->tot_dimms; i++) {
++              if (mci->dimms[i]->smbios_handle == handle)
++                      return i;
++      }
++      return -1;
++}
++
+ static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg)
+ {
+       struct ghes_edac_dimm_fill *dimm_fill = arg;
+@@ -177,6 +189,8 @@ static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg)
+                               entry->total_width, entry->data_width);
+               }
++              dimm->smbios_handle = entry->handle;
++
+               dimm_fill->count++;
+       }
+ }
+@@ -328,12 +342,21 @@ void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
+               p += sprintf(p, "bit_pos:%d ", mem_err->bit_pos);
+       if (mem_err->validation_bits & CPER_MEM_VALID_MODULE_HANDLE) {
+               const char *bank = NULL, *device = NULL;
++              int index = -1;
++
+               dmi_memdev_name(mem_err->mem_dev_handle, &bank, &device);
+               if (bank != NULL && device != NULL)
+                       p += sprintf(p, "DIMM location:%s %s ", bank, device);
+               else
+                       p += sprintf(p, "DIMM DMI handle: 0x%.4x ",
+                                    mem_err->mem_dev_handle);
++
++              index = get_dimm_smbios_index(mem_err->mem_dev_handle);
++              if (index >= 0) {
++                      e->top_layer = index;
++                      e->enable_per_layer_report = true;
++              }
++
+       }
+       if (p > e->location)
+               *(p - 1) = '\0';
+diff --git a/include/linux/edac.h b/include/linux/edac.h
+index 958d69332c1d..1d0c9ea8825d 100644
+--- a/include/linux/edac.h
++++ b/include/linux/edac.h
+@@ -452,6 +452,8 @@ struct dimm_info {
+       u32 nr_pages;                   /* number of pages on this dimm */
+       unsigned csrow, cschannel;      /* Points to the old API data */
++
++      u16 smbios_handle;              /* Handle for SMBIOS type 17 */
+ };
+ /**
+-- 
+2.25.1
+
diff --git a/queue-4.19/libnvdimm-btt-fix-lba-masking-during-free-list-popul.patch b/queue-4.19/libnvdimm-btt-fix-lba-masking-during-free-list-popul.patch
new file mode 100644 (file)
index 0000000..7dbb96c
--- /dev/null
@@ -0,0 +1,153 @@
+From f9c8e5440846ff4ee40f8a15727ea8252a3f15d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Feb 2019 17:06:27 -0700
+Subject: libnvdimm/btt: Fix LBA masking during 'free list' population
+
+From: Vishal Verma <vishal.l.verma@intel.com>
+
+[ Upstream commit 9dedc73a4658ebcc0c9b58c3cb84e9ac80122213 ]
+
+The Linux BTT implementation assumes that log entries will never have
+the 'zero' flag set, and indeed it never sets that flag for log entries
+itself.
+
+However, the UEFI spec is ambiguous on the exact format of the LBA field
+of a log entry, specifically as to whether it should include the
+additional flag bits or not. While a zero bit doesn't make sense in the
+context of a log entry, other BTT implementations might still have it set.
+
+If an implementation does happen to have it set, we would happily read
+it in as the next block to write to for writes. Since a high bit is set,
+it pushes the block number out of the range of an 'arena', and we fail
+such a write with an EIO.
+
+Follow the robustness principle, and tolerate such implementations by
+stripping out the zero flag when populating the free list during
+initialization. Additionally, use the same stripped out entries for
+detection of incomplete writes and map restoration that happens at this
+stage.
+
+Add a sysfs file 'log_zero_flags' that indicates the ability to accept
+such a layout to userspace applications. This enables 'ndctl
+check-namespace' to recognize whether the kernel is able to handle zero
+flags, or whether it should attempt a fix-up under the --repair option.
+
+Cc: Dan Williams <dan.j.williams@intel.com>
+Reported-by: Dexuan Cui <decui@microsoft.com>
+Reported-by: Pedro d'Aquino Filocre F S Barbuda <pbarbuda@microsoft.com>
+Tested-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvdimm/btt.c      | 25 +++++++++++++++++++------
+ drivers/nvdimm/btt.h      |  2 ++
+ drivers/nvdimm/btt_devs.c |  8 ++++++++
+ 3 files changed, 29 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
+index d78cfe82ad5c..1064a703ccec 100644
+--- a/drivers/nvdimm/btt.c
++++ b/drivers/nvdimm/btt.c
+@@ -542,8 +542,8 @@ static int arena_clear_freelist_error(struct arena_info *arena, u32 lane)
+ static int btt_freelist_init(struct arena_info *arena)
+ {
+       int new, ret;
+-      u32 i, map_entry;
+       struct log_entry log_new;
++      u32 i, map_entry, log_oldmap, log_newmap;
+       arena->freelist = kcalloc(arena->nfree, sizeof(struct free_entry),
+                                       GFP_KERNEL);
+@@ -555,16 +555,22 @@ static int btt_freelist_init(struct arena_info *arena)
+               if (new < 0)
+                       return new;
++              /* old and new map entries with any flags stripped out */
++              log_oldmap = ent_lba(le32_to_cpu(log_new.old_map));
++              log_newmap = ent_lba(le32_to_cpu(log_new.new_map));
++
+               /* sub points to the next one to be overwritten */
+               arena->freelist[i].sub = 1 - new;
+               arena->freelist[i].seq = nd_inc_seq(le32_to_cpu(log_new.seq));
+-              arena->freelist[i].block = le32_to_cpu(log_new.old_map);
++              arena->freelist[i].block = log_oldmap;
+               /*
+                * FIXME: if error clearing fails during init, we want to make
+                * the BTT read-only
+                */
+-              if (ent_e_flag(log_new.old_map)) {
++              if (ent_e_flag(log_new.old_map) &&
++                              !ent_normal(log_new.old_map)) {
++                      arena->freelist[i].has_err = 1;
+                       ret = arena_clear_freelist_error(arena, i);
+                       if (ret)
+                               dev_err_ratelimited(to_dev(arena),
+@@ -572,7 +578,7 @@ static int btt_freelist_init(struct arena_info *arena)
+               }
+               /* This implies a newly created or untouched flog entry */
+-              if (log_new.old_map == log_new.new_map)
++              if (log_oldmap == log_newmap)
+                       continue;
+               /* Check if map recovery is needed */
+@@ -580,8 +586,15 @@ static int btt_freelist_init(struct arena_info *arena)
+                               NULL, NULL, 0);
+               if (ret)
+                       return ret;
+-              if ((le32_to_cpu(log_new.new_map) != map_entry) &&
+-                              (le32_to_cpu(log_new.old_map) == map_entry)) {
++
++              /*
++               * The map_entry from btt_read_map is stripped of any flag bits,
++               * so use the stripped out versions from the log as well for
++               * testing whether recovery is needed. For restoration, use the
++               * 'raw' version of the log entries as that captured what we
++               * were going to write originally.
++               */
++              if ((log_newmap != map_entry) && (log_oldmap == map_entry)) {
+                       /*
+                        * Last transaction wrote the flog, but wasn't able
+                        * to complete the map write. So fix up the map.
+diff --git a/drivers/nvdimm/btt.h b/drivers/nvdimm/btt.h
+index db3cb6d4d0d4..ddff49c707b0 100644
+--- a/drivers/nvdimm/btt.h
++++ b/drivers/nvdimm/btt.h
+@@ -44,6 +44,8 @@
+ #define ent_e_flag(ent) (!!(ent & MAP_ERR_MASK))
+ #define ent_z_flag(ent) (!!(ent & MAP_TRIM_MASK))
+ #define set_e_flag(ent) (ent |= MAP_ERR_MASK)
++/* 'normal' is both e and z flags set */
++#define ent_normal(ent) (ent_e_flag(ent) && ent_z_flag(ent))
+ enum btt_init_state {
+       INIT_UNCHECKED = 0,
+diff --git a/drivers/nvdimm/btt_devs.c b/drivers/nvdimm/btt_devs.c
+index e341498876ca..9486acc08402 100644
+--- a/drivers/nvdimm/btt_devs.c
++++ b/drivers/nvdimm/btt_devs.c
+@@ -159,11 +159,19 @@ static ssize_t size_show(struct device *dev,
+ }
+ static DEVICE_ATTR_RO(size);
++static ssize_t log_zero_flags_show(struct device *dev,
++              struct device_attribute *attr, char *buf)
++{
++      return sprintf(buf, "Y\n");
++}
++static DEVICE_ATTR_RO(log_zero_flags);
++
+ static struct attribute *nd_btt_attributes[] = {
+       &dev_attr_sector_size.attr,
+       &dev_attr_namespace.attr,
+       &dev_attr_uuid.attr,
+       &dev_attr_size.attr,
++      &dev_attr_log_zero_flags.attr,
+       NULL,
+ };
+-- 
+2.25.1
+
diff --git a/queue-4.19/libnvdimm-btt-remove-unnecessary-code-in-btt_freelis.patch b/queue-4.19/libnvdimm-btt-remove-unnecessary-code-in-btt_freelis.patch
new file mode 100644 (file)
index 0000000..ae2bad6
--- /dev/null
@@ -0,0 +1,51 @@
+From 2a7cc392098606a94124e3848738a37cfbc6a36b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Feb 2019 17:06:26 -0700
+Subject: libnvdimm/btt: Remove unnecessary code in btt_freelist_init
+
+From: Vishal Verma <vishal.l.verma@intel.com>
+
+[ Upstream commit 2f8c9011151337d0bc106693f272f9bddbccfab2 ]
+
+We call btt_log_read() twice, once to get the 'old' log entry, and again
+to get the 'new' entry. However, we have no use for the 'old' entry, so
+remove it.
+
+Cc: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvdimm/btt.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
+index 75ae2c508a04..d78cfe82ad5c 100644
+--- a/drivers/nvdimm/btt.c
++++ b/drivers/nvdimm/btt.c
+@@ -541,9 +541,9 @@ static int arena_clear_freelist_error(struct arena_info *arena, u32 lane)
+ static int btt_freelist_init(struct arena_info *arena)
+ {
+-      int old, new, ret;
++      int new, ret;
+       u32 i, map_entry;
+-      struct log_entry log_new, log_old;
++      struct log_entry log_new;
+       arena->freelist = kcalloc(arena->nfree, sizeof(struct free_entry),
+                                       GFP_KERNEL);
+@@ -551,10 +551,6 @@ static int btt_freelist_init(struct arena_info *arena)
+               return -ENOMEM;
+       for (i = 0; i < arena->nfree; i++) {
+-              old = btt_log_read(arena, i, &log_old, LOG_OLD_ENT);
+-              if (old < 0)
+-                      return old;
+-
+               new = btt_log_read(arena, i, &log_new, LOG_NEW_ENT);
+               if (new < 0)
+                       return new;
+-- 
+2.25.1
+
diff --git a/queue-4.19/media-fdp1-fix-r-car-m3-n-naming-in-debug-message.patch b/queue-4.19/media-fdp1-fix-r-car-m3-n-naming-in-debug-message.patch
new file mode 100644 (file)
index 0000000..f2484f8
--- /dev/null
@@ -0,0 +1,37 @@
+From a740df5747542a1bf0799f733f1d2394a8f42016 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Oct 2019 10:09:16 -0300
+Subject: media: fdp1: Fix R-Car M3-N naming in debug message
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit c05b9d7b9f3ece2831e4e4829f10e904df296df8 ]
+
+The official name is "R-Car M3-N", not "R-Car M3N".
+
+Fixes: 4e8c120de9268fc2 ("media: fdp1: Support M3N and E3 platforms")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/rcar_fdp1.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c
+index 5a30f1d84fe1..2bd5898a6204 100644
+--- a/drivers/media/platform/rcar_fdp1.c
++++ b/drivers/media/platform/rcar_fdp1.c
+@@ -2368,7 +2368,7 @@ static int fdp1_probe(struct platform_device *pdev)
+               dprintk(fdp1, "FDP1 Version R-Car H3\n");
+               break;
+       case FD1_IP_M3N:
+-              dprintk(fdp1, "FDP1 Version R-Car M3N\n");
++              dprintk(fdp1, "FDP1 Version R-Car M3-N\n");
+               break;
+       case FD1_IP_E3:
+               dprintk(fdp1, "FDP1 Version R-Car E3\n");
+-- 
+2.25.1
+
diff --git a/queue-4.19/net-bcmgenet-abort-suspend-on-error.patch b/queue-4.19/net-bcmgenet-abort-suspend-on-error.patch
new file mode 100644 (file)
index 0000000..c9c2bcc
--- /dev/null
@@ -0,0 +1,60 @@
+From 513f1113de9c37d8b071852468cbc7fa34d490a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Nov 2018 18:00:22 -0800
+Subject: net: bcmgenet: abort suspend on error
+
+From: Doug Berger <opendmb@gmail.com>
+
+[ Upstream commit c5a54bbcececa36852807c36157a86d808b62310 ]
+
+If an error occurs during suspension of the driver the driver should
+restore the hardware configuration and return an error to force the
+system to resume.
+
+Fixes: 0db55093b566 ("net: bcmgenet: return correct value 'ret' from bcmgenet_power_down")
+Signed-off-by: Doug Berger <opendmb@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/genet/bcmgenet.c     | 3 +++
+ drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 6 ++++++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+index 60abf9fab810..047fc0cf0263 100644
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+@@ -3722,6 +3722,9 @@ static int bcmgenet_suspend(struct device *d)
+       /* Turn off the clocks */
+       clk_disable_unprepare(priv->clk);
++      if (ret)
++              bcmgenet_resume(d);
++
+       return ret;
+ }
+ #endif /* CONFIG_PM_SLEEP */
+diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
+index 2fbd027f0148..b3596e0ee47b 100644
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
+@@ -186,9 +186,15 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
+       }
+       reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
++      if (!(reg & MPD_EN))
++              return; /* already powered up so skip the rest */
+       reg &= ~MPD_EN;
+       bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
++      reg = bcmgenet_hfb_reg_readl(priv, HFB_CTRL);
++      reg &= ~(RBUF_HFB_EN | RBUF_ACPI_EN);
++      bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL);
++
+       /* Disable CRC Forward */
+       reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+       reg &= ~CMD_CRC_FWD;
+-- 
+2.25.1
+
diff --git a/queue-4.19/net-bcmgenet-code-movement.patch b/queue-4.19/net-bcmgenet-code-movement.patch
new file mode 100644 (file)
index 0000000..94078db
--- /dev/null
@@ -0,0 +1,102 @@
+From 7be85a54418ebd2bd63ea4ba7d64fa8c040d773a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Nov 2018 18:00:21 -0800
+Subject: net: bcmgenet: code movement
+
+From: Doug Berger <opendmb@gmail.com>
+
+[ Upstream commit a94cbf03eb514d4d64d8c4f4caa0616b7ce5040a ]
+
+This commit switches the order of bcmgenet_suspend and bcmgenet_resume
+in the file to prevent the need for a forward declaration in the next
+commit and to make the review of that commit easier.
+
+Signed-off-by: Doug Berger <opendmb@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/broadcom/genet/bcmgenet.c    | 60 +++++++++----------
+ 1 file changed, 30 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+index 89cc146d2c5c..60abf9fab810 100644
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+@@ -3616,36 +3616,6 @@ static int bcmgenet_remove(struct platform_device *pdev)
+ }
+ #ifdef CONFIG_PM_SLEEP
+-static int bcmgenet_suspend(struct device *d)
+-{
+-      struct net_device *dev = dev_get_drvdata(d);
+-      struct bcmgenet_priv *priv = netdev_priv(dev);
+-      int ret = 0;
+-
+-      if (!netif_running(dev))
+-              return 0;
+-
+-      netif_device_detach(dev);
+-
+-      bcmgenet_netif_stop(dev);
+-
+-      if (!device_may_wakeup(d))
+-              phy_suspend(dev->phydev);
+-
+-      /* Prepare the device for Wake-on-LAN and switch to the slow clock */
+-      if (device_may_wakeup(d) && priv->wolopts) {
+-              ret = bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC);
+-              clk_prepare_enable(priv->clk_wol);
+-      } else if (priv->internal_phy) {
+-              ret = bcmgenet_power_down(priv, GENET_POWER_PASSIVE);
+-      }
+-
+-      /* Turn off the clocks */
+-      clk_disable_unprepare(priv->clk);
+-
+-      return ret;
+-}
+-
+ static int bcmgenet_resume(struct device *d)
+ {
+       struct net_device *dev = dev_get_drvdata(d);
+@@ -3724,6 +3694,36 @@ static int bcmgenet_resume(struct device *d)
+       clk_disable_unprepare(priv->clk);
+       return ret;
+ }
++
++static int bcmgenet_suspend(struct device *d)
++{
++      struct net_device *dev = dev_get_drvdata(d);
++      struct bcmgenet_priv *priv = netdev_priv(dev);
++      int ret = 0;
++
++      if (!netif_running(dev))
++              return 0;
++
++      netif_device_detach(dev);
++
++      bcmgenet_netif_stop(dev);
++
++      if (!device_may_wakeup(d))
++              phy_suspend(dev->phydev);
++
++      /* Prepare the device for Wake-on-LAN and switch to the slow clock */
++      if (device_may_wakeup(d) && priv->wolopts) {
++              ret = bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC);
++              clk_prepare_enable(priv->clk_wol);
++      } else if (priv->internal_phy) {
++              ret = bcmgenet_power_down(priv, GENET_POWER_PASSIVE);
++      }
++
++      /* Turn off the clocks */
++      clk_disable_unprepare(priv->clk);
++
++      return ret;
++}
+ #endif /* CONFIG_PM_SLEEP */
+ static SIMPLE_DEV_PM_OPS(bcmgenet_pm_ops, bcmgenet_suspend, bcmgenet_resume);
+-- 
+2.25.1
+
diff --git a/queue-4.19/nfit-add-hyper-v-nvdimm-dsm-command-set-to-white-lis.patch b/queue-4.19/nfit-add-hyper-v-nvdimm-dsm-command-set-to-white-lis.patch
new file mode 100644 (file)
index 0000000..f12c984
--- /dev/null
@@ -0,0 +1,110 @@
+From 87ea032c46864ced2f44cb87d96716384fae06f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Jan 2019 00:56:17 +0000
+Subject: nfit: Add Hyper-V NVDIMM DSM command set to white list
+
+From: Dexuan Cui <decui@microsoft.com>
+
+[ Upstream commit 1194c4133195dfcb6c5fc0935d54bbed872a5285 ]
+
+Add the Hyper-V _DSM command set to the white list of NVDIMM command
+sets.
+
+This command set is documented at http://www.uefi.org/RFIC_LIST
+(see "Virtual NVDIMM 0x1901").
+
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/nfit/core.c   | 17 ++++++++++++++---
+ drivers/acpi/nfit/nfit.h   |  6 +++++-
+ include/uapi/linux/ndctl.h |  1 +
+ 3 files changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
+index 8340c81b258b..dd4c7289610e 100644
+--- a/drivers/acpi/nfit/core.c
++++ b/drivers/acpi/nfit/core.c
+@@ -1773,9 +1773,17 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
+       dev_set_drvdata(&adev_dimm->dev, nfit_mem);
+       /*
+-       * Until standardization materializes we need to consider 4
+-       * different command sets.  Note, that checking for function0 (bit0)
+-       * tells us if any commands are reachable through this GUID.
++       * There are 4 "legacy" NVDIMM command sets
++       * (NVDIMM_FAMILY_{INTEL,MSFT,HPE1,HPE2}) that were created before
++       * an EFI working group was established to constrain this
++       * proliferation. The nfit driver probes for the supported command
++       * set by GUID. Note, if you're a platform developer looking to add
++       * a new command set to this probe, consider using an existing set,
++       * or otherwise seek approval to publish the command set at
++       * http://www.uefi.org/RFIC_LIST.
++       *
++       * Note, that checking for function0 (bit0) tells us if any commands
++       * are reachable through this GUID.
+        */
+       for (i = 0; i <= NVDIMM_FAMILY_MAX; i++)
+               if (acpi_check_dsm(adev_dimm->handle, to_nfit_uuid(i), 1, 1))
+@@ -1798,6 +1806,8 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
+                       dsm_mask &= ~(1 << 8);
+       } else if (nfit_mem->family == NVDIMM_FAMILY_MSFT) {
+               dsm_mask = 0xffffffff;
++      } else if (nfit_mem->family == NVDIMM_FAMILY_HYPERV) {
++              dsm_mask = 0x1f;
+       } else {
+               dev_dbg(dev, "unknown dimm command family\n");
+               nfit_mem->family = -1;
+@@ -3622,6 +3632,7 @@ static __init int nfit_init(void)
+       guid_parse(UUID_NFIT_DIMM_N_HPE1, &nfit_uuid[NFIT_DEV_DIMM_N_HPE1]);
+       guid_parse(UUID_NFIT_DIMM_N_HPE2, &nfit_uuid[NFIT_DEV_DIMM_N_HPE2]);
+       guid_parse(UUID_NFIT_DIMM_N_MSFT, &nfit_uuid[NFIT_DEV_DIMM_N_MSFT]);
++      guid_parse(UUID_NFIT_DIMM_N_HYPERV, &nfit_uuid[NFIT_DEV_DIMM_N_HYPERV]);
+       nfit_wq = create_singlethread_workqueue("nfit");
+       if (!nfit_wq)
+diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h
+index 68848fc4b7c9..cc2ec62951de 100644
+--- a/drivers/acpi/nfit/nfit.h
++++ b/drivers/acpi/nfit/nfit.h
+@@ -34,11 +34,14 @@
+ /* https://msdn.microsoft.com/library/windows/hardware/mt604741 */
+ #define UUID_NFIT_DIMM_N_MSFT "1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"
++/* http://www.uefi.org/RFIC_LIST (see "Virtual NVDIMM 0x1901") */
++#define UUID_NFIT_DIMM_N_HYPERV "5746c5f2-a9a2-4264-ad0e-e4ddc9e09e80"
++
+ #define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \
+               | ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \
+               | ACPI_NFIT_MEM_NOT_ARMED | ACPI_NFIT_MEM_MAP_FAILED)
+-#define NVDIMM_FAMILY_MAX NVDIMM_FAMILY_MSFT
++#define NVDIMM_FAMILY_MAX NVDIMM_FAMILY_HYPERV
+ #define NVDIMM_STANDARD_CMDMASK \
+ (1 << ND_CMD_SMART | 1 << ND_CMD_SMART_THRESHOLD | 1 << ND_CMD_DIMM_FLAGS \
+@@ -75,6 +78,7 @@ enum nfit_uuids {
+       NFIT_DEV_DIMM_N_HPE1 = NVDIMM_FAMILY_HPE1,
+       NFIT_DEV_DIMM_N_HPE2 = NVDIMM_FAMILY_HPE2,
+       NFIT_DEV_DIMM_N_MSFT = NVDIMM_FAMILY_MSFT,
++      NFIT_DEV_DIMM_N_HYPERV = NVDIMM_FAMILY_HYPERV,
+       NFIT_SPA_VOLATILE,
+       NFIT_SPA_PM,
+       NFIT_SPA_DCR,
+diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h
+index 2f2c43d633c5..7b0189d6dfa9 100644
+--- a/include/uapi/linux/ndctl.h
++++ b/include/uapi/linux/ndctl.h
+@@ -247,6 +247,7 @@ struct nd_cmd_pkg {
+ #define NVDIMM_FAMILY_HPE1 1
+ #define NVDIMM_FAMILY_HPE2 2
+ #define NVDIMM_FAMILY_MSFT 3
++#define NVDIMM_FAMILY_HYPERV 4
+ #define ND_IOCTL_CALL                 _IOWR(ND_IOCTL, ND_CMD_CALL,\
+                                       struct nd_cmd_pkg)
+-- 
+2.25.1
+
diff --git a/queue-4.19/ppp-mppe-revert-ppp-mppe-add-softdep-to-arc4.patch b/queue-4.19/ppp-mppe-revert-ppp-mppe-add-softdep-to-arc4.patch
new file mode 100644 (file)
index 0000000..d28fdc1
--- /dev/null
@@ -0,0 +1,47 @@
+From 6cf0a0eccfa292bf07b8ad1acc02bb38502a5e24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jul 2019 16:39:31 -0700
+Subject: ppp: mppe: Revert "ppp: mppe: Add softdep to arc4"
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit 25a09ce79639a8775244808c17282c491cff89cf ]
+
+Commit 0e5a610b5ca5 ("ppp: mppe: switch to RC4 library interface"),
+which was merged through the crypto tree for v5.3, changed ppp_mppe.c to
+use the new arc4_crypt() library function rather than access RC4 through
+the dynamic crypto_skcipher API.
+
+Meanwhile commit aad1dcc4f011 ("ppp: mppe: Add softdep to arc4") was
+merged through the net tree and added a module soft-dependency on "arc4".
+
+The latter commit no longer makes sense because the code now uses the
+"libarc4" module rather than "arc4", and also due to the direct use of
+arc4_crypt(), no module soft-dependency is required.
+
+So revert the latter commit.
+
+Cc: Takashi Iwai <tiwai@suse.de>
+Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ppp/ppp_mppe.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/net/ppp/ppp_mppe.c b/drivers/net/ppp/ppp_mppe.c
+index 8609c1a0777b..a205750b431b 100644
+--- a/drivers/net/ppp/ppp_mppe.c
++++ b/drivers/net/ppp/ppp_mppe.c
+@@ -63,7 +63,6 @@ MODULE_AUTHOR("Frank Cusack <fcusack@fcusack.com>");
+ MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support");
+ MODULE_LICENSE("Dual BSD/GPL");
+ MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
+-MODULE_SOFTDEP("pre: arc4");
+ MODULE_VERSION("1.0.2");
+ static unsigned int
+-- 
+2.25.1
+
diff --git a/queue-4.19/revert-gfs2-don-t-demote-a-glock-until-its-revokes-a.patch b/queue-4.19/revert-gfs2-don-t-demote-a-glock-until-its-revokes-a.patch
new file mode 100644 (file)
index 0000000..bb0a80f
--- /dev/null
@@ -0,0 +1,48 @@
+From 35729e2e2df4c17a422088744aab1b70950b2211 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 May 2020 15:01:25 -0500
+Subject: Revert "gfs2: Don't demote a glock until its revokes are written"
+
+From: Bob Peterson <rpeterso@redhat.com>
+
+[ Upstream commit b14c94908b1b884276a6608dea3d0b1b510338b7 ]
+
+This reverts commit df5db5f9ee112e76b5202fbc331f990a0fc316d6.
+
+This patch fixes a regression: patch df5db5f9ee112 allowed function
+run_queue() to bypass its call to do_xmote() if revokes were queued for
+the glock. That's wrong because its call to do_xmote() is what is
+responsible for calling the go_sync() glops functions to sync both
+the ail list and any revokes queued for it. By bypassing the call,
+gfs2 could get into a stand-off where the glock could not be demoted
+until its revokes are written back, but the revokes would not be
+written back because do_xmote() was never called.
+
+It "sort of" works, however, because there are other mechanisms like
+the log flush daemon (logd) that can sync the ail items and revokes,
+if it deems it necessary. The problem is: without file system pressure,
+it might never deem it necessary.
+
+Signed-off-by: Bob Peterson <rpeterso@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/glock.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
+index f8a5eef3d014..ccdd8c821abd 100644
+--- a/fs/gfs2/glock.c
++++ b/fs/gfs2/glock.c
+@@ -636,9 +636,6 @@ __acquires(&gl->gl_lockref.lock)
+                       goto out_unlock;
+               if (nonblock)
+                       goto out_sched;
+-              smp_mb();
+-              if (atomic_read(&gl->gl_revokes) != 0)
+-                      goto out_sched;
+               set_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags);
+               GLOCK_BUG_ON(gl, gl->gl_demote_state == LM_ST_EXCLUSIVE);
+               gl->gl_target = gl->gl_demote_state;
+-- 
+2.25.1
+
diff --git a/queue-4.19/revert-net-ibmvnic-fix-eoi-when-running-in-xive-mode.patch b/queue-4.19/revert-net-ibmvnic-fix-eoi-when-running-in-xive-mode.patch
new file mode 100644 (file)
index 0000000..8b6396c
--- /dev/null
@@ -0,0 +1,47 @@
+From ad90566c5a43a485d154bcf045e74fea47ba9aae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Nov 2019 10:50:03 -0500
+Subject: Revert "net/ibmvnic: Fix EOI when running in XIVE mode"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Juliet Kim <julietk@linux.vnet.ibm.com>
+
+[ Upstream commit 284f87d2f3871247d08a2b6a24466ae905079913 ]
+
+This reverts commit 11d49ce9f7946dfed4dcf5dbde865c78058b50ab
+(“net/ibmvnic: Fix EOI when running in XIVE mode.”) since that
+has the unintended effect of changing the interrupt priority
+and emits warning when running in legacy XICS mode.
+
+Signed-off-by: Juliet Kim <julietk@linux.vnet.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 8a1916443235..abfd990ba4d8 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -2731,10 +2731,12 @@ static int enable_scrq_irq(struct ibmvnic_adapter *adapter,
+       if (adapter->resetting &&
+           adapter->reset_reason == VNIC_RESET_MOBILITY) {
+-              struct irq_desc *desc = irq_to_desc(scrq->irq);
+-              struct irq_chip *chip = irq_desc_get_chip(desc);
++              u64 val = (0xff000000) | scrq->hw_irq;
+-              chip->irq_eoi(&desc->irq_data);
++              rc = plpar_hcall_norets(H_EOI, val);
++              if (rc)
++                      dev_err(dev, "H_EOI FAILED irq 0x%llx. rc=%ld\n",
++                              val, rc);
+       }
+       rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address,
+-- 
+2.25.1
+
index c68cb53cb0ab30ef20626d24aacc00f9df2ee925..be9ed6376d22ab1d77a9f7f54cd006777471c19f 100644 (file)
@@ -48,3 +48,20 @@ dmaengine-owl-use-correct-lock-in-owl_dma_get_pchan.patch
 drm-i915-gvt-init-dpll-ddi-vreg-for-virtual-display-instead-of-inheritance.patch
 powerpc-remove-strict_kernel_rwx-incompatibility-wit.patch
 powerpc-64s-disable-strict_kernel_rwx.patch
+nfit-add-hyper-v-nvdimm-dsm-command-set-to-white-lis.patch
+libnvdimm-btt-remove-unnecessary-code-in-btt_freelis.patch
+libnvdimm-btt-fix-lba-masking-during-free-list-popul.patch
+staging-most-core-replace-strcpy-by-strscpy.patch
+thunderbolt-drop-duplicated-get_switch_at_route.patch
+ppp-mppe-revert-ppp-mppe-add-softdep-to-arc4.patch
+media-fdp1-fix-r-car-m3-n-naming-in-debug-message.patch
+edac-ghes-use-cper-module-handles-to-locate-dimms.patch
+edac-ghes-fix-locking-and-memory-barrier-issues.patch
+revert-net-ibmvnic-fix-eoi-when-running-in-xive-mode.patch
+net-bcmgenet-code-movement.patch
+net-bcmgenet-abort-suspend-on-error.patch
+cxgb4-free-mac_hlist-properly.patch
+cxgb4-cxgb4vf-fix-mac_hlist-initialization-and-free.patch
+tty-serial-qcom_geni_serial-fix-wrap-around-of-tx-bu.patch
+brcmfmac-abort-and-release-host-after-error.patch
+revert-gfs2-don-t-demote-a-glock-until-its-revokes-a.patch
diff --git a/queue-4.19/staging-most-core-replace-strcpy-by-strscpy.patch b/queue-4.19/staging-most-core-replace-strcpy-by-strscpy.patch
new file mode 100644 (file)
index 0000000..afec688
--- /dev/null
@@ -0,0 +1,40 @@
+From 5c80194d5ce3914cc40cca608bd1368e51e4f5df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Apr 2019 10:40:38 -0500
+Subject: staging: most: core: replace strcpy() by strscpy()
+
+From: Gustavo A. R. Silva <gustavo@embeddedor.com>
+
+[ Upstream commit 3970d0d81816310175b6272e709ee09dd3e05171 ]
+
+The strcpy() function is being deprecated. Replace it by the safer
+strscpy() and fix the following Coverity warning:
+
+"You might overrun the 80-character fixed-size string iface->p->name
+by copying iface->description without checking the length."
+
+Addresses-Coverity-ID: 1444760 ("Copy into fixed size buffer")
+Fixes: 131ac62253db ("staging: most: core: use device description as name")
+Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/most/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c
+index 25a077f4ea94..08f60ce6293d 100644
+--- a/drivers/staging/most/core.c
++++ b/drivers/staging/most/core.c
+@@ -1412,7 +1412,7 @@ int most_register_interface(struct most_interface *iface)
+       INIT_LIST_HEAD(&iface->p->channel_list);
+       iface->p->dev_id = id;
+-      strcpy(iface->p->name, iface->description);
++      strscpy(iface->p->name, iface->description, sizeof(iface->p->name));
+       iface->dev.init_name = iface->p->name;
+       iface->dev.bus = &mc.bus;
+       iface->dev.parent = &mc.dev;
+-- 
+2.25.1
+
diff --git a/queue-4.19/thunderbolt-drop-duplicated-get_switch_at_route.patch b/queue-4.19/thunderbolt-drop-duplicated-get_switch_at_route.patch
new file mode 100644 (file)
index 0000000..2fae1cb
--- /dev/null
@@ -0,0 +1,138 @@
+From e0c6a6af7929c55acb7bf33401dcabc790b01df6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Mar 2019 14:56:21 +0200
+Subject: thunderbolt: Drop duplicated get_switch_at_route()
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit 8f965efd215a09c20b0b5e5bb4e20009a954472e ]
+
+tb_switch_find_by_route() does the same already so use it instead and
+remove duplicated get_switch_at_route().
+
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Reviewed-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thunderbolt/icm.c    | 12 ++++++++----
+ drivers/thunderbolt/switch.c | 18 ------------------
+ drivers/thunderbolt/tb.c     |  9 ++++++---
+ drivers/thunderbolt/tb.h     |  1 -
+ 4 files changed, 14 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c
+index 8490a1b6b615..2b83d8b02f81 100644
+--- a/drivers/thunderbolt/icm.c
++++ b/drivers/thunderbolt/icm.c
+@@ -801,9 +801,11 @@ icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr)
+        * connected another host to the same port, remove the switch
+        * first.
+        */
+-      sw = get_switch_at_route(tb->root_switch, route);
+-      if (sw)
++      sw = tb_switch_find_by_route(tb, route);
++      if (sw) {
+               remove_switch(sw);
++              tb_switch_put(sw);
++      }
+       sw = tb_switch_find_by_link_depth(tb, link, depth);
+       if (!sw) {
+@@ -1146,9 +1148,11 @@ icm_tr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr)
+        * connected another host to the same port, remove the switch
+        * first.
+        */
+-      sw = get_switch_at_route(tb->root_switch, route);
+-      if (sw)
++      sw = tb_switch_find_by_route(tb, route);
++      if (sw) {
+               remove_switch(sw);
++              tb_switch_put(sw);
++      }
+       sw = tb_switch_find_by_route(tb, get_parent_route(route));
+       if (!sw) {
+diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
+index 42d90ceec279..010a50ac4881 100644
+--- a/drivers/thunderbolt/switch.c
++++ b/drivers/thunderbolt/switch.c
+@@ -664,24 +664,6 @@ int tb_switch_reset(struct tb *tb, u64 route)
+       return res.err;
+ }
+-struct tb_switch *get_switch_at_route(struct tb_switch *sw, u64 route)
+-{
+-      u8 next_port = route; /*
+-                             * Routes use a stride of 8 bits,
+-                             * eventhough a port index has 6 bits at most.
+-                             * */
+-      if (route == 0)
+-              return sw;
+-      if (next_port > sw->config.max_port_number)
+-              return NULL;
+-      if (tb_is_upstream_port(&sw->ports[next_port]))
+-              return NULL;
+-      if (!sw->ports[next_port].remote)
+-              return NULL;
+-      return get_switch_at_route(sw->ports[next_port].remote->sw,
+-                                 route >> TB_ROUTE_SHIFT);
+-}
+-
+ /**
+  * tb_plug_events_active() - enable/disable plug events on a switch
+  *
+diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
+index 1424581fd9af..146f261bf2c3 100644
+--- a/drivers/thunderbolt/tb.c
++++ b/drivers/thunderbolt/tb.c
+@@ -258,7 +258,7 @@ static void tb_handle_hotplug(struct work_struct *work)
+       if (!tcm->hotplug_active)
+               goto out; /* during init, suspend or shutdown */
+-      sw = get_switch_at_route(tb->root_switch, ev->route);
++      sw = tb_switch_find_by_route(tb, ev->route);
+       if (!sw) {
+               tb_warn(tb,
+                       "hotplug event from non existent switch %llx:%x (unplug: %d)\n",
+@@ -269,14 +269,14 @@ static void tb_handle_hotplug(struct work_struct *work)
+               tb_warn(tb,
+                       "hotplug event from non existent port %llx:%x (unplug: %d)\n",
+                       ev->route, ev->port, ev->unplug);
+-              goto out;
++              goto put_sw;
+       }
+       port = &sw->ports[ev->port];
+       if (tb_is_upstream_port(port)) {
+               tb_warn(tb,
+                       "hotplug event for upstream port %llx:%x (unplug: %d)\n",
+                       ev->route, ev->port, ev->unplug);
+-              goto out;
++              goto put_sw;
+       }
+       if (ev->unplug) {
+               if (port->remote) {
+@@ -306,6 +306,9 @@ static void tb_handle_hotplug(struct work_struct *work)
+                       tb_activate_pcie_devices(tb);
+               }
+       }
++
++put_sw:
++      tb_switch_put(sw);
+ out:
+       mutex_unlock(&tb->lock);
+       kfree(ev);
+diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
+index 7a0ee9836a8a..d927cf7b14d2 100644
+--- a/drivers/thunderbolt/tb.h
++++ b/drivers/thunderbolt/tb.h
+@@ -397,7 +397,6 @@ void tb_switch_suspend(struct tb_switch *sw);
+ int tb_switch_resume(struct tb_switch *sw);
+ int tb_switch_reset(struct tb *tb, u64 route);
+ void tb_sw_set_unplugged(struct tb_switch *sw);
+-struct tb_switch *get_switch_at_route(struct tb_switch *sw, u64 route);
+ struct tb_switch *tb_switch_find_by_link_depth(struct tb *tb, u8 link,
+                                              u8 depth);
+ struct tb_switch *tb_switch_find_by_uuid(struct tb *tb, const uuid_t *uuid);
+-- 
+2.25.1
+
diff --git a/queue-4.19/tty-serial-qcom_geni_serial-fix-wrap-around-of-tx-bu.patch b/queue-4.19/tty-serial-qcom_geni_serial-fix-wrap-around-of-tx-bu.patch
new file mode 100644 (file)
index 0000000..9ace3b8
--- /dev/null
@@ -0,0 +1,76 @@
+From 1012adad00af2365ab6abad8cd2fc4de4ea4fdfd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Dec 2018 10:17:47 -0800
+Subject: tty: serial: qcom_geni_serial: Fix wrap around of TX buffer
+
+From: Matthias Kaehlcke <mka@chromium.org>
+
+[ Upstream commit 3c66eb4ba18dd1cab0d1bde651cde6d8bdb47696 ]
+
+Before commit a1fee899e5bed ("tty: serial: qcom_geni_serial: Fix
+softlock") the size of TX transfers was limited to the TX FIFO size,
+and wrap arounds of the UART circular buffer were split into two
+transfers. With the commit wrap around are allowed within a transfer.
+The TX FIFO of the geni serial port uses a word size of 4 bytes. In
+case of a circular buffer wrap within a transfer the driver currently
+may write an incomplete word to the FIFO, with some bytes containing
+data from the circular buffer and others being zero. Since the
+transfer isn't completed yet the zero bytes are sent as if they were
+actual data.
+
+Handle wrap arounds of the TX buffer properly and ensure that words
+written to the TX FIFO always contain valid data (unless the transfer
+is completed).
+
+Fixes: a1fee899e5bed ("tty: serial: qcom_geni_serial: Fix softlock")
+Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
+Reviewed-by: Evan Green <evgreen@chromium.org>
+Tested-by: Ryan Case <ryandcase@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/qcom_geni_serial.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
+index 4458419f053b..0d405cc58e72 100644
+--- a/drivers/tty/serial/qcom_geni_serial.c
++++ b/drivers/tty/serial/qcom_geni_serial.c
+@@ -705,7 +705,7 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
+       avail *= port->tx_bytes_pw;
+       tail = xmit->tail;
+-      chunk = min3(avail, pending, (size_t)(UART_XMIT_SIZE - tail));
++      chunk = min(avail, pending);
+       if (!chunk)
+               goto out_write_wakeup;
+@@ -727,19 +727,21 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
+               memset(buf, 0, ARRAY_SIZE(buf));
+               tx_bytes = min_t(size_t, remaining, port->tx_bytes_pw);
+-              for (c = 0; c < tx_bytes ; c++)
+-                      buf[c] = xmit->buf[tail + c];
++
++              for (c = 0; c < tx_bytes ; c++) {
++                      buf[c] = xmit->buf[tail++];
++                      tail &= UART_XMIT_SIZE - 1;
++              }
+               iowrite32_rep(uport->membase + SE_GENI_TX_FIFOn, buf, 1);
+               i += tx_bytes;
+-              tail += tx_bytes;
+               uport->icount.tx += tx_bytes;
+               remaining -= tx_bytes;
+               port->tx_remaining -= tx_bytes;
+       }
+-      xmit->tail = tail & (UART_XMIT_SIZE - 1);
++      xmit->tail = tail;
+       /*
+        * The tx fifo watermark is level triggered and latched. Though we had
+-- 
+2.25.1
+