From: Sasha Levin Date: Sun, 24 May 2020 13:51:25 +0000 (-0400) Subject: Fixes for 4.19 X-Git-Tag: v4.4.225~31 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=3f554c4ae7dd73001a1a1d2a1321af159d499416;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.19 Signed-off-by: Sasha Levin --- 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 index 00000000000..189ab5d451e --- /dev/null +++ b/queue-4.19/brcmfmac-abort-and-release-host-after-error.patch @@ -0,0 +1,57 @@ +From f20547486d3dff0d1905f4778d049e6f96580618 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Jan 2020 14:14:57 -0800 +Subject: brcmfmac: abort and release host after error + +From: Guenter Roeck + +[ 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 +[] (__schedule) from [] (schedule+0x98/0xc4) +[] (schedule) from [] (__mmc_claim_host+0x154/0x274) +[] (__mmc_claim_host) from [] (brcmf_sdio_watchdog_thread+0x1b0/0x1f8 [brcmfmac]) +[] (brcmf_sdio_watchdog_thread [brcmfmac]) from [] (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 +Cc: Matthias Kaehlcke +Cc: Brian Norris +Cc: Douglas Anderson +Signed-off-by: Guenter Roeck +Reviewed-by: Douglas Anderson +Acked-by: franky.lin@broadcom.com +Acked-by: Dan Carpenter +Signed-off-by: Kalle Valo +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..3c128eb50dd --- /dev/null +++ b/queue-4.19/cxgb4-cxgb4vf-fix-mac_hlist-initialization-and-free.patch @@ -0,0 +1,116 @@ +From e212d6737da4d99294953d11f69e7decc2559da6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Nov 2018 12:11:39 +0530 +Subject: cxgb4/cxgb4vf: Fix mac_hlist initialization and free + +From: Arjun Vynipadath + +[ 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 +Signed-off-by: Casey Leedom +Signed-off-by: Ganesh Goudar +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..2258e9d1198 --- /dev/null +++ b/queue-4.19/cxgb4-free-mac_hlist-properly.patch @@ -0,0 +1,49 @@ +From 6535fe7b7166cb98416265bbba8b7acea148aadd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Nov 2018 14:50:25 +0530 +Subject: cxgb4: free mac_hlist properly + +From: Arjun Vynipadath + +[ Upstream commit 2a8d84bf513823ba398f4b2dec41b8decf4041af ] + +The locally maintained list for tracking hash mac table was +not freed during driver remove. + +Signed-off-by: Arjun Vynipadath +Signed-off-by: Ganesh Goudar +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..b6db0924aa1 --- /dev/null +++ b/queue-4.19/edac-ghes-fix-locking-and-memory-barrier-issues.patch @@ -0,0 +1,265 @@ +From d3ff24263fd0320ccf2a5292cfe8c8a8343813e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2019 20:07:51 +0000 +Subject: EDAC/ghes: Fix locking and memory barrier issues + +From: Robert Richter + +[ 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 +Signed-off-by: James Morse +Co-developed-by: Borislav Petkov +Signed-off-by: Borislav Petkov +Signed-off-by: Robert Richter +Signed-off-by: Borislav Petkov +Cc: "linux-edac@vger.kernel.org" +Cc: Mauro Carvalho Chehab +Cc: Tony Luck +Link: https://lkml.kernel.org/r/20191105200732.3053-1-rrichter@marvell.com +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..dc38a772d9b --- /dev/null +++ b/queue-4.19/edac-ghes-use-cper-module-handles-to-locate-dimms.patch @@ -0,0 +1,104 @@ +From 957d981cb18842bcc33767199e5a83635c0e233d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Sep 2018 01:59:00 +0000 +Subject: EDAC, ghes: Use CPER module handles to locate DIMMs + +From: Fan Wu + +[ 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 +[ Massage commit message. ] +Signed-off-by: Borislav Petkov +Reviewed-by: Tyler Baicar +Reviewed-by: James Morse +Tested-by: Toshi Kani +Cc: Mauro Carvalho Chehab +Cc: baicar.tyler@gmail.com +Cc: john.garry@huawei.com +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-edac +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 +--- + 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 index 00000000000..7dbb96cd003 --- /dev/null +++ b/queue-4.19/libnvdimm-btt-fix-lba-masking-during-free-list-popul.patch @@ -0,0 +1,153 @@ +From f9c8e5440846ff4ee40f8a15727ea8252a3f15d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Feb 2019 17:06:27 -0700 +Subject: libnvdimm/btt: Fix LBA masking during 'free list' population + +From: Vishal Verma + +[ 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 +Reported-by: Dexuan Cui +Reported-by: Pedro d'Aquino Filocre F S Barbuda +Tested-by: Dexuan Cui +Signed-off-by: Vishal Verma +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..ae2bad6e615 --- /dev/null +++ b/queue-4.19/libnvdimm-btt-remove-unnecessary-code-in-btt_freelis.patch @@ -0,0 +1,51 @@ +From 2a7cc392098606a94124e3848738a37cfbc6a36b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Feb 2019 17:06:26 -0700 +Subject: libnvdimm/btt: Remove unnecessary code in btt_freelist_init + +From: Vishal Verma + +[ 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 +Signed-off-by: Vishal Verma +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..f2484f8035b --- /dev/null +++ b/queue-4.19/media-fdp1-fix-r-car-m3-n-naming-in-debug-message.patch @@ -0,0 +1,37 @@ +From a740df5747542a1bf0799f733f1d2394a8f42016 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Oct 2019 10:09:16 -0300 +Subject: media: fdp1: Fix R-Car M3-N naming in debug message + +From: Geert Uytterhoeven + +[ 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 +Reviewed-by: Kieran Bingham +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..c9c2bcc90bf --- /dev/null +++ b/queue-4.19/net-bcmgenet-abort-suspend-on-error.patch @@ -0,0 +1,60 @@ +From 513f1113de9c37d8b071852468cbc7fa34d490a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Nov 2018 18:00:22 -0800 +Subject: net: bcmgenet: abort suspend on error + +From: Doug Berger + +[ 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 +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..94078db63e3 --- /dev/null +++ b/queue-4.19/net-bcmgenet-code-movement.patch @@ -0,0 +1,102 @@ +From 7be85a54418ebd2bd63ea4ba7d64fa8c040d773a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Nov 2018 18:00:21 -0800 +Subject: net: bcmgenet: code movement + +From: Doug Berger + +[ 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 +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..f12c984df2d --- /dev/null +++ b/queue-4.19/nfit-add-hyper-v-nvdimm-dsm-command-set-to-white-lis.patch @@ -0,0 +1,110 @@ +From 87ea032c46864ced2f44cb87d96716384fae06f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Jan 2019 00:56:17 +0000 +Subject: nfit: Add Hyper-V NVDIMM DSM command set to white list + +From: Dexuan Cui + +[ 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 +Reviewed-by: Michael Kelley +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..d28fdc15012 --- /dev/null +++ b/queue-4.19/ppp-mppe-revert-ppp-mppe-add-softdep-to-arc4.patch @@ -0,0 +1,47 @@ +From 6cf0a0eccfa292bf07b8ad1acc02bb38502a5e24 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Jul 2019 16:39:31 -0700 +Subject: ppp: mppe: Revert "ppp: mppe: Add softdep to arc4" + +From: Eric Biggers + +[ 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 +Cc: Ard Biesheuvel +Signed-off-by: Eric Biggers +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 "); + 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 index 00000000000..bb0a80f86d1 --- /dev/null +++ b/queue-4.19/revert-gfs2-don-t-demote-a-glock-until-its-revokes-a.patch @@ -0,0 +1,48 @@ +From 35729e2e2df4c17a422088744aab1b70950b2211 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..8b6396c7063 --- /dev/null +++ b/queue-4.19/revert-net-ibmvnic-fix-eoi-when-running-in-xive-mode.patch @@ -0,0 +1,47 @@ +From ad90566c5a43a485d154bcf045e74fea47ba9aae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-4.19/series b/queue-4.19/series index c68cb53cb0a..be9ed6376d2 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -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 index 00000000000..afec688c326 --- /dev/null +++ b/queue-4.19/staging-most-core-replace-strcpy-by-strscpy.patch @@ -0,0 +1,40 @@ +From 5c80194d5ce3914cc40cca608bd1368e51e4f5df Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Apr 2019 10:40:38 -0500 +Subject: staging: most: core: replace strcpy() by strscpy() + +From: Gustavo A. R. Silva + +[ 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 +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..2fae1cb6a2f --- /dev/null +++ b/queue-4.19/thunderbolt-drop-duplicated-get_switch_at_route.patch @@ -0,0 +1,138 @@ +From e0c6a6af7929c55acb7bf33401dcabc790b01df6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Mar 2019 14:56:21 +0200 +Subject: thunderbolt: Drop duplicated get_switch_at_route() + +From: Mika Westerberg + +[ 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 +Reviewed-by: Lukas Wunner +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..9ace3b85577 --- /dev/null +++ b/queue-4.19/tty-serial-qcom_geni_serial-fix-wrap-around-of-tx-bu.patch @@ -0,0 +1,76 @@ +From 1012adad00af2365ab6abad8cd2fc4de4ea4fdfd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Dec 2018 10:17:47 -0800 +Subject: tty: serial: qcom_geni_serial: Fix wrap around of TX buffer + +From: Matthias Kaehlcke + +[ 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 +Reviewed-by: Evan Green +Tested-by: Ryan Case +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 +