From: Masahiro Yamada masahiroy@kernel.org
[ Upstream commit 63b903dfebdea92aa92ad337d8451a6fbfeabf9d ]
As far as I understood from the Kconfig help text, this build rule is used to rebuild the driver firmware, which runs on an old m68k-based chip. So, you need m68k tools for the firmware rebuild.
wanxl.c is a PCI driver, but CONFIG_M68K does not select CONFIG_HAVE_PCI. So, you cannot enable CONFIG_WANXL_BUILD_FIRMWARE for ARCH=m68k. In other words, ifeq ($(ARCH),m68k) is false here.
I am keeping the dead code for now, but rebuilding the firmware requires 'as68k' and 'ld68k', which I do not have in hand.
Instead, the kernel.org m68k GCC [1] successfully built it.
Allowing a user to pass in CROSS_COMPILE_M68K= is handier.
[1] https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/9.2.0/x...
Suggested-by: Geert Uytterhoeven geert@linux-m68k.org Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wan/Kconfig | 2 +- drivers/net/wan/Makefile | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig index 4e9fe75d70675..21190dfbabb16 100644 --- a/drivers/net/wan/Kconfig +++ b/drivers/net/wan/Kconfig @@ -199,7 +199,7 @@ config WANXL_BUILD_FIRMWARE depends on WANXL && !PREVENT_FIRMWARE_BUILD help Allows you to rebuild firmware run by the QUICC processor. - It requires as68k, ld68k and hexdump programs. + It requires m68k toolchains and hexdump programs.
You should never need this option, say N.
diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile index 9532e69fda878..c21b7345b50b1 100644 --- a/drivers/net/wan/Makefile +++ b/drivers/net/wan/Makefile @@ -41,17 +41,17 @@ $(obj)/wanxl.o: $(obj)/wanxlfw.inc
ifeq ($(CONFIG_WANXL_BUILD_FIRMWARE),y) ifeq ($(ARCH),m68k) - AS68K = $(AS) - LD68K = $(LD) + M68KAS = $(AS) + M68KLD = $(LD) else - AS68K = as68k - LD68K = ld68k + M68KAS = $(CROSS_COMPILE_M68K)as + M68KLD = $(CROSS_COMPILE_M68K)ld endif
quiet_cmd_build_wanxlfw = BLD FW $@ cmd_build_wanxlfw = \ - $(CPP) -D__ASSEMBLY__ -Wp,-MD,$(depfile) -I$(srctree)/include/uapi $< | $(AS68K) -m68360 -o $(obj)/wanxlfw.o; \ - $(LD68K) --oformat binary -Ttext 0x1000 $(obj)/wanxlfw.o -o $(obj)/wanxlfw.bin; \ + $(CPP) -D__ASSEMBLY__ -Wp,-MD,$(depfile) -I$(srctree)/include/uapi $< | $(M68KAS) -m68360 -o $(obj)/wanxlfw.o; \ + $(M68KLD) --oformat binary -Ttext 0x1000 $(obj)/wanxlfw.o -o $(obj)/wanxlfw.bin; \ hexdump -ve '"\n" 16/1 "0x%02X,"' $(obj)/wanxlfw.bin | sed 's/0x ,//g;1s/^/static const u8 firmware[]={/;$$s/,$$/\n};\n/' >$(obj)/wanxlfw.inc; \ rm -f $(obj)/wanxlfw.bin $(obj)/wanxlfw.o
From: Heiner Kallweit hkallweit1@gmail.com
[ Upstream commit 16983507742cbcaa5592af530872a82e82fb9c51 ]
If we have scenarios like
mdiobus_register() -> loads PHY driver module(s) -> registers PHY driver(s) -> may schedule async probe phydev = mdiobus_get_phy() <phydev action involving PHY driver>
or
phydev = phy_device_create() -> loads PHY driver module -> registers PHY driver -> may schedule async probe <phydev action involving PHY driver>
then we expect the PHY driver to be bound to the phydev when triggering the action. This may not be the case in case of asynchronous probing. Therefore ensure that PHY drivers are probed synchronously.
Default still is sync probing, except async probing is explicitly requested. I saw some comments that the intention is to promote async probing for more parallelism in boot process and want to be prepared for the case that the default is changed to async probing.
Signed-off-by: Heiner Kallweit hkallweit1@gmail.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Reviewed-by: Andrew Lunn andrew@lunn.ch Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/phy_device.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 302d183beb9e8..9ae121cb6dc11 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -1939,6 +1939,7 @@ int phy_driver_register(struct phy_driver *new_driver, struct module *owner) new_driver->mdiodrv.driver.probe = phy_probe; new_driver->mdiodrv.driver.remove = phy_remove; new_driver->mdiodrv.driver.owner = owner; + new_driver->mdiodrv.driver.probe_type = PROBE_FORCE_SYNCHRONOUS;
/* The following works around an issue where the PHY driver doesn't bind * to the device, resulting in the genphy driver being used instead of
From: Zhu Yanjun yanjunz@mellanox.com
[ Upstream commit d0ca2c35dd15a3d989955caec02beea02f735ee6 ]
The RXE driver doesn't set sys_image_guid and user space applications see zeros. This causes to pyverbs tests to fail with the following traceback, because the IBTA spec requires to have valid sys_image_guid.
Traceback (most recent call last): File "./tests/test_device.py", line 51, in test_query_device self.verify_device_attr(attr) File "./tests/test_device.py", line 74, in verify_device_attr assert attr.sys_image_guid != 0
In order to fix it, set sys_image_guid to be equal to node_guid.
Before: 5: rxe0: ... node_guid 5054:00ff:feaa:5363 sys_image_guid 0000:0000:0000:0000
After: 5: rxe0: ... node_guid 5054:00ff:feaa:5363 sys_image_guid 5054:00ff:feaa:5363
Fixes: 8700e3e7c485 ("Soft RoCE driver") Link: https://lore.kernel.org/r/20200323112800.1444784-1-leon@kernel.org Signed-off-by: Zhu Yanjun yanjunz@mellanox.com Signed-off-by: Leon Romanovsky leonro@mellanox.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rxe/rxe.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c index 10999fa692818..157d08f167345 100644 --- a/drivers/infiniband/sw/rxe/rxe.c +++ b/drivers/infiniband/sw/rxe/rxe.c @@ -121,6 +121,8 @@ static void rxe_init_device_param(struct rxe_dev *rxe) rxe->attr.max_fast_reg_page_list_len = RXE_MAX_FMR_PAGE_LIST_LEN; rxe->attr.max_pkeys = RXE_MAX_PKEYS; rxe->attr.local_ca_ack_delay = RXE_LOCAL_CA_ACK_DELAY; + addrconf_addr_eui48((unsigned char *)&rxe->attr.sys_image_guid, + rxe->ndev->dev_addr);
rxe->max_ucontext = RXE_MAX_UCONTEXT; }
From: Haibo Chen haibo.chen@nxp.com
[ Upstream commit e65bb38824711559844ba932132f417bc5a355e2 ]
Except SDHCI_QUIRK_BROKEN_CARD_DETECTION and MMC_CAP_NONREMOVABLE, we also do not need to handle controller native card detect interrupt for gpio cd type. If we wrong enabled the card detect interrupt for gpio case, it will cause a lot of unexpected card detect interrupts during data transfer which should not happen.
Signed-off-by: Haibo Chen haibo.chen@nxp.com Acked-by: Adrian Hunter adrian.hunter@intel.com Reviewed-by: Linus Walleij linus.walleij@linaro.org Link: https://lore.kernel.org/r/1582100563-20555-2-git-send-email-haibo.chen@nxp.c... Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 5a7fd89a8f2b1..499a3d2a8e315 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -133,7 +133,7 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable) u32 present;
if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) || - !mmc_card_is_removable(host->mmc)) + !mmc_card_is_removable(host->mmc) || mmc_can_gpio_cd(host->mmc)) return;
if (enable) {
From: Peter Ujfalusi peter.ujfalusi@ti.com
[ Upstream commit 4ce35a3617c0ac758c61122b2218b6c8c9ac9398 ]
When booting j721e the following bug is printed:
[ 1.154821] BUG: sleeping function called from invalid context at kernel/sched/completion.c:99 [ 1.154827] in_atomic(): 0, irqs_disabled(): 128, non_block: 0, pid: 12, name: kworker/0:1 [ 1.154832] 3 locks held by kworker/0:1/12: [ 1.154836] #0: ffff000840030728 ((wq_completion)events){+.+.}, at: process_one_work+0x1d4/0x6e8 [ 1.154852] #1: ffff80001214fdd8 (deferred_probe_work){+.+.}, at: process_one_work+0x1d4/0x6e8 [ 1.154860] #2: ffff00084060b170 (&dev->mutex){....}, at: __device_attach+0x38/0x138 [ 1.154872] irq event stamp: 63096 [ 1.154881] hardirqs last enabled at (63095): [<ffff800010b74318>] _raw_spin_unlock_irqrestore+0x70/0x78 [ 1.154887] hardirqs last disabled at (63096): [<ffff800010b740d8>] _raw_spin_lock_irqsave+0x28/0x80 [ 1.154893] softirqs last enabled at (62254): [<ffff800010080c88>] _stext+0x488/0x564 [ 1.154899] softirqs last disabled at (62247): [<ffff8000100fdb3c>] irq_exit+0x114/0x140 [ 1.154906] CPU: 0 PID: 12 Comm: kworker/0:1 Not tainted 5.6.0-rc6-next-20200318-00094-g45e4089b0bd3 #221 [ 1.154911] Hardware name: Texas Instruments K3 J721E SoC (DT) [ 1.154917] Workqueue: events deferred_probe_work_func [ 1.154923] Call trace: [ 1.154928] dump_backtrace+0x0/0x190 [ 1.154933] show_stack+0x14/0x20 [ 1.154940] dump_stack+0xe0/0x148 [ 1.154946] ___might_sleep+0x150/0x1f0 [ 1.154952] __might_sleep+0x4c/0x80 [ 1.154957] wait_for_completion_timeout+0x40/0x140 [ 1.154964] ti_sci_set_device_state+0xa0/0x158 [ 1.154969] ti_sci_cmd_get_device_exclusive+0x14/0x20 [ 1.154977] ti_sci_dev_start+0x34/0x50 [ 1.154984] genpd_runtime_resume+0x78/0x1f8 [ 1.154991] __rpm_callback+0x3c/0x140 [ 1.154996] rpm_callback+0x20/0x80 [ 1.155001] rpm_resume+0x568/0x758 [ 1.155007] __pm_runtime_resume+0x44/0xb0 [ 1.155013] omap8250_probe+0x2b4/0x508 [ 1.155019] platform_drv_probe+0x50/0xa0 [ 1.155023] really_probe+0xd4/0x318 [ 1.155028] driver_probe_device+0x54/0xe8 [ 1.155033] __device_attach_driver+0x80/0xb8 [ 1.155039] bus_for_each_drv+0x74/0xc0 [ 1.155044] __device_attach+0xdc/0x138 [ 1.155049] device_initial_probe+0x10/0x18 [ 1.155053] bus_probe_device+0x98/0xa0 [ 1.155058] deferred_probe_work_func+0x74/0xb0 [ 1.155063] process_one_work+0x280/0x6e8 [ 1.155068] worker_thread+0x48/0x430 [ 1.155073] kthread+0x108/0x138 [ 1.155079] ret_from_fork+0x10/0x18
To fix the bug we need to first call pm_runtime_enable() prior to any pm_runtime calls.
Reported-by: Tomi Valkeinen tomi.valkeinen@ti.com Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Link: https://lore.kernel.org/r/20200320125200.6772-1-peter.ujfalusi@ti.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index a019286f8bb65..a7e555e413a69 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -1227,11 +1227,11 @@ static int omap8250_probe(struct platform_device *pdev) spin_lock_init(&priv->rx_dma_lock);
device_init_wakeup(&pdev->dev, true); + pm_runtime_enable(&pdev->dev); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, -1);
pm_runtime_irq_safe(&pdev->dev); - pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit da206d65f2b293274f8082a26da4e43a1610da54 ]
The helper for configuring the pinout of the MII side of the PHY should do so irrespective of whether RGMII delays are used or not. So accept the ID, TXID and RXID variants as well, not just the no-delay RGMII variant.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.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/phy/mscc.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c index 36647b70b9a36..1ff03d5cb6a64 100644 --- a/drivers/net/phy/mscc.c +++ b/drivers/net/phy/mscc.c @@ -470,6 +470,9 @@ static int vsc85xx_mac_if_set(struct phy_device *phydev, reg_val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1); reg_val &= ~(MAC_IF_SELECTION_MASK); switch (interface) { + case PHY_INTERFACE_MODE_RGMII_TXID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_ID: case PHY_INTERFACE_MODE_RGMII: reg_val |= (MAC_IF_SELECTION_RGMII << MAC_IF_SELECTION_POS); break;
From: Jason Gunthorpe jgg@mellanox.com
[ Upstream commit 8a6c61704746d3a1e004e054504ae8d98ed95697 ]
A work queue cannot just rely on the ib_device not being freed, it must hold a kref on the memory so that the BNXT_RE_FLAG_IBDEV_REGISTERED check works.
Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Link: https://lore.kernel.org/r/1584117207-2664-3-git-send-email-selvin.xavier@bro... Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/bnxt_re/main.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c index 589b0d4677d52..75fe489a70b0c 100644 --- a/drivers/infiniband/hw/bnxt_re/main.c +++ b/drivers/infiniband/hw/bnxt_re/main.c @@ -1505,6 +1505,7 @@ static void bnxt_re_task(struct work_struct *work) smp_mb__before_atomic(); atomic_dec(&rdev->sched_count); exit: + put_device(&rdev->ibdev.dev); kfree(re_work); }
@@ -1581,6 +1582,7 @@ static int bnxt_re_netdev_event(struct notifier_block *notifier, /* Allocate for the deferred task */ re_work = kzalloc(sizeof(*re_work), GFP_ATOMIC); if (re_work) { + get_device(&rdev->ibdev.dev); re_work->rdev = rdev; re_work->event = event; re_work->vlan_dev = (real_dev == netdev ?
From: Jason Gunthorpe jgg@mellanox.com
[ Upstream commit d1de9a88074b66482443f0cd91618d7b51a7c9b6 ]
All accesses to id.state must be done under the spinlock.
Fixes: a977049dacde ("[PATCH] IB: Add the kernel CM implementation") Link: https://lore.kernel.org/r/20200310092545.251365-10-leon@kernel.org Signed-off-by: Leon Romanovsky leonro@mellanox.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/core/cm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 64f206e11d497..7251068b6af0f 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -1812,8 +1812,12 @@ static void cm_dup_req_handler(struct cm_work *work, counter[CM_REQ_COUNTER]);
/* Quick state check to discard duplicate REQs. */ - if (cm_id_priv->id.state == IB_CM_REQ_RCVD) + spin_lock_irq(&cm_id_priv->lock); + if (cm_id_priv->id.state == IB_CM_REQ_RCVD) { + spin_unlock_irq(&cm_id_priv->lock); return; + } + spin_unlock_irq(&cm_id_priv->lock);
ret = cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg); if (ret)
From: Arindam Nath arindam.nath@amd.com
[ Upstream commit 2465b87ce36ea2dbd97e5fb58a0efd284c9f687e ]
amd_ack_smu() should only set the corresponding bits into SMUACK register. Setting the bitmask of peer_sta should be done within the event handler. They are two different things, and so should be handled differently and at different places.
Signed-off-by: Arindam Nath arindam.nath@amd.com Signed-off-by: Jon Mason jdmason@kudzu.us Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ntb/hw/amd/ntb_hw_amd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/ntb/hw/amd/ntb_hw_amd.c b/drivers/ntb/hw/amd/ntb_hw_amd.c index efb214fc545a2..967724ccb03ac 100644 --- a/drivers/ntb/hw/amd/ntb_hw_amd.c +++ b/drivers/ntb/hw/amd/ntb_hw_amd.c @@ -493,8 +493,6 @@ static void amd_ack_smu(struct amd_ntb_dev *ndev, u32 bit) reg = readl(mmio + AMD_SMUACK_OFFSET); reg |= bit; writel(reg, mmio + AMD_SMUACK_OFFSET); - - ndev->peer_sta |= bit; }
static void amd_handle_event(struct amd_ntb_dev *ndev, int vec) @@ -512,9 +510,11 @@ static void amd_handle_event(struct amd_ntb_dev *ndev, int vec) status &= AMD_EVENT_INTMASK; switch (status) { case AMD_PEER_FLUSH_EVENT: + ndev->peer_sta |= AMD_PEER_FLUSH_EVENT; dev_info(dev, "Flush is done.\n"); break; case AMD_PEER_RESET_EVENT: + ndev->peer_sta |= AMD_PEER_RESET_EVENT; amd_ack_smu(ndev, AMD_PEER_RESET_EVENT);
/* link down first */ @@ -527,6 +527,7 @@ static void amd_handle_event(struct amd_ntb_dev *ndev, int vec) case AMD_PEER_PMETO_EVENT: case AMD_LINK_UP_EVENT: case AMD_LINK_DOWN_EVENT: + ndev->peer_sta |= status; amd_ack_smu(ndev, status);
/* link down */ @@ -540,6 +541,7 @@ static void amd_handle_event(struct amd_ntb_dev *ndev, int vec) if (status & 0x1) dev_info(dev, "Wakeup is done.\n");
+ ndev->peer_sta |= AMD_PEER_D0_EVENT; amd_ack_smu(ndev, AMD_PEER_D0_EVENT);
/* start a timer to poll link status */
From: Helge Deller deller@gmx.de
[ Upstream commit 2ef97a6c181eba48f14c9ed98ce4398d21164683 ]
The correct printk format is %pa or %pap, but not %pa[p].
Fixes: 7f46c8b3a5523 ("NTB: ntb_tool: Add full multi-port NTB API support") Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Jon Mason jdmason@kudzu.us Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ntb/test/ntb_tool.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/ntb/test/ntb_tool.c b/drivers/ntb/test/ntb_tool.c index d592c0ffbd198..69da758fe64c8 100644 --- a/drivers/ntb/test/ntb_tool.c +++ b/drivers/ntb/test/ntb_tool.c @@ -678,19 +678,19 @@ static ssize_t tool_mw_trans_read(struct file *filep, char __user *ubuf, &inmw->dma_base);
off += scnprintf(buf + off, buf_size - off, - "Window Size \t%pa[p]\n", + "Window Size \t%pap\n", &inmw->size);
off += scnprintf(buf + off, buf_size - off, - "Alignment \t%pa[p]\n", + "Alignment \t%pap\n", &addr_align);
off += scnprintf(buf + off, buf_size - off, - "Size Alignment \t%pa[p]\n", + "Size Alignment \t%pap\n", &size_align);
off += scnprintf(buf + off, buf_size - off, - "Size Max \t%pa[p]\n", + "Size Max \t%pap\n", &size_max);
ret = simple_read_from_buffer(ubuf, size, offp, buf, off); @@ -907,16 +907,16 @@ static ssize_t tool_peer_mw_trans_read(struct file *filep, char __user *ubuf, "Virtual address \t0x%pK\n", outmw->io_base);
off += scnprintf(buf + off, buf_size - off, - "Phys Address \t%pa[p]\n", &map_base); + "Phys Address \t%pap\n", &map_base);
off += scnprintf(buf + off, buf_size - off, - "Mapping Size \t%pa[p]\n", &map_size); + "Mapping Size \t%pap\n", &map_size);
off += scnprintf(buf + off, buf_size - off, "Translation Address \t0x%016llx\n", outmw->tr_base);
off += scnprintf(buf + off, buf_size - off, - "Window Size \t%pa[p]\n", &outmw->size); + "Window Size \t%pap\n", &outmw->size);
ret = simple_read_from_buffer(ubuf, size, offp, buf, off); kfree(buf);
From: Wen Gong wgong@codeaurora.org
[ Upstream commit 402f2992b4d62760cce7c689ff216ea3bf4d6e8a ]
When use command to read values, it crashed.
command: dd if=/sys/kernel/debug/ieee80211/phy0/ath10k/mem_value count=1 bs=4 skip=$((0x100233))
It will call to ath10k_sdio_hif_diag_read with address = 0x4008cc and buf_len = 4.
Then system crash: [ 1786.013258] Unable to handle kernel paging request at virtual address ffffffc00bd45000 [ 1786.013273] Mem abort info: [ 1786.013281] ESR = 0x96000045 [ 1786.013291] Exception class = DABT (current EL), IL = 32 bits [ 1786.013299] SET = 0, FnV = 0 [ 1786.013307] EA = 0, S1PTW = 0 [ 1786.013314] Data abort info: [ 1786.013322] ISV = 0, ISS = 0x00000045 [ 1786.013330] CM = 0, WnR = 1 [ 1786.013342] swapper pgtable: 4k pages, 39-bit VAs, pgdp = 000000008542a60e [ 1786.013350] [ffffffc00bd45000] pgd=0000000000000000, pud=0000000000000000 [ 1786.013368] Internal error: Oops: 96000045 [#1] PREEMPT SMP [ 1786.013609] Process swapper/0 (pid: 0, stack limit = 0x0000000084b153c6) [ 1786.013623] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.19.86 #137 [ 1786.013631] Hardware name: MediaTek krane sku176 board (DT) [ 1786.013643] pstate: 80000085 (Nzcv daIf -PAN -UAO) [ 1786.013662] pc : __memcpy+0x94/0x180 [ 1786.013678] lr : swiotlb_tbl_unmap_single+0x84/0x150 [ 1786.013686] sp : ffffff8008003c60 [ 1786.013694] x29: ffffff8008003c90 x28: ffffffae96411f80 [ 1786.013708] x27: ffffffae960d2018 x26: ffffff8019a4b9a8 [ 1786.013721] x25: 0000000000000000 x24: 0000000000000001 [ 1786.013734] x23: ffffffae96567000 x22: 00000000000051d4 [ 1786.013747] x21: 0000000000000000 x20: 00000000fe6e9000 [ 1786.013760] x19: 0000000000000004 x18: 0000000000000020 [ 1786.013773] x17: 0000000000000001 x16: 0000000000000000 [ 1786.013787] x15: 00000000ffffffff x14: 00000000000044c0 [ 1786.013800] x13: 0000000000365ba4 x12: 0000000000000000 [ 1786.013813] x11: 0000000000000001 x10: 00000037be6e9000 [ 1786.013826] x9 : ffffffc940000000 x8 : 000000000bd45000 [ 1786.013839] x7 : 0000000000000000 x6 : ffffffc00bd45000 [ 1786.013852] x5 : 0000000000000000 x4 : 0000000000000000 [ 1786.013865] x3 : 0000000000000c00 x2 : 0000000000000004 [ 1786.013878] x1 : fffffff7be6e9004 x0 : ffffffc00bd45000 [ 1786.013891] Call trace: [ 1786.013903] __memcpy+0x94/0x180 [ 1786.013914] unmap_single+0x6c/0x84 [ 1786.013925] swiotlb_unmap_sg_attrs+0x54/0x80 [ 1786.013938] __swiotlb_unmap_sg_attrs+0x8c/0xa4 [ 1786.013952] msdc_unprepare_data+0x6c/0x84 [ 1786.013963] msdc_request_done+0x58/0x84 [ 1786.013974] msdc_data_xfer_done+0x1a0/0x1c8 [ 1786.013985] msdc_irq+0x12c/0x17c [ 1786.013996] __handle_irq_event_percpu+0xe4/0x250 [ 1786.014006] handle_irq_event_percpu+0x28/0x68 [ 1786.014015] handle_irq_event+0x48/0x78 [ 1786.014026] handle_fasteoi_irq+0xd0/0x1a0 [ 1786.014039] __handle_domain_irq+0x84/0xc4 [ 1786.014050] gic_handle_irq+0x124/0x1a4 [ 1786.014059] el1_irq+0xb0/0x128 [ 1786.014072] cpuidle_enter_state+0x298/0x328 [ 1786.014082] cpuidle_enter+0x30/0x40 [ 1786.014094] do_idle+0x190/0x268 [ 1786.014104] cpu_startup_entry+0x24/0x28 [ 1786.014116] rest_init+0xd4/0xe0 [ 1786.014126] start_kernel+0x30c/0x38c [ 1786.014139] Code: f8408423 f80084c3 36100062 b8404423 (b80044c3) [ 1786.014150] ---[ end trace 3b02ddb698ea69ee ]--- [ 1786.015415] Kernel panic - not syncing: Fatal exception in interrupt [ 1786.015433] SMP: stopping secondary CPUs [ 1786.015447] Kernel Offset: 0x2e8d200000 from 0xffffff8008000000 [ 1786.015458] CPU features: 0x0,2188200c [ 1786.015466] Memory Limit: none
For sdio chip, it need the memory which is kmalloc, if it is vmalloc from ath10k_mem_value_read, then it have a memory error. kzalloc of ath10k_sdio_hif_diag_read32 is the correct type, so add kzalloc in ath10k_sdio_hif_diag_read to replace the buffer which is vmalloc from ath10k_mem_value_read.
This patch only effect sdio chip.
Tested with QCA6174 SDIO with firmware WLAN.RMH.4.4.1-00029.
Signed-off-by: Wen Gong wgong@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath10k/sdio.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c index 0ecaba824fb28..0cdaecb0e28a9 100644 --- a/drivers/net/wireless/ath/ath10k/sdio.c +++ b/drivers/net/wireless/ath/ath10k/sdio.c @@ -1567,23 +1567,33 @@ static int ath10k_sdio_hif_diag_read(struct ath10k *ar, u32 address, void *buf, size_t buf_len) { int ret; + void *mem; + + mem = kzalloc(buf_len, GFP_KERNEL); + if (!mem) + return -ENOMEM;
/* set window register to start read cycle */ ret = ath10k_sdio_write32(ar, MBOX_WINDOW_READ_ADDR_ADDRESS, address); if (ret) { ath10k_warn(ar, "failed to set mbox window read address: %d", ret); - return ret; + goto out; }
/* read the data */ - ret = ath10k_sdio_read(ar, MBOX_WINDOW_DATA_ADDRESS, buf, buf_len); + ret = ath10k_sdio_read(ar, MBOX_WINDOW_DATA_ADDRESS, mem, buf_len); if (ret) { ath10k_warn(ar, "failed to read from mbox window data address: %d\n", ret); - return ret; + goto out; }
- return 0; + memcpy(buf, mem, buf_len); + +out: + kfree(mem); + + return ret; }
static int ath10k_sdio_hif_diag_read32(struct ath10k *ar, u32 address,
From: Brian Norris briannorris@chromium.org
[ Upstream commit 9454f7a895b822dd8fb4588fc55fda7c96728869 ]
hard_header_len provides limitations for things like AF_PACKET, such that we don't allow transmitting packets smaller than this.
needed_headroom provides a suggested minimum headroom for SKBs, so that we can trivally add our headers to the front.
The latter is the correct field to use in this case, while the former mostly just prevents sending small AF_PACKET frames.
In any case, mwifiex already does its own bounce buffering [1] if we don't have enough headroom, so hints (not hard limits) are all that are needed.
This is the essentially the same bug (and fix) that brcmfmac had, fixed in commit cb39288fd6bb ("brcmfmac: use ndev->needed_headroom to reserve additional header space").
[1] mwifiex_hard_start_xmit(): if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) { [...] /* Insufficient skb headroom - allocate a new skb */
Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver") Signed-off-by: Brian Norris briannorris@chromium.org Acked-by: Ganapathi Bhat ganapathi.gbhat@nxp.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index 7b74ef71bef1d..af59f622c48e8 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -3025,7 +3025,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
dev->flags |= IFF_BROADCAST | IFF_MULTICAST; dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT; - dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN; + dev->needed_headroom = MWIFIEX_MIN_DATA_HEADER_LEN; dev->ethtool_ops = &mwifiex_ethtool_ops;
mdev_priv = netdev_priv(dev);
From: Howard Chung howardchung@google.com
[ Upstream commit 96298f640104e4cd9a913a6e50b0b981829b94ff ]
According to Core Spec Version 5.2 | Vol 3, Part A 6.1.5, the incoming L2CAP_ConfigReq should be handled during OPEN state.
The section below shows the btmon trace when running L2CAP/COS/CFD/BV-12-C before and after this change.
=== Before === ...
ACL Data RX: Handle 256 flags 0x02 dlen 12 #22
L2CAP: Connection Request (0x02) ident 2 len 4 PSM: 1 (0x0001) Source CID: 65 < ACL Data TX: Handle 256 flags 0x00 dlen 16 #23 L2CAP: Connection Response (0x03) ident 2 len 8 Destination CID: 64 Source CID: 65 Result: Connection successful (0x0000) Status: No further information available (0x0000) < ACL Data TX: Handle 256 flags 0x00 dlen 12 #24 L2CAP: Configure Request (0x04) ident 2 len 4 Destination CID: 65 Flags: 0x0000
HCI Event: Number of Completed Packets (0x13) plen 5 #25
Num handles: 1 Handle: 256 Count: 1
HCI Event: Number of Completed Packets (0x13) plen 5 #26
Num handles: 1 Handle: 256 Count: 1
ACL Data RX: Handle 256 flags 0x02 dlen 16 #27
L2CAP: Configure Request (0x04) ident 3 len 8 Destination CID: 64 Flags: 0x0000 Option: Unknown (0x10) [hint] 01 00 .. < ACL Data TX: Handle 256 flags 0x00 dlen 18 #28 L2CAP: Configure Response (0x05) ident 3 len 10 Source CID: 65 Flags: 0x0000 Result: Success (0x0000) Option: Maximum Transmission Unit (0x01) [mandatory] MTU: 672
HCI Event: Number of Completed Packets (0x13) plen 5 #29
Num handles: 1 Handle: 256 Count: 1
ACL Data RX: Handle 256 flags 0x02 dlen 14 #30
L2CAP: Configure Response (0x05) ident 2 len 6 Source CID: 64 Flags: 0x0000 Result: Success (0x0000)
ACL Data RX: Handle 256 flags 0x02 dlen 20 #31
L2CAP: Configure Request (0x04) ident 3 len 12 Destination CID: 64 Flags: 0x0000 Option: Unknown (0x10) [hint] 01 00 91 02 11 11 ...... < ACL Data TX: Handle 256 flags 0x00 dlen 14 #32 L2CAP: Command Reject (0x01) ident 3 len 6 Reason: Invalid CID in request (0x0002) Destination CID: 64 Source CID: 65
HCI Event: Number of Completed Packets (0x13) plen 5 #33
Num handles: 1 Handle: 256 Count: 1 ... === After === ...
ACL Data RX: Handle 256 flags 0x02 dlen 12 #22
L2CAP: Connection Request (0x02) ident 2 len 4 PSM: 1 (0x0001) Source CID: 65 < ACL Data TX: Handle 256 flags 0x00 dlen 16 #23 L2CAP: Connection Response (0x03) ident 2 len 8 Destination CID: 64 Source CID: 65 Result: Connection successful (0x0000) Status: No further information available (0x0000) < ACL Data TX: Handle 256 flags 0x00 dlen 12 #24 L2CAP: Configure Request (0x04) ident 2 len 4 Destination CID: 65 Flags: 0x0000
HCI Event: Number of Completed Packets (0x13) plen 5 #25
Num handles: 1 Handle: 256 Count: 1
HCI Event: Number of Completed Packets (0x13) plen 5 #26
Num handles: 1 Handle: 256 Count: 1
ACL Data RX: Handle 256 flags 0x02 dlen 16 #27
L2CAP: Configure Request (0x04) ident 3 len 8 Destination CID: 64 Flags: 0x0000 Option: Unknown (0x10) [hint] 01 00 .. < ACL Data TX: Handle 256 flags 0x00 dlen 18 #28 L2CAP: Configure Response (0x05) ident 3 len 10 Source CID: 65 Flags: 0x0000 Result: Success (0x0000) Option: Maximum Transmission Unit (0x01) [mandatory] MTU: 672
HCI Event: Number of Completed Packets (0x13) plen 5 #29
Num handles: 1 Handle: 256 Count: 1
ACL Data RX: Handle 256 flags 0x02 dlen 14 #30
L2CAP: Configure Response (0x05) ident 2 len 6 Source CID: 64 Flags: 0x0000 Result: Success (0x0000)
ACL Data RX: Handle 256 flags 0x02 dlen 20 #31
L2CAP: Configure Request (0x04) ident 3 len 12 Destination CID: 64 Flags: 0x0000 Option: Unknown (0x10) [hint] 01 00 91 02 11 11 ..... < ACL Data TX: Handle 256 flags 0x00 dlen 18 #32 L2CAP: Configure Response (0x05) ident 3 len 10 Source CID: 65 Flags: 0x0000 Result: Success (0x0000) Option: Maximum Transmission Unit (0x01) [mandatory] MTU: 672 < ACL Data TX: Handle 256 flags 0x00 dlen 12 #33 L2CAP: Configure Request (0x04) ident 3 len 4 Destination CID: 65 Flags: 0x0000
HCI Event: Number of Completed Packets (0x13) plen 5 #34
Num handles: 1 Handle: 256 Count: 1
HCI Event: Number of Completed Packets (0x13) plen 5 #35
Num handles: 1 Handle: 256 Count: 1 ...
Signed-off-by: Howard Chung howardchung@google.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/l2cap_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 0d84d1f820d4c..3b9af4aba619b 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -4114,7 +4114,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, return 0; }
- if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) { + if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2 && + chan->state != BT_CONNECTED) { cmd_reject_invalid_cid(conn, cmd->ident, chan->scid, chan->dcid); goto unlock;
From: Dmitry Osipenko digetx@gmail.com
[ Upstream commit 0411ea89a689531e1829fdf8af3747646c02c721 ]
Runtime PM and RGB output need to be released when host1x client registration fails. The releasing is missed in the code, let's correct it.
Signed-off-by: Dmitry Osipenko digetx@gmail.com Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/tegra/dc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 965088afcfade..923088626e1f4 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -2420,10 +2420,16 @@ static int tegra_dc_probe(struct platform_device *pdev) if (err < 0) { dev_err(&pdev->dev, "failed to register host1x client: %d\n", err); - return err; + goto disable_pm; }
return 0; + +disable_pm: + pm_runtime_disable(&pdev->dev); + tegra_dc_rgb_remove(dc); + + return err; }
static int tegra_dc_remove(struct platform_device *pdev)
From: Rodrigo Siqueira Rodrigo.Siqueira@amd.com
[ Upstream commit a0e40018dcc3f59a10ca21d58f8ea8ceb1b035ac ]
Raven provides retimer feature support that requires i2c interaction in order to make it work well, all settings required for this configuration are loaded from the Atom bios which include the i2c address. If the retimer feature is not available, we should abort the attempt to set this feature, otherwise, it makes the following line return I2C_CHANNEL_OPERATION_NO_RESPONSE:
i2c_success = i2c_write(pipe_ctx, slave_address, buffer, sizeof(buffer)); ... if (!i2c_success) ASSERT(i2c_success);
This ends up causing problems with hotplugging HDMI displays on Raven, and causes retimer settings to warn like so:
WARNING: CPU: 1 PID: 429 at drivers/gpu/drm/amd/amdgpu/../dal/dc/core/dc_link.c:1998 write_i2c_retimer_setting+0xc2/0x3c0 [amdgpu] Modules linked in: edac_mce_amd ccp kvm irqbypass binfmt_misc crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio snd_hda_codec_hdmi snd_hda_intel amdgpu(+) snd_hda_codec snd_hda_core snd_hwdep snd_pcm snd_seq_midi snd_seq_midi_event snd_rawmidi aesni_intel snd_seq amd_iommu_v2 gpu_sched aes_x86_64 crypto_simd cryptd glue_helper snd_seq_device ttm drm_kms_helper snd_timer eeepc_wmi wmi_bmof asus_wmi sparse_keymap drm mxm_wmi snd k10temp fb_sys_fops syscopyarea sysfillrect sysimgblt soundcore joydev input_leds mac_hid sch_fq_codel parport_pc ppdev lp parport ip_tables x_tables autofs4 igb i2c_algo_bit hid_generic usbhid i2c_piix4 dca ahci hid libahci video wmi gpio_amdpt gpio_generic CPU: 1 PID: 429 Comm: systemd-udevd Tainted: G W 5.2.0-rc1sept162019+ #1 Hardware name: System manufacturer System Product Name/ROG STRIX B450-F GAMING, BIOS 2605 08/06/2019 RIP: 0010:write_i2c_retimer_setting+0xc2/0x3c0 [amdgpu] Code: ff 0f b6 4d ce 44 0f b6 45 cf 44 0f b6 c8 45 89 cf 44 89 e2 48 c7 c6 f0 34 bc c0 bf 04 00 00 00 e8 63 b0 90 ff 45 84 ff 75 02 <0f> 0b 42 0f b6 04 73 8d 50 f6 80 fa 02 77 8c 3c 0a 0f 85 c8 00 00 RSP: 0018:ffffa99d02726fd0 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffffa99d02727035 RCX: 0000000000000006 RDX: 0000000000000000 RSI: 0000000000000002 RDI: ffff976acc857440 RBP: ffffa99d02727018 R08: 0000000000000002 R09: 000000000002a600 R10: ffffe90610193680 R11: 00000000000005e3 R12: 000000000000005d R13: ffff976ac4b201b8 R14: 0000000000000001 R15: 0000000000000000 FS: 00007f14f99e1680(0000) GS:ffff976acc840000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fdf212843b8 CR3: 0000000408906000 CR4: 00000000003406e0 Call Trace: core_link_enable_stream+0x626/0x680 [amdgpu] dce110_apply_ctx_to_hw+0x414/0x4e0 [amdgpu] dc_commit_state+0x331/0x5e0 [amdgpu] ? drm_calc_timestamping_constants+0xf9/0x150 [drm] amdgpu_dm_atomic_commit_tail+0x395/0x1e00 [amdgpu] ? dm_plane_helper_prepare_fb+0x20c/0x280 [amdgpu] commit_tail+0x42/0x70 [drm_kms_helper] drm_atomic_helper_commit+0x10c/0x120 [drm_kms_helper] amdgpu_dm_atomic_commit+0x95/0xa0 [amdgpu] drm_atomic_commit+0x4a/0x50 [drm] restore_fbdev_mode_atomic+0x1c0/0x1e0 [drm_kms_helper] restore_fbdev_mode+0x4c/0x160 [drm_kms_helper] ? _cond_resched+0x19/0x40 drm_fb_helper_restore_fbdev_mode_unlocked+0x4e/0xa0 [drm_kms_helper] drm_fb_helper_set_par+0x2d/0x50 [drm_kms_helper] fbcon_init+0x471/0x630 visual_init+0xd5/0x130 do_bind_con_driver+0x20a/0x430 do_take_over_console+0x7d/0x1b0 do_fbcon_takeover+0x5c/0xb0 fbcon_event_notify+0x6cd/0x8a0 notifier_call_chain+0x4c/0x70 blocking_notifier_call_chain+0x43/0x60 fb_notifier_call_chain+0x1b/0x20 register_framebuffer+0x254/0x360 __drm_fb_helper_initial_config_and_unlock+0x2c5/0x510 [drm_kms_helper] drm_fb_helper_initial_config+0x35/0x40 [drm_kms_helper] amdgpu_fbdev_init+0xcd/0x100 [amdgpu] amdgpu_device_init+0x1156/0x1930 [amdgpu] amdgpu_driver_load_kms+0x8d/0x2e0 [amdgpu] drm_dev_register+0x12b/0x1c0 [drm] amdgpu_pci_probe+0xd3/0x160 [amdgpu] local_pci_probe+0x47/0xa0 pci_device_probe+0x142/0x1b0 really_probe+0xf5/0x3d0 driver_probe_device+0x11b/0x130 device_driver_attach+0x58/0x60 __driver_attach+0xa3/0x140 ? device_driver_attach+0x60/0x60 ? device_driver_attach+0x60/0x60 bus_for_each_dev+0x74/0xb0 ? kmem_cache_alloc_trace+0x1a3/0x1c0 driver_attach+0x1e/0x20 bus_add_driver+0x147/0x220 ? 0xffffffffc0cb9000 driver_register+0x60/0x100 ? 0xffffffffc0cb9000 __pci_register_driver+0x5a/0x60 amdgpu_init+0x74/0x83 [amdgpu] do_one_initcall+0x4a/0x1fa ? _cond_resched+0x19/0x40 ? kmem_cache_alloc_trace+0x3f/0x1c0 ? __vunmap+0x1cc/0x200 do_init_module+0x5f/0x227 load_module+0x2330/0x2b40 __do_sys_finit_module+0xfc/0x120 ? __do_sys_finit_module+0xfc/0x120 __x64_sys_finit_module+0x1a/0x20 do_syscall_64+0x5a/0x130 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x7f14f9500839 Code: 00 f3 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 1f f6 2c 00 f7 d8 64 89 01 48 RSP: 002b:00007fff9bc4f5a8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 RAX: ffffffffffffffda RBX: 000055afb5abce30 RCX: 00007f14f9500839 RDX: 0000000000000000 RSI: 000055afb5ace0f0 RDI: 0000000000000017 RBP: 000055afb5ace0f0 R08: 0000000000000000 R09: 000000000000000a R10: 0000000000000017 R11: 0000000000000246 R12: 0000000000000000 R13: 000055afb5aad800 R14: 0000000000020000 R15: 0000000000000000 ---[ end trace c286e96563966f08 ]---
This commit reworks the way that we handle i2c write for retimer in the way that we abort this configuration if the feature is not available in the device. For debug sake, we kept a simple log message in case the retimer is not available.
Signed-off-by: Rodrigo Siqueira Rodrigo.Siqueira@amd.com Reviewed-by: Hersen Wu hersenxs.wu@amd.com Acked-by: Rodrigo Siqueira Rodrigo.Siqueira@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 67 ++++++++----------- 1 file changed, 29 insertions(+), 38 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 3abc0294c05f5..2fb2c683ad54b 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -1576,8 +1576,7 @@ static void write_i2c_retimer_setting( buffer, sizeof(buffer));
if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail;
/* Based on DP159 specs, APPLY_RX_TX_CHANGE bit in 0x0A * needs to be set to 1 on every 0xA-0xC write. @@ -1595,8 +1594,7 @@ static void write_i2c_retimer_setting( pipe_ctx->stream->sink->link->ddc, slave_address, &offset, 1, &value, 1); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; }
buffer[0] = offset; @@ -1605,8 +1603,7 @@ static void write_i2c_retimer_setting( i2c_success = i2c_write(pipe_ctx, slave_address, buffer, sizeof(buffer)); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; } } } @@ -1623,8 +1620,7 @@ static void write_i2c_retimer_setting( buffer, sizeof(buffer));
if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail;
/* Based on DP159 specs, APPLY_RX_TX_CHANGE bit in 0x0A * needs to be set to 1 on every 0xA-0xC write. @@ -1642,8 +1638,7 @@ static void write_i2c_retimer_setting( pipe_ctx->stream->sink->link->ddc, slave_address, &offset, 1, &value, 1); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; }
buffer[0] = offset; @@ -1652,8 +1647,7 @@ static void write_i2c_retimer_setting( i2c_success = i2c_write(pipe_ctx, slave_address, buffer, sizeof(buffer)); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; } } } @@ -1668,8 +1662,7 @@ static void write_i2c_retimer_setting( i2c_success = i2c_write(pipe_ctx, slave_address, buffer, sizeof(buffer)); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail;
/* Write offset 0x00 to 0x23 */ buffer[0] = 0x00; @@ -1677,8 +1670,7 @@ static void write_i2c_retimer_setting( i2c_success = i2c_write(pipe_ctx, slave_address, buffer, sizeof(buffer)); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail;
/* Write offset 0xff to 0x00 */ buffer[0] = 0xff; @@ -1686,10 +1678,14 @@ static void write_i2c_retimer_setting( i2c_success = i2c_write(pipe_ctx, slave_address, buffer, sizeof(buffer)); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail;
} + + return; + +i2c_write_fail: + DC_LOG_DEBUG("Set retimer failed"); }
static void write_i2c_default_retimer_setting( @@ -1710,8 +1706,7 @@ static void write_i2c_default_retimer_setting( i2c_success = i2c_write(pipe_ctx, slave_address, buffer, sizeof(buffer)); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail;
/* Write offset 0x0A to 0x17 */ buffer[0] = 0x0A; @@ -1719,8 +1714,7 @@ static void write_i2c_default_retimer_setting( i2c_success = i2c_write(pipe_ctx, slave_address, buffer, sizeof(buffer)); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail;
/* Write offset 0x0B to 0xDA or 0xD8 */ buffer[0] = 0x0B; @@ -1728,8 +1722,7 @@ static void write_i2c_default_retimer_setting( i2c_success = i2c_write(pipe_ctx, slave_address, buffer, sizeof(buffer)); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail;
/* Write offset 0x0A to 0x17 */ buffer[0] = 0x0A; @@ -1737,8 +1730,7 @@ static void write_i2c_default_retimer_setting( i2c_success = i2c_write(pipe_ctx, slave_address, buffer, sizeof(buffer)); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail;
/* Write offset 0x0C to 0x1D or 0x91 */ buffer[0] = 0x0C; @@ -1746,8 +1738,7 @@ static void write_i2c_default_retimer_setting( i2c_success = i2c_write(pipe_ctx, slave_address, buffer, sizeof(buffer)); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail;
/* Write offset 0x0A to 0x17 */ buffer[0] = 0x0A; @@ -1755,8 +1746,7 @@ static void write_i2c_default_retimer_setting( i2c_success = i2c_write(pipe_ctx, slave_address, buffer, sizeof(buffer)); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail;
if (is_vga_mode) { @@ -1768,8 +1758,7 @@ static void write_i2c_default_retimer_setting( i2c_success = i2c_write(pipe_ctx, slave_address, buffer, sizeof(buffer)); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail;
/* Write offset 0x00 to 0x23 */ buffer[0] = 0x00; @@ -1777,8 +1766,7 @@ static void write_i2c_default_retimer_setting( i2c_success = i2c_write(pipe_ctx, slave_address, buffer, sizeof(buffer)); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail;
/* Write offset 0xff to 0x00 */ buffer[0] = 0xff; @@ -1786,9 +1774,13 @@ static void write_i2c_default_retimer_setting( i2c_success = i2c_write(pipe_ctx, slave_address, buffer, sizeof(buffer)); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; } + + return; + +i2c_write_fail: + DC_LOG_DEBUG("Set default retimer failed"); }
static void write_i2c_redriver_setting( @@ -1811,8 +1803,7 @@ static void write_i2c_redriver_setting( buffer, sizeof(buffer));
if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + DC_LOG_DEBUG("Set redriver failed"); }
static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
From: Vlad Buslov vladbu@mellanox.com
[ Upstream commit 6783e8b29f636383af293a55336f036bc7ad5619 ]
During transition to uplink representors the code responsible for initializing ethtool steering functionality wasn't added to representor init rx routine. This causes NULL pointer dereference during configuration of network flow classification rule with ethtool (only possible to reproduce with next commit in this series which registers necessary ethtool callbacks).
Signed-off-by: Vlad Buslov vladbu@mellanox.com Reviewed-by: Roi Dayan roid@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 701624a63d2f4..d70af8a8e8b48 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -1022,6 +1022,8 @@ static int mlx5e_init_rep_rx(struct mlx5e_priv *priv) } rpriv->vport_rx_rule = flow_rule;
+ mlx5e_ethtool_init_steering(priv); + return 0;
err_destroy_direct_tirs:
From: Martin Leung martin.leung@amd.com
[ Upstream commit e592e85f3378246dd66b861fa60ef803d8cece6b ]
[why] on some displays that prefer swapped polarity we were seeing L/R images swapped because OTG_STEREO_SYNC_OUTPUT_POLARITY would always be mapped to 0
[how] fix initial dal3 implementation to properly update the polarity field according to the crtc_stereo_flags (same as OTG_STEREO_EYE_FLAG_POLARITY)
Signed-off-by: Martin Leung martin.leung@amd.com Reviewed-by: Aric Cyr Aric.Cyr@amd.com Acked-by: Rodrigo Siqueira Rodrigo.Siqueira@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c index 411f89218e019..ff3a87c9d5194 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c @@ -1161,7 +1161,7 @@ static void optc1_enable_stereo(struct timing_generator *optc, REG_UPDATE_3(OTG_STEREO_CONTROL, OTG_STEREO_EN, stereo_en, OTG_STEREO_SYNC_OUTPUT_LINE_NUM, 0, - OTG_STEREO_SYNC_OUTPUT_POLARITY, 0); + OTG_STEREO_SYNC_OUTPUT_POLARITY, flags->RIGHT_EYE_POLARITY == 0 ? 0 : 1);
if (flags->PROGRAM_POLARITY) REG_UPDATE(OTG_STEREO_CONTROL,
From: Marcel Holtmann marcel@holtmann.org
[ Upstream commit debdedf2eb5a2d9777cabff40900772be13cd9f9 ]
When processing SCO packets, the handle is wrongly assumed as 16-bit value. The actual size is 12-bits and the other 4-bits are used for packet flags.
Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Johan Hedberg johan.hedberg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/hci_core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index e03faca84919e..99c2685b6c89d 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -4190,13 +4190,16 @@ static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_sco_hdr *hdr = (void *) skb->data; struct hci_conn *conn; - __u16 handle; + __u16 handle, flags;
skb_pull(skb, HCI_SCO_HDR_SIZE);
handle = __le16_to_cpu(hdr->handle); + flags = hci_flags(handle); + handle = hci_handle(handle);
- BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); + BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, + handle, flags);
hdev->stat.sco_rx++;
From: Taehee Yoo ap420073@gmail.com
[ Upstream commit eed22a0685d651fc531bc63f215bb2a71d4b98e5 ]
In the current rmnet code, there is no module alias. So, RTNL couldn't load rmnet module automatically.
Test commands: ip link add dummy0 type dummy modprobe -rv rmnet ip link add rmnet0 link dummy0 type rmnet mux_id 1
Signed-off-by: Taehee Yoo ap420073@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c index 37786affa9750..d452cb773287f 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c @@ -484,4 +484,5 @@ static void __exit rmnet_exit(void)
module_init(rmnet_init) module_exit(rmnet_exit) +MODULE_ALIAS_RTNL_LINK("rmnet"); MODULE_LICENSE("GPL v2");
From: Eric Bernstein eric.bernstein@amd.com
[ Upstream commit ccb6af1e25830e5601b6beacc698390f0245316f ]
[Why] Logger mask was updated to uint64_t, however default mask definition was not updated for unsigned long long
[How] Update DC_DEFAULT_LOG_MASK to support uint64_t type
Signed-off-by: Eric Bernstein eric.bernstein@amd.com Reviewed-by: Dmytro Laktyushkin Dmytro.Laktyushkin@amd.com Acked-by: Rodrigo Siqueira Rodrigo.Siqueira@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../drm/amd/display/include/logger_types.h | 63 ++++++++++--------- 1 file changed, 32 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/include/logger_types.h b/drivers/gpu/drm/amd/display/include/logger_types.h index ad3695e67b76f..dbc5a4d6d2e3f 100644 --- a/drivers/gpu/drm/amd/display/include/logger_types.h +++ b/drivers/gpu/drm/amd/display/include/logger_types.h @@ -106,36 +106,37 @@ enum dc_log_type { #define DC_MIN_LOG_MASK ((1 << LOG_ERROR) | \ (1 << LOG_DETECTION_EDID_PARSER))
-#define DC_DEFAULT_LOG_MASK ((1 << LOG_ERROR) | \ - (1 << LOG_WARNING) | \ - (1 << LOG_EVENT_MODE_SET) | \ - (1 << LOG_EVENT_DETECTION) | \ - (1 << LOG_EVENT_LINK_TRAINING) | \ - (1 << LOG_EVENT_LINK_LOSS) | \ - (1 << LOG_EVENT_UNDERFLOW) | \ - (1 << LOG_RESOURCE) | \ - (1 << LOG_FEATURE_OVERRIDE) | \ - (1 << LOG_DETECTION_EDID_PARSER) | \ - (1 << LOG_DC) | \ - (1 << LOG_HW_HOTPLUG) | \ - (1 << LOG_HW_SET_MODE) | \ - (1 << LOG_HW_RESUME_S3) | \ - (1 << LOG_HW_HPD_IRQ) | \ - (1 << LOG_SYNC) | \ - (1 << LOG_BANDWIDTH_VALIDATION) | \ - (1 << LOG_MST) | \ - (1 << LOG_DETECTION_DP_CAPS) | \ - (1 << LOG_BACKLIGHT)) | \ - (1 << LOG_I2C_AUX) | \ - (1 << LOG_IF_TRACE) | \ - (1 << LOG_DTN) /* | \ - (1 << LOG_DEBUG) | \ - (1 << LOG_BIOS) | \ - (1 << LOG_SURFACE) | \ - (1 << LOG_SCALER) | \ - (1 << LOG_DML) | \ - (1 << LOG_HW_LINK_TRAINING) | \ - (1 << LOG_HW_AUDIO)| \ - (1 << LOG_BANDWIDTH_CALCS)*/ +#define DC_DEFAULT_LOG_MASK ((1ULL << LOG_ERROR) | \ + (1ULL << LOG_WARNING) | \ + (1ULL << LOG_EVENT_MODE_SET) | \ + (1ULL << LOG_EVENT_DETECTION) | \ + (1ULL << LOG_EVENT_LINK_TRAINING) | \ + (1ULL << LOG_EVENT_LINK_LOSS) | \ + (1ULL << LOG_EVENT_UNDERFLOW) | \ + (1ULL << LOG_RESOURCE) | \ + (1ULL << LOG_FEATURE_OVERRIDE) | \ + (1ULL << LOG_DETECTION_EDID_PARSER) | \ + (1ULL << LOG_DC) | \ + (1ULL << LOG_HW_HOTPLUG) | \ + (1ULL << LOG_HW_SET_MODE) | \ + (1ULL << LOG_HW_RESUME_S3) | \ + (1ULL << LOG_HW_HPD_IRQ) | \ + (1ULL << LOG_SYNC) | \ + (1ULL << LOG_BANDWIDTH_VALIDATION) | \ + (1ULL << LOG_MST) | \ + (1ULL << LOG_DETECTION_DP_CAPS) | \ + (1ULL << LOG_BACKLIGHT)) | \ + (1ULL << LOG_I2C_AUX) | \ + (1ULL << LOG_IF_TRACE) | \ + (1ULL << LOG_HDMI_FRL) | \ + (1ULL << LOG_DTN) /* | \ + (1ULL << LOG_DEBUG) | \ + (1ULL << LOG_BIOS) | \ + (1ULL << LOG_SURFACE) | \ + (1ULL << LOG_SCALER) | \ + (1ULL << LOG_DML) | \ + (1ULL << LOG_HW_LINK_TRAINING) | \ + (1ULL << LOG_HW_AUDIO)| \ + (1ULL << LOG_BANDWIDTH_CALCS)*/
#endif /* __DAL_LOGGER_TYPES_H__ */
From: Parav Pandit parav@mellanox.com
[ Upstream commit 79db784e794b6e7b7fb9b1dd464a34e4c0c039af ]
Cited commit missed to include low level congestion control related debugfs stage initialization. This resulted in missing debugfs entries for cc_params of a RDMA device.
Add them back.
Fixes: b5ca15ad7e61 ("IB/mlx5: Add proper representors support") Link: https://lore.kernel.org/r/20200227125407.99803-1-leon@kernel.org Signed-off-by: Parav Pandit parav@mellanox.com Reviewed-by: Mark Bloch markb@mellanox.com Signed-off-by: Leon Romanovsky leonro@mellanox.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/mlx5/main.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 2db34f7b5ced1..c9983838e3493 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -6288,6 +6288,9 @@ static const struct mlx5_ib_profile nic_rep_profile = { STAGE_CREATE(MLX5_IB_STAGE_COUNTERS, mlx5_ib_stage_counters_init, mlx5_ib_stage_counters_cleanup), + STAGE_CREATE(MLX5_IB_STAGE_CONG_DEBUGFS, + mlx5_ib_stage_cong_debugfs_init, + mlx5_ib_stage_cong_debugfs_cleanup), STAGE_CREATE(MLX5_IB_STAGE_UAR, mlx5_ib_stage_uar_init, mlx5_ib_stage_uar_cleanup),
From: Alain Michaud alainm@chromium.org
[ Upstream commit 08bb4da90150e2a225f35e0f642cdc463958d696 ]
Some controllers have been observed to send zero'd events under some conditions. This change guards against this condition as well as adding a trace to facilitate diagnosability of this condition.
Signed-off-by: Alain Michaud alainm@chromium.org Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/hci_event.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 3e7badb3ac2d5..93d077328c6ab 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -5718,6 +5718,11 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) u8 status = 0, event = hdr->evt, req_evt = 0; u16 opcode = HCI_OP_NOP;
+ if (!event) { + bt_dev_warn(hdev, "Received unexpected HCI Event 00000000"); + goto done; + } + if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->hci.req_event == event) { struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data; opcode = __le16_to_cpu(cmd_hdr->opcode); @@ -5929,6 +5934,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) req_complete_skb(hdev, status, opcode, orig_skb); }
+done: kfree_skb(orig_skb); kfree_skb(skb); hdev->stat.evt_rx++;
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit ff462ddfd95b915345c3c7c037c3bfafdc58bae7 ]
kctx_len = (ntohl(KEY_CONTEXT_CTX_LEN_V(aeadctx->key_ctx_hdr)) << 4) - sizeof(chcr_req->key_ctx); can't possibly be endian-safe. Look: ->key_ctx_hdr is __be32. And KEY_CONTEXT_CTX_LEN_V is "shift up by 24 bits". On little-endian hosts it sees b0 b1 b2 b3 in memory, inteprets that into b0 + (b1 << 8) + (b2 << 16) + (b3 << 24), shifts up by 24, resulting in b0 << 24, does ntohl (byteswap on l-e), gets b0 and shifts that up by 4. So we get b0 * 16 - sizeof(...).
Sounds reasonable, but on b-e we get b3 + (b2 << 8) + (b1 << 16) + (b0 << 24), shift up by 24, yielding b3 << 24, do ntohl (no-op on b-e) and then shift up by 4. Resulting in b3 << 28 - sizeof(...), i.e. slightly under b3 * 256M.
Then we increase it some more and pass to alloc_skb() as size. Somehow I doubt that we really want a quarter-gigabyte skb allocation here...
Note that when you are building those values in #define FILL_KEY_CTX_HDR(ck_size, mk_size, d_ck, opad, ctx_len) \ htonl(KEY_CONTEXT_VALID_V(1) | \ KEY_CONTEXT_CK_SIZE_V((ck_size)) | \ KEY_CONTEXT_MK_SIZE_V(mk_size) | \ KEY_CONTEXT_DUAL_CK_V((d_ck)) | \ KEY_CONTEXT_OPAD_PRESENT_V((opad)) | \ KEY_CONTEXT_SALT_PRESENT_V(1) | \ KEY_CONTEXT_CTX_LEN_V((ctx_len))) ctx_len ends up in the first octet (i.e. b0 in the above), which matches the current behaviour on l-e. If that's the intent, this thing should've been kctx_len = (KEY_CONTEXT_CTX_LEN_G(ntohl(aeadctx->key_ctx_hdr)) << 4) - sizeof(chcr_req->key_ctx); instead - fetch after ntohl() we get (b0 << 24) + (b1 << 16) + (b2 << 8) + b3, shift it down by 24 (b0), resuling in b0 * 16 - sizeof(...) both on l-e and on b-e.
PS: when sparse warns you about endianness problems, it might be worth checking if there really is something wrong. And I don't mean "slap __force cast on it"...
Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/chelsio/chcr_algo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/chelsio/chcr_algo.c b/drivers/crypto/chelsio/chcr_algo.c index c435f89f34e37..8b68ccc137c53 100644 --- a/drivers/crypto/chelsio/chcr_algo.c +++ b/drivers/crypto/chelsio/chcr_algo.c @@ -2298,7 +2298,7 @@ static struct sk_buff *create_authenc_wr(struct aead_request *req, dnents += MIN_AUTH_SG; // For IV
dst_size = get_space_for_phys_dsgl(dnents); - kctx_len = (ntohl(KEY_CONTEXT_CTX_LEN_V(aeadctx->key_ctx_hdr)) << 4) + kctx_len = (KEY_CONTEXT_CTX_LEN_G(ntohl(aeadctx->key_ctx_hdr)) << 4) - sizeof(chcr_req->key_ctx); transhdr_len = CIPHER_TRANSHDR_SIZE(kctx_len, dst_size); reqctx->imm = (transhdr_len + assoclen + IV + req->cryptlen) <
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit fb3063d31995cc4cf1d47a406bb61d6fb1b1d58d ]
From the comment above the definition of the roundup_pow_of_two() macro:
The result is undefined when n == 0.
Hence only pass positive values to roundup_pow_of_two(). This patch fixes the following UBSAN complaint:
UBSAN: Undefined behaviour in ./include/linux/log2.h:57:13 shift exponent 64 is too large for 64-bit type 'long unsigned int' Call Trace: dump_stack+0xa5/0xe6 ubsan_epilogue+0x9/0x26 __ubsan_handle_shift_out_of_bounds.cold+0x4c/0xf9 rxe_qp_from_attr.cold+0x37/0x5d [rdma_rxe] rxe_modify_qp+0x59/0x70 [rdma_rxe] _ib_modify_qp+0x5aa/0x7c0 [ib_core] ib_modify_qp+0x3b/0x50 [ib_core] cma_modify_qp_rtr+0x234/0x260 [rdma_cm] __rdma_accept+0x1a7/0x650 [rdma_cm] nvmet_rdma_cm_handler+0x1286/0x14cd [nvmet_rdma] cma_cm_event_handler+0x6b/0x330 [rdma_cm] cma_ib_req_handler+0xe60/0x22d0 [rdma_cm] cm_process_work+0x30/0x140 [ib_cm] cm_req_handler+0x11f4/0x1cd0 [ib_cm] cm_work_handler+0xb8/0x344e [ib_cm] process_one_work+0x569/0xb60 worker_thread+0x7a/0x5d0 kthread+0x1e6/0x210 ret_from_fork+0x24/0x30
Link: https://lore.kernel.org/r/20200217205714.26937-1-bvanassche@acm.org Fixes: 8700e3e7c485 ("Soft RoCE driver") Signed-off-by: Bart Van Assche bvanassche@acm.org Reviewed-by: Leon Romanovsky leonro@mellanox.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rxe/rxe_qp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c index 230697fa31fe3..8a22ab8b29e9b 100644 --- a/drivers/infiniband/sw/rxe/rxe_qp.c +++ b/drivers/infiniband/sw/rxe/rxe_qp.c @@ -583,15 +583,16 @@ int rxe_qp_from_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask, int err;
if (mask & IB_QP_MAX_QP_RD_ATOMIC) { - int max_rd_atomic = __roundup_pow_of_two(attr->max_rd_atomic); + int max_rd_atomic = attr->max_rd_atomic ? + roundup_pow_of_two(attr->max_rd_atomic) : 0;
qp->attr.max_rd_atomic = max_rd_atomic; atomic_set(&qp->req.rd_atomic, max_rd_atomic); }
if (mask & IB_QP_MAX_DEST_RD_ATOMIC) { - int max_dest_rd_atomic = - __roundup_pow_of_two(attr->max_dest_rd_atomic); + int max_dest_rd_atomic = attr->max_dest_rd_atomic ? + roundup_pow_of_two(attr->max_dest_rd_atomic) : 0;
qp->attr.max_dest_rd_atomic = max_dest_rd_atomic;
From: Jia-Ju Bai baijiaju1990@gmail.com
[ Upstream commit 2e05f756c7099c8991142382648a37b0d4c85943 ]
The driver may sleep while holding a spinlock. The function call path (from bottom to top) in Linux 4.19 is:
drivers/net/ethernet/intel/e1000e/mac.c, 1366: usleep_range in e1000e_get_hw_semaphore drivers/net/ethernet/intel/e1000e/80003es2lan.c, 322: e1000e_get_hw_semaphore in e1000_release_swfw_sync_80003es2lan drivers/net/ethernet/intel/e1000e/80003es2lan.c, 197: e1000_release_swfw_sync_80003es2lan in e1000_release_phy_80003es2lan drivers/net/ethernet/intel/e1000e/netdev.c, 4883: (FUNC_PTR) e1000_release_phy_80003es2lan in e1000e_update_phy_stats drivers/net/ethernet/intel/e1000e/netdev.c, 4917: e1000e_update_phy_stats in e1000e_update_stats drivers/net/ethernet/intel/e1000e/netdev.c, 5945: e1000e_update_stats in e1000e_get_stats64 drivers/net/ethernet/intel/e1000e/netdev.c, 5944: spin_lock in e1000e_get_stats64
drivers/net/ethernet/intel/e1000e/mac.c, 1384: usleep_range in e1000e_get_hw_semaphore drivers/net/ethernet/intel/e1000e/80003es2lan.c, 322: e1000e_get_hw_semaphore in e1000_release_swfw_sync_80003es2lan drivers/net/ethernet/intel/e1000e/80003es2lan.c, 197: e1000_release_swfw_sync_80003es2lan in e1000_release_phy_80003es2lan drivers/net/ethernet/intel/e1000e/netdev.c, 4883: (FUNC_PTR) e1000_release_phy_80003es2lan in e1000e_update_phy_stats drivers/net/ethernet/intel/e1000e/netdev.c, 4917: e1000e_update_phy_stats in e1000e_update_stats drivers/net/ethernet/intel/e1000e/netdev.c, 5945: e1000e_update_stats in e1000e_get_stats64 drivers/net/ethernet/intel/e1000e/netdev.c, 5944: spin_lock in e1000e_get_stats64
(FUNC_PTR) means a function pointer is called.
To fix these bugs, usleep_range() is replaced with udelay().
These bugs are found by a static analysis tool STCheck written by myself.
Signed-off-by: Jia-Ju Bai baijiaju1990@gmail.com Tested-by: Aaron Brown aaron.f.brown@intel.com Signed-off-by: Jeff Kirsher jeffrey.t.kirsher@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/e1000e/mac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c index 4abd55d646c55..356fd19ed8b68 100644 --- a/drivers/net/ethernet/intel/e1000e/mac.c +++ b/drivers/net/ethernet/intel/e1000e/mac.c @@ -1363,7 +1363,7 @@ s32 e1000e_get_hw_semaphore(struct e1000_hw *hw) if (!(swsm & E1000_SWSM_SMBI)) break;
- usleep_range(50, 100); + udelay(100); i++; }
@@ -1381,7 +1381,7 @@ s32 e1000e_get_hw_semaphore(struct e1000_hw *hw) if (er32(SWSM) & E1000_SWSM_SWESMBI) break;
- usleep_range(50, 100); + udelay(100); }
if (i == timeout) {
From: Florian Fainelli f.fainelli@gmail.com
[ Upstream commit 7458bd540fa0a90220b9e8c349d910d9dde9caf8 ]
Either port 5 or port 8 can be used on a 7278 device, make sure that port 5 also gets configured properly for 2Gb/sec in that case.
Signed-off-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/dsa/bcm_sf2.c | 3 +++ drivers/net/dsa/bcm_sf2_regs.h | 1 + 2 files changed, 4 insertions(+)
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index 8c69789fbe094..a5a83955a7cff 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c @@ -599,6 +599,9 @@ static void bcm_sf2_sw_mac_config(struct dsa_switch *ds, int port, if (state->duplex == DUPLEX_FULL) reg |= DUPLX_MODE;
+ if (priv->type == BCM7278_DEVICE_ID && dsa_is_cpu_port(ds, port)) + reg |= GMIIP_SPEED_UP_2G; + core_writel(priv, reg, offset); }
diff --git a/drivers/net/dsa/bcm_sf2_regs.h b/drivers/net/dsa/bcm_sf2_regs.h index 0a1e530d52b72..c389702f07ccf 100644 --- a/drivers/net/dsa/bcm_sf2_regs.h +++ b/drivers/net/dsa/bcm_sf2_regs.h @@ -182,6 +182,7 @@ enum bcm_sf2_reg_offs { #define RXFLOW_CNTL (1 << 4) #define TXFLOW_CNTL (1 << 5) #define SW_OVERRIDE (1 << 6) +#define GMIIP_SPEED_UP_2G (1 << 7)
#define CORE_WATCHDOG_CTRL 0x001e4 #define SOFTWARE_RESET (1 << 7)
On 4/11/2020 4:11 PM, Sasha Levin wrote:
From: Florian Fainelli f.fainelli@gmail.com
[ Upstream commit 7458bd540fa0a90220b9e8c349d910d9dde9caf8 ]
Either port 5 or port 8 can be used on a 7278 device, make sure that port 5 also gets configured properly for 2Gb/sec in that case.
This was later reverted with:
3f02735e5da5367e4cd563ce6e5c21ce27922248 ("Revert "net: dsa: bcm_sf2: Also configure Port 5 for 2Gb/sec on 7278") please drop it from this selection.
From: Sergei Shtylyov sergei.shtylyov@cogentembedded.com
[ Upstream commit 6eaeedc1aa27a423bd89043705eca39215015bb3 ]
When adding the sh_eth_cpu_data::no_tx_cntrs flag I forgot to add the flag check to __sh_eth_get_regs(), causing the non-existing TX counter registers to be considered for dumping on the R7S72100 SoC (the register offset sanity check has the final say here)...
Fixes: ce9134dff6d9 ("sh_eth: add sh_eth_cpu_data::no_tx_cntrs flag") Signed-off-by: Sergei Shtylyov sergei.shtylyov@cogentembedded.com Tested-by: Chris Brandt chris.brandt@renesas.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/renesas/sh_eth.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 441643670ac0e..9e735b52b85fb 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2164,10 +2164,12 @@ static size_t __sh_eth_get_regs(struct net_device *ndev, u32 *buf) add_reg(BCULR); add_reg(MAHR); add_reg(MALR); - add_reg(TROCR); - add_reg(CDCR); - add_reg(LCCR); - add_reg(CNDCR); + if (!cd->no_tx_cntrs) { + add_reg(TROCR); + add_reg(CDCR); + add_reg(LCCR); + add_reg(CNDCR); + } add_reg(CEFCR); add_reg(FRECR); add_reg(TSFRCR);
From: Sergei Shtylyov sergei.shtylyov@cogentembedded.com
[ Upstream commit f75ca32403dbf91e20c275719aab705401b9e718 ]
When adding the sh_eth_cpu_data::cexcr flag I forgot to add the flag check to __sh_eth_get_regs(), causing the non-existing RX packet counter registers to be considered for dumping on the R7S72100 SoC (the register offset sanity check has the final say here)...
Fixes: 4c1d45850d5 ("sh_eth: add sh_eth_cpu_data::cexcr flag") Signed-off-by: Sergei Shtylyov sergei.shtylyov@cogentembedded.com Tested-by: Chris Brandt chris.brandt@renesas.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/renesas/sh_eth.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 9e735b52b85fb..7d3207d2d6d6d 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2174,8 +2174,10 @@ static size_t __sh_eth_get_regs(struct net_device *ndev, u32 *buf) add_reg(FRECR); add_reg(TSFRCR); add_reg(TLFRCR); - add_reg(CERCR); - add_reg(CEECR); + if (cd->cexcr) { + add_reg(CERCR); + add_reg(CEECR); + } add_reg(MAFCR); if (cd->rtrate) add_reg(RTRATE);
From: Sergei Shtylyov sergei.shtylyov@cogentembedded.com
[ Upstream commit 7bf47f609f7eaac4f7e9c407a85ad78997288a38 ]
When adding the sh_eth_cpu_data::no_xdfar flag I forgot to add the flag check to __sh_eth_get_regs(), causing the non-existing RDFAR/TDFAR to be considered for dumping on the R-Car gen1/2 SoCs (the register offset check has the final say here)...
Fixes: 4c1d45850d5 ("sh_eth: add sh_eth_cpu_data::cexcr flag") Signed-off-by: Sergei Shtylyov sergei.shtylyov@cogentembedded.com Tested-by: Chris Brandt chris.brandt@renesas.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/renesas/sh_eth.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 7d3207d2d6d6d..14e39a41d475d 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2120,11 +2120,13 @@ static size_t __sh_eth_get_regs(struct net_device *ndev, u32 *buf) add_reg(EESR); add_reg(EESIPR); add_reg(TDLAR); - add_reg(TDFAR); + if (!cd->no_xdfar) + add_reg(TDFAR); add_reg(TDFXR); add_reg(TDFFR); add_reg(RDLAR); - add_reg(RDFAR); + if (!cd->no_xdfar) + add_reg(RDFAR); add_reg(RDFXR); add_reg(RDFFR); add_reg(TRSCER);
From: Samuel Holland samuel@sholland.org
[ Upstream commit 0e4e3fb4901d19f49e5c0a582f383b10dda8d1c5 ]
The continued use of an ERR_PTR to signify "no panel" outside of sun6i_dsi_attach is confusing because it is a double negative. Because the connector always reports itself as connected, there is also the possibility of sending an ERR_PTR to drm_panel_get_modes(), which would crash.
Solve both of these by only storing the panel pointer if it is valid.
Fixes: 133add5b5ad4 ("drm/sun4i: Add Allwinner A31 MIPI-DSI controller support") Signed-off-by: Samuel Holland samuel@sholland.org Signed-off-by: Maxime Ripard maxime@cerno.tech Link: https://patchwork.freedesktop.org/patch/msgid/20200211072858.30784-2-samuel@... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c index 79eb11cd185d1..bc9454a562877 100644 --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c @@ -642,7 +642,7 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder) sun6i_dphy_init(dsi->dphy, device->lanes); sun6i_dphy_power_on(dsi->dphy, device->lanes);
- if (!IS_ERR(dsi->panel)) + if (dsi->panel) drm_panel_prepare(dsi->panel);
/* @@ -657,7 +657,7 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder) * ordering on the panels I've tested it with, so I guess this * will do for now, until that IP is better understood. */ - if (!IS_ERR(dsi->panel)) + if (dsi->panel) drm_panel_enable(dsi->panel);
sun6i_dsi_start(dsi, DSI_START_HSC); @@ -673,7 +673,7 @@ static void sun6i_dsi_encoder_disable(struct drm_encoder *encoder)
DRM_DEBUG_DRIVER("Disabling DSI output\n");
- if (!IS_ERR(dsi->panel)) { + if (dsi->panel) { drm_panel_disable(dsi->panel); drm_panel_unprepare(dsi->panel); } @@ -835,11 +835,13 @@ static int sun6i_dsi_attach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { struct sun6i_dsi *dsi = host_to_sun6i_dsi(host); + struct drm_panel *panel = of_drm_find_panel(device->dev.of_node);
+ if (IS_ERR(panel)) + return PTR_ERR(panel); + + dsi->panel = panel; dsi->device = device; - dsi->panel = of_drm_find_panel(device->dev.of_node); - if (IS_ERR(dsi->panel)) - return PTR_ERR(dsi->panel);
dev_info(host->dev, "Attached device %s\n", device->name);
From: Ayush Sawal ayush.sawal@chelsio.com
[ Upstream commit 9195189e00a7db55e7d448cee973cae87c5a3c71 ]
The libkcapi test which causes kernel panic is aead asynchronous vmsplice multiple test.
./bin/kcapi -v -d 4 -x 10 -c "ccm(aes)" -q 4edb58e8d5eb6bc711c43a6f3693daebde2e5524f1b55297abb29f003236e43d -t a7877c99 -n 674742abd0f5ba -k 2861fd0253705d7875c95ba8a53171b4 -a fb7bc304a3909e66e2e0c5ef952712dd884ce3e7324171369f2c5db1adc48c7d
This patch avoids dma_mapping of a zero length sg which causes the panic, by using sg_nents_for_len which maps only upto a specific length
Signed-off-by: Ayush Sawal ayush.sawal@chelsio.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/chelsio/chcr_algo.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/chelsio/chcr_algo.c b/drivers/crypto/chelsio/chcr_algo.c index 8b68ccc137c53..796206faabec9 100644 --- a/drivers/crypto/chelsio/chcr_algo.c +++ b/drivers/crypto/chelsio/chcr_algo.c @@ -2418,8 +2418,9 @@ int chcr_aead_dma_map(struct device *dev, else reqctx->b0_dma = 0; if (req->src == req->dst) { - error = dma_map_sg(dev, req->src, sg_nents(req->src), - DMA_BIDIRECTIONAL); + error = dma_map_sg(dev, req->src, + sg_nents_for_len(req->src, dst_size), + DMA_BIDIRECTIONAL); if (!error) goto err; } else {
From: Horia Geantă horia.geanta@nxp.com
[ Upstream commit 8e3b7fd7ea554ccb1bdc596bfbcdaf56f7ab017c ]
When running tcrypt skcipher speed tests, logs contain things like: testing speed of async ecb(des3_ede) (ecb(des3_ede-generic)) encryption or: testing speed of async ecb(aes) (ecb(aes-ce)) encryption
The algorithm implementations are sync, not async. Fix this inaccuracy.
Fixes: 7166e589da5b6 ("crypto: tcrypt - Use skcipher") Signed-off-by: Horia Geantă horia.geanta@nxp.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- crypto/tcrypt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index d332988eb8dea..f1618c745c180 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -1518,8 +1518,8 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs, return; }
- pr_info("\ntesting speed of async %s (%s) %s\n", algo, - get_driver_name(crypto_skcipher, tfm), e); + pr_info("\ntesting speed of %s %s (%s) %s\n", async ? "async" : "sync", + algo, get_driver_name(crypto_skcipher, tfm), e);
req = skcipher_request_alloc(tfm, GFP_KERNEL); if (!req) {
From: Wen Yang wen.yang99@zte.com.cn
[ Upstream commit 47340e46f34a3b1d80e40b43ae3d7a8da34a3541 ]
The call to of_find_matching_node returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage.
Detected by coccinelle with the following warnings: drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c:212:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 209, but without a corresponding object release within this function. drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c:237:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 209, but without a corresponding object release within this function.
Signed-off-by: Wen Yang wen.yang99@zte.com.cn Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Reviewed-by: Mukesh Ojha mojha@codeaurora.org Cc: Tomi Valkeinen tomi.valkeinen@ti.com Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Cc: Sebastian Reichel sebastian.reichel@collabora.com Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com Cc: dri-devel@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Cc: Markus Elfring Markus.Elfring@web.de Signed-off-by: Tomi Valkeinen tomi.valkeinen@ti.com Link: https://patchwork.freedesktop.org/patch/msgid/1554692313-28882-2-git-send-em... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c b/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c index 3bfb95d230e0e..d8fb686c1fda9 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c +++ b/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c @@ -193,7 +193,7 @@ static int __init omapdss_boot_init(void) dss = of_find_matching_node(NULL, omapdss_of_match);
if (dss == NULL || !of_device_is_available(dss)) - return 0; + goto put_node;
omapdss_walk_device(dss, true);
@@ -218,6 +218,8 @@ static int __init omapdss_boot_init(void) kfree(n); }
+put_node: + of_node_put(dss); return 0; }
From: Steve Grubb sgrubb@redhat.com
[ Upstream commit 70b3eeed49e8190d97139806f6fbaf8964306cdb ]
Common Criteria calls out for any action that modifies the audit trail to be recorded. That usually is interpreted to mean insertion or removal of rules. It is not required to log modification of the inode information since the watch is still in effect. Additionally, if the rule is a never rule and the underlying file is one they do not want events for, they get an event for this bookkeeping update against their wishes.
Since no device/inode info is logged at insertion and no device/inode information is logged on update, there is nothing meaningful being communicated to the admin by the CONFIG_CHANGE updated_rules event. One can assume that the rule was not "modified" because it is still watching the intended target. If the device or inode cannot be resolved, then audit_panic is called which is sufficient.
The correct resolution is to drop logging config_update events since the watch is still in effect but just on another unknown inode.
Signed-off-by: Steve Grubb sgrubb@redhat.com Signed-off-by: Paul Moore paul@paul-moore.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/audit_watch.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index 4f7262eba73d8..50952d6d81209 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c @@ -317,8 +317,6 @@ static void audit_update_watch(struct audit_parent *parent, if (oentry->rule.exe) audit_remove_mark(oentry->rule.exe);
- audit_watch_log_rule_change(r, owatch, "updated_rules"); - call_rcu(&oentry->rcu, audit_free_rule_rcu); }
From: Sergey Shatunov me@prok.pw
[ Upstream commit eb3939e386ec8df6049697d388298590231ac79c ]
The ASUS FX505DV laptop contains RTL8822CE device with an associated BT chip using a USB ID of 13d3:3548. This patch add fw download support for it.
T: Bus=03 Lev=01 Prnt=01 Port=03 Cnt=03 Dev#= 4 Spd=12 MxCh= 0 D: Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=13d3 ProdID=3548 Rev= 0.00 S: Manufacturer=Realtek S: Product=Bluetooth Radio S: SerialNumber=00e04c000001 C:* #Ifs= 2 Cfg#= 1 Atr=a0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
Signed-off-by: Sergey Shatunov me@prok.pw Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/btusb.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 1b0adf5c23760..f3681f151749d 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -393,6 +393,7 @@ static const struct usb_device_id blacklist_table[] = {
/* Additional Realtek 8822CE Bluetooth devices */ { USB_DEVICE(0x04ca, 0x4005), .driver_info = BTUSB_REALTEK }, + { USB_DEVICE(0x13d3, 0x3548), .driver_info = BTUSB_REALTEK },
/* Silicon Wave based devices */ { USB_DEVICE(0x0c10, 0x0000), .driver_info = BTUSB_SWAVE },
From: Yannick Fertre yannick.fertre@st.com
[ Upstream commit a6bd58c51ac43083f3977057a7ad668def55812f ]
Following investigations of a hardware bug, the LIE interrupt can occur while the display controller is not activated. LIE interrupt (vblank) don't have to be set if the CRTC is not enabled.
Signed-off-by: Yannick Fertre yannick.fertre@st.com Acked-by: Philippe Cornu philippe.cornu@st.com Signed-off-by: Benjamin Gaignard benjamin.gaignard@st.com Link: https://patchwork.freedesktop.org/patch/msgid/1579601650-7055-1-git-send-ema... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/stm/ltdc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index 477d0a27b9a5d..75d108db127c8 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -612,9 +612,14 @@ static const struct drm_crtc_helper_funcs ltdc_crtc_helper_funcs = { static int ltdc_crtc_enable_vblank(struct drm_crtc *crtc) { struct ltdc_device *ldev = crtc_to_ltdc(crtc); + struct drm_crtc_state *state = crtc->state;
DRM_DEBUG_DRIVER("\n"); - reg_set(ldev->regs, LTDC_IER, IER_LIE); + + if (state->enable) + reg_set(ldev->regs, LTDC_IER, IER_LIE); + else + return -EPERM;
return 0; }
From: James Smart jsmart2021@gmail.com
[ Upstream commit 39c4f1a965a9244c3ba60695e8ff8da065ec6ac4 ]
The driver is occasionally seeing the following SLI Port error, requiring reset and reinit:
Port Status Event: ... error 1=0x52004a01, error 2=0x218
The failure means an RQ timeout. That is, the adapter had received asynchronous receive frames, ran out of buffer slots to place the frames, and the driver did not replenish the buffer slots before a timeout occurred. The driver should not be so slow in replenishing buffers that a timeout can occur.
When the driver received all the frames of a sequence, it allocates an IOCB to put the frames in. In a situation where there was no IOCB available for the frame of a sequence, the RQ buffer corresponding to the first frame of the sequence was not returned to the FW. Eventually, with enough traffic encountering the situation, the timeout occurred.
Fix by releasing the buffer back to firmware whenever there is no IOCB for the first frame.
[mkp: typo]
Link: https://lore.kernel.org/r/20200128002312.16346-2-jsmart2021@gmail.com Signed-off-by: Dick Kennedy dick.kennedy@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_sli.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index a801917d3c193..c7ba7ea93eed0 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -17411,6 +17411,10 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) list_add_tail(&iocbq->list, &first_iocbq->list); } } + /* Free the sequence's header buffer */ + if (!first_iocbq) + lpfc_in_buf_free(vport->phba, &seq_dmabuf->dbuf); + return first_iocbq; }
From: Martin Kepplinger martin.kepplinger@puri.sm
[ Upstream commit 16bbc3eb83728c03138191a5d23d84d38175fa26 ]
Appearently the hw pointer can be NULL while the module is loaded and in that case rsi_shutdown() crashes due to the unconditional dereference.
Signed-off-by: Martin Kepplinger martin.kepplinger@puri.sm Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/rsi/rsi_91x_sdio.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c index 81cc1044532d1..fee43cd882f8f 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c @@ -1357,12 +1357,15 @@ static void rsi_shutdown(struct device *dev) struct rsi_91x_sdiodev *sdev = (struct rsi_91x_sdiodev *)adapter->rsi_dev; struct ieee80211_hw *hw = adapter->hw; - struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config;
rsi_dbg(ERR_ZONE, "SDIO Bus shutdown =====>\n");
- if (rsi_config_wowlan(adapter, wowlan)) - rsi_dbg(ERR_ZONE, "Failed to configure WoWLAN\n"); + if (hw) { + struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config; + + if (rsi_config_wowlan(adapter, wowlan)) + rsi_dbg(ERR_ZONE, "Failed to configure WoWLAN\n"); + }
if (IS_ENABLED(CONFIG_RSI_COEX) && adapter->priv->coex_mode > 1 && adapter->priv->bt_adapter) {
From: Aric Cyr aric.cyr@amd.com
[ Upstream commit 6a6c4a4d459ecacc9013c45dcbf2bc9747fdbdbd ]
[Why] Since the i2c payload allocation can fail need to check return codes
[How] Clean up i2c payload allocations and check for errors
Signed-off-by: Aric Cyr aric.cyr@amd.com Reviewed-by: Joshua Aberback Joshua.Aberback@amd.com Acked-by: Rodrigo Siqueira Rodrigo.Siqueira@amd.com Acked-by: Harry Wentland harry.wentland@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/display/dc/core/dc_link_ddc.c | 52 +++++++++---------- 1 file changed, 25 insertions(+), 27 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c index 46c9cb47a96e5..145af3bb2dfcb 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c @@ -127,22 +127,16 @@ struct aux_payloads { struct vector payloads; };
-static struct i2c_payloads *dal_ddc_i2c_payloads_create(struct dc_context *ctx, uint32_t count) +static bool dal_ddc_i2c_payloads_create( + struct dc_context *ctx, + struct i2c_payloads *payloads, + uint32_t count) { - struct i2c_payloads *payloads; - - payloads = kzalloc(sizeof(struct i2c_payloads), GFP_KERNEL); - - if (!payloads) - return NULL; - if (dal_vector_construct( &payloads->payloads, ctx, count, sizeof(struct i2c_payload))) - return payloads; - - kfree(payloads); - return NULL; + return true;
+ return false; }
static struct i2c_payload *dal_ddc_i2c_payloads_get(struct i2c_payloads *p) @@ -155,14 +149,12 @@ static uint32_t dal_ddc_i2c_payloads_get_count(struct i2c_payloads *p) return p->payloads.count; }
-static void dal_ddc_i2c_payloads_destroy(struct i2c_payloads **p) +static void dal_ddc_i2c_payloads_destroy(struct i2c_payloads *p) { - if (!p || !*p) + if (!p) return; - dal_vector_destruct(&(*p)->payloads); - kfree(*p); - *p = NULL;
+ dal_vector_destruct(&p->payloads); }
static struct aux_payloads *dal_ddc_aux_payloads_create(struct dc_context *ctx, uint32_t count) @@ -580,9 +572,13 @@ bool dal_ddc_service_query_ddc_data(
uint32_t payloads_num = write_payloads + read_payloads;
+ if (write_size > EDID_SEGMENT_SIZE || read_size > EDID_SEGMENT_SIZE) return false;
+ if (!payloads_num) + return false; + /*TODO: len of payload data for i2c and aux is uint8!!!!, * but we want to read 256 over i2c!!!!*/ if (dal_ddc_service_is_in_aux_transaction_mode(ddc)) { @@ -613,23 +609,25 @@ bool dal_ddc_service_query_ddc_data( dal_ddc_aux_payloads_destroy(&payloads);
} else { - struct i2c_payloads *payloads = - dal_ddc_i2c_payloads_create(ddc->ctx, payloads_num); + struct i2c_command command = {0}; + struct i2c_payloads payloads;
- struct i2c_command command = { - .payloads = dal_ddc_i2c_payloads_get(payloads), - .number_of_payloads = 0, - .engine = DDC_I2C_COMMAND_ENGINE, - .speed = ddc->ctx->dc->caps.i2c_speed_in_khz }; + if (!dal_ddc_i2c_payloads_create(ddc->ctx, &payloads, payloads_num)) + return false; + + command.payloads = dal_ddc_i2c_payloads_get(&payloads); + command.number_of_payloads = 0; + command.engine = DDC_I2C_COMMAND_ENGINE; + command.speed = ddc->ctx->dc->caps.i2c_speed_in_khz;
dal_ddc_i2c_payloads_add( - payloads, address, write_size, write_buf, true); + &payloads, address, write_size, write_buf, true);
dal_ddc_i2c_payloads_add( - payloads, address, read_size, read_buf, false); + &payloads, address, read_size, read_buf, false);
command.number_of_payloads = - dal_ddc_i2c_payloads_get_count(payloads); + dal_ddc_i2c_payloads_get_count(&payloads);
ret = dm_helpers_submit_i2c( ddc->ctx,
From: Jason Gunthorpe jgg@mellanox.com
[ Upstream commit 7c11910783a1ea17e88777552ef146cace607b3c ]
The rdma_cm must be used single threaded.
This appears to be a bug in the design, as it does have lots of locking that seems like it should allow concurrency. However, when it is all said and done every single place that uses the cma_exch() scheme is broken, and all the unlocked reads from the ucma of the cm_id data are wrong too.
syzkaller has been finding endless bugs related to this.
Fixing this in any elegant way is some enormous amount of work. Take a very big hammer and put a mutex around everything to do with the ucma_context at the top of every syscall.
Fixes: 75216638572f ("RDMA/cma: Export rdma cm interface to userspace") Link: https://lore.kernel.org/r/20200218210432.GA31966@ziepe.ca Reported-by: syzbot+adb15cf8c2798e4e0db4@syzkaller.appspotmail.com Reported-by: syzbot+e5579222b6a3edd96522@syzkaller.appspotmail.com Reported-by: syzbot+4b628fcc748474003457@syzkaller.appspotmail.com Reported-by: syzbot+29ee8f76017ce6cf03da@syzkaller.appspotmail.com Reported-by: syzbot+6956235342b7317ec564@syzkaller.appspotmail.com Reported-by: syzbot+b358909d8d01556b790b@syzkaller.appspotmail.com Reported-by: syzbot+6b46b135602a3f3ac99e@syzkaller.appspotmail.com Reported-by: syzbot+8458d13b13562abf6b77@syzkaller.appspotmail.com Reported-by: syzbot+bd034f3fdc0402e942ed@syzkaller.appspotmail.com Reported-by: syzbot+c92378b32760a4eef756@syzkaller.appspotmail.com Reported-by: syzbot+68b44a1597636e0b342c@syzkaller.appspotmail.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/core/ucma.c | 49 ++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 01d68ed46c1b6..2acc30c3d5b2d 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -89,6 +89,7 @@ struct ucma_context {
struct ucma_file *file; struct rdma_cm_id *cm_id; + struct mutex mutex; u64 uid;
struct list_head list; @@ -215,6 +216,7 @@ static struct ucma_context *ucma_alloc_ctx(struct ucma_file *file) init_completion(&ctx->comp); INIT_LIST_HEAD(&ctx->mc_list); ctx->file = file; + mutex_init(&ctx->mutex);
mutex_lock(&mut); ctx->id = idr_alloc(&ctx_idr, ctx, 0, 0, GFP_KERNEL); @@ -596,6 +598,7 @@ static int ucma_free_ctx(struct ucma_context *ctx) }
events_reported = ctx->events_reported; + mutex_destroy(&ctx->mutex); kfree(ctx); return events_reported; } @@ -665,7 +668,10 @@ static ssize_t ucma_bind_ip(struct ucma_file *file, const char __user *inbuf, if (IS_ERR(ctx)) return PTR_ERR(ctx);
+ mutex_lock(&ctx->mutex); ret = rdma_bind_addr(ctx->cm_id, (struct sockaddr *) &cmd.addr); + mutex_unlock(&ctx->mutex); + ucma_put_ctx(ctx); return ret; } @@ -688,7 +694,9 @@ static ssize_t ucma_bind(struct ucma_file *file, const char __user *inbuf, if (IS_ERR(ctx)) return PTR_ERR(ctx);
+ mutex_lock(&ctx->mutex); ret = rdma_bind_addr(ctx->cm_id, (struct sockaddr *) &cmd.addr); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; } @@ -712,8 +720,10 @@ static ssize_t ucma_resolve_ip(struct ucma_file *file, if (IS_ERR(ctx)) return PTR_ERR(ctx);
+ mutex_lock(&ctx->mutex); ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr, (struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; } @@ -738,8 +748,10 @@ static ssize_t ucma_resolve_addr(struct ucma_file *file, if (IS_ERR(ctx)) return PTR_ERR(ctx);
+ mutex_lock(&ctx->mutex); ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr, (struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; } @@ -759,7 +771,9 @@ static ssize_t ucma_resolve_route(struct ucma_file *file, if (IS_ERR(ctx)) return PTR_ERR(ctx);
+ mutex_lock(&ctx->mutex); ret = rdma_resolve_route(ctx->cm_id, cmd.timeout_ms); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; } @@ -848,6 +862,7 @@ static ssize_t ucma_query_route(struct ucma_file *file, if (IS_ERR(ctx)) return PTR_ERR(ctx);
+ mutex_lock(&ctx->mutex); memset(&resp, 0, sizeof resp); addr = (struct sockaddr *) &ctx->cm_id->route.addr.src_addr; memcpy(&resp.src_addr, addr, addr->sa_family == AF_INET ? @@ -871,6 +886,7 @@ static ssize_t ucma_query_route(struct ucma_file *file, ucma_copy_iw_route(&resp, &ctx->cm_id->route);
out: + mutex_unlock(&ctx->mutex); if (copy_to_user(u64_to_user_ptr(cmd.response), &resp, sizeof(resp))) ret = -EFAULT; @@ -1022,6 +1038,7 @@ static ssize_t ucma_query(struct ucma_file *file, if (IS_ERR(ctx)) return PTR_ERR(ctx);
+ mutex_lock(&ctx->mutex); switch (cmd.option) { case RDMA_USER_CM_QUERY_ADDR: ret = ucma_query_addr(ctx, response, out_len); @@ -1036,6 +1053,7 @@ static ssize_t ucma_query(struct ucma_file *file, ret = -ENOSYS; break; } + mutex_unlock(&ctx->mutex);
ucma_put_ctx(ctx); return ret; @@ -1076,7 +1094,9 @@ static ssize_t ucma_connect(struct ucma_file *file, const char __user *inbuf, return PTR_ERR(ctx);
ucma_copy_conn_param(ctx->cm_id, &conn_param, &cmd.conn_param); + mutex_lock(&ctx->mutex); ret = rdma_connect(ctx->cm_id, &conn_param); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; } @@ -1097,7 +1117,9 @@ static ssize_t ucma_listen(struct ucma_file *file, const char __user *inbuf,
ctx->backlog = cmd.backlog > 0 && cmd.backlog < max_backlog ? cmd.backlog : max_backlog; + mutex_lock(&ctx->mutex); ret = rdma_listen(ctx->cm_id, ctx->backlog); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; } @@ -1120,13 +1142,17 @@ static ssize_t ucma_accept(struct ucma_file *file, const char __user *inbuf, if (cmd.conn_param.valid) { ucma_copy_conn_param(ctx->cm_id, &conn_param, &cmd.conn_param); mutex_lock(&file->mut); + mutex_lock(&ctx->mutex); ret = __rdma_accept(ctx->cm_id, &conn_param, NULL); + mutex_unlock(&ctx->mutex); if (!ret) ctx->uid = cmd.uid; mutex_unlock(&file->mut); - } else + } else { + mutex_lock(&ctx->mutex); ret = __rdma_accept(ctx->cm_id, NULL, NULL); - + mutex_unlock(&ctx->mutex); + } ucma_put_ctx(ctx); return ret; } @@ -1145,7 +1171,9 @@ static ssize_t ucma_reject(struct ucma_file *file, const char __user *inbuf, if (IS_ERR(ctx)) return PTR_ERR(ctx);
+ mutex_lock(&ctx->mutex); ret = rdma_reject(ctx->cm_id, cmd.private_data, cmd.private_data_len); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; } @@ -1164,7 +1192,9 @@ static ssize_t ucma_disconnect(struct ucma_file *file, const char __user *inbuf, if (IS_ERR(ctx)) return PTR_ERR(ctx);
+ mutex_lock(&ctx->mutex); ret = rdma_disconnect(ctx->cm_id); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; } @@ -1195,7 +1225,9 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file, resp.qp_attr_mask = 0; memset(&qp_attr, 0, sizeof qp_attr); qp_attr.qp_state = cmd.qp_state; + mutex_lock(&ctx->mutex); ret = rdma_init_qp_attr(ctx->cm_id, &qp_attr, &resp.qp_attr_mask); + mutex_unlock(&ctx->mutex); if (ret) goto out;
@@ -1274,9 +1306,13 @@ static int ucma_set_ib_path(struct ucma_context *ctx, struct sa_path_rec opa;
sa_convert_path_ib_to_opa(&opa, &sa_path); + mutex_lock(&ctx->mutex); ret = rdma_set_ib_path(ctx->cm_id, &opa); + mutex_unlock(&ctx->mutex); } else { + mutex_lock(&ctx->mutex); ret = rdma_set_ib_path(ctx->cm_id, &sa_path); + mutex_unlock(&ctx->mutex); } if (ret) return ret; @@ -1309,7 +1345,9 @@ static int ucma_set_option_level(struct ucma_context *ctx, int level,
switch (level) { case RDMA_OPTION_ID: + mutex_lock(&ctx->mutex); ret = ucma_set_option_id(ctx, optname, optval, optlen); + mutex_unlock(&ctx->mutex); break; case RDMA_OPTION_IB: ret = ucma_set_option_ib(ctx, optname, optval, optlen); @@ -1369,8 +1407,10 @@ static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf, if (IS_ERR(ctx)) return PTR_ERR(ctx);
+ mutex_lock(&ctx->mutex); if (ctx->cm_id->device) ret = rdma_notify(ctx->cm_id, (enum ib_event_type)cmd.event); + mutex_unlock(&ctx->mutex);
ucma_put_ctx(ctx); return ret; @@ -1413,8 +1453,10 @@ static ssize_t ucma_process_join(struct ucma_file *file, mc->join_state = join_state; mc->uid = cmd->uid; memcpy(&mc->addr, addr, cmd->addr_size); + mutex_lock(&ctx->mutex); ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *)&mc->addr, join_state, mc); + mutex_unlock(&ctx->mutex); if (ret) goto err2;
@@ -1518,7 +1560,10 @@ static ssize_t ucma_leave_multicast(struct ucma_file *file, goto out; }
+ mutex_lock(&mc->ctx->mutex); rdma_leave_multicast(mc->ctx->cm_id, (struct sockaddr *) &mc->addr); + mutex_unlock(&mc->ctx->mutex); + mutex_lock(&mc->ctx->file->mut); ucma_cleanup_mc_events(mc); list_del(&mc->list);
From: Qiujun Huang hqjagain@gmail.com
[ Upstream commit 71811cac8532b2387b3414f7cd8fe9e497482864 ]
Needn't call 'rfcomm_dlc_put' here, because 'rfcomm_dlc_exists' didn't increase dlc->refcnt.
Reported-by: syzbot+4496e82090657320efc6@syzkaller.appspotmail.com Signed-off-by: Qiujun Huang hqjagain@gmail.com Suggested-by: Hillf Danton hdanton@sina.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/rfcomm/tty.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 5e44d842cc5d0..cf0ccd05329c7 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -413,10 +413,8 @@ static int __rfcomm_create_dev(struct sock *sk, void __user *arg) dlc = rfcomm_dlc_exists(&req.src, &req.dst, req.channel); if (IS_ERR(dlc)) return PTR_ERR(dlc); - else if (dlc) { - rfcomm_dlc_put(dlc); + if (dlc) return -EBUSY; - } dlc = rfcomm_dlc_alloc(GFP_KERNEL); if (!dlc) return -ENOMEM;
From: Eric Biggers ebiggers@google.com
[ Upstream commit 10a98cb16d80be3595fdb165fad898bb28b8b6d2 ]
Leaving PF_MEMALLOC set when exiting a kthread causes it to remain set during do_exit(). That can confuse things. In particular, if BSD process accounting is enabled, then do_exit() writes data to an accounting file. If that file has FS_SYNC_FL set, then this write occurs synchronously and can misbehave if PF_MEMALLOC is set.
For example, if the accounting file is located on an XFS filesystem, then a WARN_ON_ONCE() in iomap_do_writepage() is triggered and the data doesn't get written when it should. Or if the accounting file is located on an ext4 filesystem without a journal, then a WARN_ON_ONCE() in ext4_write_inode() is triggered and the inode doesn't get written.
Fix this in xfsaild() by using the helper functions to save and restore PF_MEMALLOC.
This can be reproduced as follows in the kvm-xfstests test appliance modified to add the 'acct' Debian package, and with kvm-xfstests's recommended kconfig modified to add CONFIG_BSD_PROCESS_ACCT=y:
mkfs.xfs -f /dev/vdb mount /vdb touch /vdb/file chattr +S /vdb/file accton /vdb/file mkfs.xfs -f /dev/vdc mount /vdc umount /vdc
It causes: WARNING: CPU: 1 PID: 336 at fs/iomap/buffered-io.c:1534 CPU: 1 PID: 336 Comm: xfsaild/vdc Not tainted 5.6.0-rc5 #3 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20191223_100556-anatol 04/01/2014 RIP: 0010:iomap_do_writepage+0x16b/0x1f0 fs/iomap/buffered-io.c:1534 [...] Call Trace: write_cache_pages+0x189/0x4d0 mm/page-writeback.c:2238 iomap_writepages+0x1c/0x33 fs/iomap/buffered-io.c:1642 xfs_vm_writepages+0x65/0x90 fs/xfs/xfs_aops.c:578 do_writepages+0x41/0xe0 mm/page-writeback.c:2344 __filemap_fdatawrite_range+0xd2/0x120 mm/filemap.c:421 file_write_and_wait_range+0x71/0xc0 mm/filemap.c:760 xfs_file_fsync+0x7a/0x2b0 fs/xfs/xfs_file.c:114 generic_write_sync include/linux/fs.h:2867 [inline] xfs_file_buffered_aio_write+0x379/0x3b0 fs/xfs/xfs_file.c:691 call_write_iter include/linux/fs.h:1901 [inline] new_sync_write+0x130/0x1d0 fs/read_write.c:483 __kernel_write+0x54/0xe0 fs/read_write.c:515 do_acct_process+0x122/0x170 kernel/acct.c:522 slow_acct_process kernel/acct.c:581 [inline] acct_process+0x1d4/0x27c kernel/acct.c:607 do_exit+0x83d/0xbc0 kernel/exit.c:791 kthread+0xf1/0x140 kernel/kthread.c:257 ret_from_fork+0x27/0x50 arch/x86/entry/entry_64.S:352
This bug was originally reported by syzbot at https://lore.kernel.org/r/0000000000000e7156059f751d7b@google.com.
Reported-by: syzbot+1f9dc49e8de2582d90c2@syzkaller.appspotmail.com Signed-off-by: Eric Biggers ebiggers@google.com Reviewed-by: Darrick J. Wong darrick.wong@oracle.com Signed-off-by: Darrick J. Wong darrick.wong@oracle.com Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- fs/xfs/xfs_trans_ail.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index d3a4e89bf4a0d..66f167aefd94f 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -520,8 +520,9 @@ xfsaild( { struct xfs_ail *ailp = data; long tout = 0; /* milliseconds */ + unsigned int noreclaim_flag;
- current->flags |= PF_MEMALLOC; + noreclaim_flag = memalloc_noreclaim_save(); set_freezable();
while (1) { @@ -592,6 +593,7 @@ xfsaild( tout = xfsaild_push(ailp); }
+ memalloc_noreclaim_restore(noreclaim_flag); return 0; }
From: Wen Gong wgong@codeaurora.org
[ Upstream commit 37b7ecb75627699e96750db1e0c5ac56224245df ]
When running simulate crash stress test, it happened "failed to read from address 0x800: -110".
Test steps: 1. Run command continuous echo soft > /sys/kernel/debug/ieee80211/phy0/ath10k/simulate_fw_crash
2. error happened and it did not begin recovery for long time. [74377.334846] ath10k_sdio mmc1:0001:1: simulating soft firmware crash [74378.378217] ath10k_sdio mmc1:0001:1: failed to read from address 0x800: -110 [74378.378371] ath10k_sdio mmc1:0001:1: failed to process pending SDIO interrupts: -110
It has sdio errors since it can not read MBOX_HOST_INT_STATUS_ADDRESS, then it has to do recovery process to recovery ath10k.
Tested with QCA6174 SDIO with firmware WLAN.RMH.4.4.1-00042.
Signed-off-by: Wen Gong wgong@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath10k/sdio.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c index 0cdaecb0e28a9..1606bd71f3834 100644 --- a/drivers/net/wireless/ath/ath10k/sdio.c +++ b/drivers/net/wireless/ath/ath10k/sdio.c @@ -915,8 +915,11 @@ static int ath10k_sdio_mbox_read_int_status(struct ath10k *ar, */ ret = ath10k_sdio_read(ar, MBOX_HOST_INT_STATUS_ADDRESS, irq_proc_reg, sizeof(*irq_proc_reg)); - if (ret) + if (ret) { + queue_work(ar->workqueue, &ar->restart_work); + ath10k_warn(ar, "read int status fail, start recovery\n"); goto out; + }
/* Update only those registers that are enabled */ *host_int_status = irq_proc_reg->host_int_status &
From: Sagar Biradar Sagar.Biradar@microchip.com
[ Upstream commit bef18d308a2215eff8c3411a23d7f34604ce56c3 ]
Fixes the occasional adapter panic when sg_reset is issued with -d, -t, -b and -H flags. Removal of command type HBA_IU_TYPE_SCSI_TM_REQ in aac_hba_send since iu_type, request_id and fib_flags are not populated. Device and target reset handlers are made to send TMF commands only when reset_state is 0.
Link: https://lore.kernel.org/r/1581553771-25796-1-git-send-email-Sagar.Biradar@mi... Reviewed-by: Sagar Biradar Sagar.Biradar@microchip.com Signed-off-by: Sagar Biradar Sagar.Biradar@microchip.com Signed-off-by: Balsundar P balsundar.p@microsemi.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/aacraid/commsup.c | 2 +- drivers/scsi/aacraid/linit.c | 34 +++++++++++++++++++++++++--------- 2 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index b7588de4484e5..4cb6ee6e1212e 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -743,7 +743,7 @@ int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback, hbacmd->request_id = cpu_to_le32((((u32)(fibptr - dev->fibs)) << 2) + 1); fibptr->flags |= FIB_CONTEXT_FLAG_SCSI_CMD; - } else if (command != HBA_IU_TYPE_SCSI_TM_REQ) + } else return -EINVAL;
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 1046947064a0b..0142547aaadd2 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -736,7 +736,11 @@ static int aac_eh_abort(struct scsi_cmnd* cmd) status = aac_hba_send(HBA_IU_TYPE_SCSI_TM_REQ, fib, (fib_callback) aac_hba_callback, (void *) cmd); - + if (status != -EINPROGRESS) { + aac_fib_complete(fib); + aac_fib_free(fib); + return ret; + } /* Wait up to 15 secs for completion */ for (count = 0; count < 15; ++count) { if (cmd->SCp.sent_command) { @@ -915,11 +919,11 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
info = &aac->hba_map[bus][cid];
- if (info->devtype != AAC_DEVTYPE_NATIVE_RAW && - info->reset_state > 0) + if (!(info->devtype == AAC_DEVTYPE_NATIVE_RAW && + !(info->reset_state > 0))) return FAILED;
- pr_err("%s: Host adapter reset request. SCSI hang ?\n", + pr_err("%s: Host device reset request. SCSI hang ?\n", AAC_DRIVERNAME);
fib = aac_fib_alloc(aac); @@ -934,7 +938,12 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd) status = aac_hba_send(command, fib, (fib_callback) aac_tmf_callback, (void *) info); - + if (status != -EINPROGRESS) { + info->reset_state = 0; + aac_fib_complete(fib); + aac_fib_free(fib); + return ret; + } /* Wait up to 15 seconds for completion */ for (count = 0; count < 15; ++count) { if (info->reset_state == 0) { @@ -973,11 +982,11 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd)
info = &aac->hba_map[bus][cid];
- if (info->devtype != AAC_DEVTYPE_NATIVE_RAW && - info->reset_state > 0) + if (!(info->devtype == AAC_DEVTYPE_NATIVE_RAW && + !(info->reset_state > 0))) return FAILED;
- pr_err("%s: Host adapter reset request. SCSI hang ?\n", + pr_err("%s: Host target reset request. SCSI hang ?\n", AAC_DRIVERNAME);
fib = aac_fib_alloc(aac); @@ -994,6 +1003,13 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd) (fib_callback) aac_tmf_callback, (void *) info);
+ if (status != -EINPROGRESS) { + info->reset_state = 0; + aac_fib_complete(fib); + aac_fib_free(fib); + return ret; + } + /* Wait up to 15 seconds for completion */ for (count = 0; count < 15; ++count) { if (info->reset_state <= 0) { @@ -1046,7 +1062,7 @@ static int aac_eh_bus_reset(struct scsi_cmnd* cmd) } }
- pr_err("%s: Host adapter reset request. SCSI hang ?\n", AAC_DRIVERNAME); + pr_err("%s: Host bus reset request. SCSI hang ?\n", AAC_DRIVERNAME);
/* * Check the health of the controller
From: Jason Gunthorpe jgg@mellanox.com
[ Upstream commit bede86a39d9dc3387ac00dcb8e1ac221676b2f25 ]
When creating a cm_id during REQ the id immediately becomes visible to the other MAD handlers, and shortly after the state is moved to IB_CM_REQ_RCVD
This allows cm_rej_handler() to run concurrently and free the work:
CPU 0 CPU1 cm_req_handler() ib_create_cm_id() cm_match_req() id_priv->state = IB_CM_REQ_RCVD cm_rej_handler() cm_acquire_id() spin_lock(&id_priv->lock) switch (id_priv->state) case IB_CM_REQ_RCVD: cm_reset_to_idle() kfree(id_priv->timewait_info); goto destroy destroy: kfree(id_priv->timewait_info); id_priv->timewait_info = NULL
Causing a double free or worse.
Do not free the timewait_info without also holding the id_priv->lock. Simplify this entire flow by making the free unconditional during cm_destroy_id() and removing the confusing special case error unwind during creation of the timewait_info.
This also fixes a leak of the timewait if cm_destroy_id() is called in IB_CM_ESTABLISHED with an XRC TGT QP. The state machine will be left in ESTABLISHED while it needed to transition through IB_CM_TIMEWAIT to release the timewait pointer.
Also fix a leak of the timewait_info if the caller mis-uses the API and does ib_send_cm_reqs().
Fixes: a977049dacde ("[PATCH] IB: Add the kernel CM implementation") Link: https://lore.kernel.org/r/20200310092545.251365-4-leon@kernel.org Signed-off-by: Leon Romanovsky leonro@mellanox.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/core/cm.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 7251068b6af0f..601a36e7f098c 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -1100,14 +1100,22 @@ static void cm_destroy_id(struct ib_cm_id *cm_id, int err) break; }
- spin_lock_irq(&cm.lock); + spin_lock_irq(&cm_id_priv->lock); + spin_lock(&cm.lock); + /* Required for cleanup paths related cm_req_handler() */ + if (cm_id_priv->timewait_info) { + cm_cleanup_timewait(cm_id_priv->timewait_info); + kfree(cm_id_priv->timewait_info); + cm_id_priv->timewait_info = NULL; + } if (!list_empty(&cm_id_priv->altr_list) && (!cm_id_priv->altr_send_port_not_ready)) list_del(&cm_id_priv->altr_list); if (!list_empty(&cm_id_priv->prim_list) && (!cm_id_priv->prim_send_port_not_ready)) list_del(&cm_id_priv->prim_list); - spin_unlock_irq(&cm.lock); + spin_unlock(&cm.lock); + spin_unlock_irq(&cm_id_priv->lock);
cm_free_id(cm_id->local_id); cm_deref_id(cm_id_priv); @@ -1424,7 +1432,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, /* Verify that we're not in timewait. */ cm_id_priv = container_of(cm_id, struct cm_id_private, id); spin_lock_irqsave(&cm_id_priv->lock, flags); - if (cm_id->state != IB_CM_IDLE) { + if (cm_id->state != IB_CM_IDLE || WARN_ON(cm_id_priv->timewait_info)) { spin_unlock_irqrestore(&cm_id_priv->lock, flags); ret = -EINVAL; goto out; @@ -1442,12 +1450,12 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, param->ppath_sgid_attr, &cm_id_priv->av, cm_id_priv); if (ret) - goto error1; + goto out; if (param->alternate_path) { ret = cm_init_av_by_path(param->alternate_path, NULL, &cm_id_priv->alt_av, cm_id_priv); if (ret) - goto error1; + goto out; } cm_id->service_id = param->service_id; cm_id->service_mask = ~cpu_to_be64(0); @@ -1465,7 +1473,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
ret = cm_alloc_msg(cm_id_priv, &cm_id_priv->msg); if (ret) - goto error1; + goto out;
req_msg = (struct cm_req_msg *) cm_id_priv->msg->mad; cm_format_req(req_msg, cm_id_priv, param); @@ -1488,7 +1496,6 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, return 0;
error2: cm_free_msg(cm_id_priv->msg); -error1: kfree(cm_id_priv->timewait_info); out: return ret; } EXPORT_SYMBOL(ib_send_cm_req); @@ -1977,7 +1984,7 @@ static int cm_req_handler(struct cm_work *work) pr_debug("%s: local_id %d, no listen_cm_id_priv\n", __func__, be32_to_cpu(cm_id->local_id)); ret = -EINVAL; - goto free_timeinfo; + goto destroy; }
cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler; @@ -2061,8 +2068,6 @@ static int cm_req_handler(struct cm_work *work) rejected: atomic_dec(&cm_id_priv->refcount); cm_deref_id(listen_cm_id_priv); -free_timeinfo: - kfree(cm_id_priv->timewait_info); destroy: ib_destroy_cm_id(cm_id); return ret;
From: Gustavo Romero gromero@linux.ibm.com
[ Upstream commit 1dff3064c764b5a51c367b949b341d2e38972bec ]
On P9 DD2.2 due to a CPU defect some TM instructions need to be emulated by KVM. This is handled at first by the hardware raising a softpatch interrupt when certain TM instructions that need KVM assistance are executed in the guest. Althought some TM instructions per Power ISA are invalid forms they can raise a softpatch interrupt too. For instance, 'tresume.' instruction as defined in the ISA must have bit 31 set (1), but an instruction that matches 'tresume.' PO and XO opcode fields but has bit 31 not set (0), like 0x7cfe9ddc, also raises a softpatch interrupt. Similarly for 'treclaim.' and 'trechkpt.' instructions with bit 31 = 0, i.e. 0x7c00075c and 0x7c0007dc, respectively. Hence, if a code like the following is executed in the guest it will raise a softpatch interrupt just like a 'tresume.' when the TM facility is enabled ('tabort. 0' in the example is used only to enable the TM facility):
int main() { asm("tabort. 0; .long 0x7cfe9ddc;"); }
Currently in such a case KVM throws a complete trace like:
[345523.705984] WARNING: CPU: 24 PID: 64413 at arch/powerpc/kvm/book3s_hv_tm.c:211 kvmhv_p9_tm_emulation+0x68/0x620 [kvm_hv] [345523.705985] Modules linked in: kvm_hv(E) xt_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp ip6table_mangle ip6table_nat iptable_mangle iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter bridge stp llc sch_fq_codel ipmi_powernv at24 vmx_crypto ipmi_devintf ipmi_msghandler ibmpowernv uio_pdrv_genirq kvm opal_prd uio leds_powernv ib_iser rdma_cm iw_cm ib_cm ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi ip_tables x_tables autofs4 btrfs blake2b_generic zstd_compress raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx libcrc32c xor raid6_pq raid1 raid0 multipath linear tg3 crct10dif_vpmsum crc32c_vpmsum ipr [last unloaded: kvm_hv] [345523.706030] CPU: 24 PID: 64413 Comm: CPU 0/KVM Tainted: G W E 5.5.0+ #1 [345523.706031] NIP: c0080000072cb9c0 LR: c0080000072b5e80 CTR: c0080000085c7850 [345523.706034] REGS: c000000399467680 TRAP: 0700 Tainted: G W E (5.5.0+) [345523.706034] MSR: 900000010282b033 <SF,HV,VEC,VSX,EE,FP,ME,IR,DR,RI,LE,TM[E]> CR: 24022428 XER: 00000000 [345523.706042] CFAR: c0080000072b5e7c IRQMASK: 0 GPR00: c0080000072b5e80 c000000399467910 c0080000072db500 c000000375ccc720 GPR04: c000000375ccc720 00000003fbec0000 0000a10395dda5a6 0000000000000000 GPR08: 000000007cfe9ddc 7cfe9ddc000005dc 7cfe9ddc7c0005dc c0080000072cd530 GPR12: c0080000085c7850 c0000003fffeb800 0000000000000001 00007dfb737f0000 GPR16: c0002001edcca558 0000000000000000 0000000000000000 0000000000000001 GPR20: c000000001b21258 c0002001edcca558 0000000000000018 0000000000000000 GPR24: 0000000001000000 ffffffffffffffff 0000000000000001 0000000000001500 GPR28: c0002001edcc4278 c00000037dd80000 800000050280f033 c000000375ccc720 [345523.706062] NIP [c0080000072cb9c0] kvmhv_p9_tm_emulation+0x68/0x620 [kvm_hv] [345523.706065] LR [c0080000072b5e80] kvmppc_handle_exit_hv.isra.53+0x3e8/0x798 [kvm_hv] [345523.706066] Call Trace: [345523.706069] [c000000399467910] [c000000399467940] 0xc000000399467940 (unreliable) [345523.706071] [c000000399467950] [c000000399467980] 0xc000000399467980 [345523.706075] [c0000003994679f0] [c0080000072bd1c4] kvmhv_run_single_vcpu+0xa1c/0xb80 [kvm_hv] [345523.706079] [c000000399467ac0] [c0080000072bd8e0] kvmppc_vcpu_run_hv+0x5b8/0xb00 [kvm_hv] [345523.706087] [c000000399467b90] [c0080000085c93cc] kvmppc_vcpu_run+0x34/0x48 [kvm] [345523.706095] [c000000399467bb0] [c0080000085c582c] kvm_arch_vcpu_ioctl_run+0x244/0x420 [kvm] [345523.706101] [c000000399467c40] [c0080000085b7498] kvm_vcpu_ioctl+0x3d0/0x7b0 [kvm] [345523.706105] [c000000399467db0] [c0000000004adf9c] ksys_ioctl+0x13c/0x170 [345523.706107] [c000000399467e00] [c0000000004adff8] sys_ioctl+0x28/0x80 [345523.706111] [c000000399467e20] [c00000000000b278] system_call+0x5c/0x68 [345523.706112] Instruction dump: [345523.706114] 419e0390 7f8a4840 409d0048 6d497c00 2f89075d 419e021c 6d497c00 2f8907dd [345523.706119] 419e01c0 6d497c00 2f8905dd 419e00a4 <0fe00000> 38210040 38600000 ebc1fff0
and then treats the executed instruction as a 'nop'.
However the POWER9 User's Manual, in section "4.6.10 Book II Invalid Forms", informs that for TM instructions bit 31 is in fact ignored, thus for the TM-related invalid forms ignoring bit 31 and handling them like the valid forms is an acceptable way to handle them. POWER8 behaves the same way too.
This commit changes the handling of the cases here described by treating the TM-related invalid forms that can generate a softpatch interrupt just like their valid forms (w/ bit 31 = 1) instead of as a 'nop' and by gently reporting any other unrecognized case to the host and treating it as illegal instruction instead of throwing a trace and treating it as a 'nop'.
Signed-off-by: Gustavo Romero gromero@linux.ibm.com Reviewed-by: Segher Boessenkool segher@kernel.crashing.org Acked-By: Michael Neuling mikey@neuling.org Reviewed-by: Leonardo Bras leonardo@linux.ibm.com Signed-off-by: Paul Mackerras paulus@ozlabs.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/include/asm/kvm_asm.h | 3 +++ arch/powerpc/kvm/book3s_hv_tm.c | 28 ++++++++++++++++++++----- arch/powerpc/kvm/book3s_hv_tm_builtin.c | 16 ++++++++++++-- 3 files changed, 40 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h index a790d5cf6ea37..684e8ae00d160 100644 --- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h @@ -163,4 +163,7 @@
#define KVM_INST_FETCH_FAILED -1
+/* Extract PO and XOP opcode fields */ +#define PO_XOP_OPCODE_MASK 0xfc0007fe + #endif /* __POWERPC_KVM_ASM_H__ */ diff --git a/arch/powerpc/kvm/book3s_hv_tm.c b/arch/powerpc/kvm/book3s_hv_tm.c index 31cd0f327c8a2..e7fd60cf97804 100644 --- a/arch/powerpc/kvm/book3s_hv_tm.c +++ b/arch/powerpc/kvm/book3s_hv_tm.c @@ -6,6 +6,8 @@ * published by the Free Software Foundation. */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kvm_host.h>
#include <asm/kvm_ppc.h> @@ -47,7 +49,18 @@ int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu) u64 newmsr, bescr; int ra, rs;
- switch (instr & 0xfc0007ff) { + /* + * rfid, rfebb, and mtmsrd encode bit 31 = 0 since it's a reserved bit + * in these instructions, so masking bit 31 out doesn't change these + * instructions. For treclaim., tsr., and trechkpt. instructions if bit + * 31 = 0 then they are per ISA invalid forms, however P9 UM, in section + * 4.6.10 Book II Invalid Forms, informs specifically that ignoring bit + * 31 is an acceptable way to handle these invalid forms that have + * bit 31 = 0. Moreover, for emulation purposes both forms (w/ and wo/ + * bit 31 set) can generate a softpatch interrupt. Hence both forms + * are handled below for these instructions so they behave the same way. + */ + switch (instr & PO_XOP_OPCODE_MASK) { case PPC_INST_RFID: /* XXX do we need to check for PR=0 here? */ newmsr = vcpu->arch.shregs.srr1; @@ -108,7 +121,8 @@ int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu) vcpu->arch.shregs.msr = newmsr; return RESUME_GUEST;
- case PPC_INST_TSR: + /* ignore bit 31, see comment above */ + case (PPC_INST_TSR & PO_XOP_OPCODE_MASK): /* check for PR=1 and arch 2.06 bit set in PCR */ if ((msr & MSR_PR) && (vcpu->arch.vcore->pcr & PCR_ARCH_206)) { /* generate an illegal instruction interrupt */ @@ -143,7 +157,8 @@ int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu) vcpu->arch.shregs.msr = msr; return RESUME_GUEST;
- case PPC_INST_TRECLAIM: + /* ignore bit 31, see comment above */ + case (PPC_INST_TRECLAIM & PO_XOP_OPCODE_MASK): /* check for TM disabled in the HFSCR or MSR */ if (!(vcpu->arch.hfscr & HFSCR_TM)) { /* generate an illegal instruction interrupt */ @@ -179,7 +194,8 @@ int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu) vcpu->arch.shregs.msr &= ~MSR_TS_MASK; return RESUME_GUEST;
- case PPC_INST_TRECHKPT: + /* ignore bit 31, see comment above */ + case (PPC_INST_TRECHKPT & PO_XOP_OPCODE_MASK): /* XXX do we need to check for PR=0 here? */ /* check for TM disabled in the HFSCR or MSR */ if (!(vcpu->arch.hfscr & HFSCR_TM)) { @@ -211,6 +227,8 @@ int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu) }
/* What should we do here? We didn't recognize the instruction */ - WARN_ON_ONCE(1); + kvmppc_core_queue_program(vcpu, SRR1_PROGILL); + pr_warn_ratelimited("Unrecognized TM-related instruction %#x for emulation", instr); + return RESUME_GUEST; } diff --git a/arch/powerpc/kvm/book3s_hv_tm_builtin.c b/arch/powerpc/kvm/book3s_hv_tm_builtin.c index 3cf5863bc06e8..3c7ca2fa19597 100644 --- a/arch/powerpc/kvm/book3s_hv_tm_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_tm_builtin.c @@ -26,7 +26,18 @@ int kvmhv_p9_tm_emulation_early(struct kvm_vcpu *vcpu) u64 newmsr, msr, bescr; int rs;
- switch (instr & 0xfc0007ff) { + /* + * rfid, rfebb, and mtmsrd encode bit 31 = 0 since it's a reserved bit + * in these instructions, so masking bit 31 out doesn't change these + * instructions. For the tsr. instruction if bit 31 = 0 then it is per + * ISA an invalid form, however P9 UM, in section 4.6.10 Book II Invalid + * Forms, informs specifically that ignoring bit 31 is an acceptable way + * to handle TM-related invalid forms that have bit 31 = 0. Moreover, + * for emulation purposes both forms (w/ and wo/ bit 31 set) can + * generate a softpatch interrupt. Hence both forms are handled below + * for tsr. to make them behave the same way. + */ + switch (instr & PO_XOP_OPCODE_MASK) { case PPC_INST_RFID: /* XXX do we need to check for PR=0 here? */ newmsr = vcpu->arch.shregs.srr1; @@ -76,7 +87,8 @@ int kvmhv_p9_tm_emulation_early(struct kvm_vcpu *vcpu) vcpu->arch.shregs.msr = newmsr; return 1;
- case PPC_INST_TSR: + /* ignore bit 31, see comment above */ + case (PPC_INST_TSR & PO_XOP_OPCODE_MASK): /* we know the MSR has the TS field = S (0b01) here */ msr = vcpu->arch.shregs.msr; /* check for PR=1 and arch 2.06 bit set in PCR */
From: Pavel Machek pavel@denx.de
[ Upstream commit 66be340f827554cb1c8a1ed7dea97920b4085af2 ]
We should free resources in unlikely case of allocation failure.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/msm_drv.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 6f81de85fb860..01524009dede8 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -495,8 +495,10 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) if (!dev->dma_parms) { dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), GFP_KERNEL); - if (!dev->dma_parms) - return -ENOMEM; + if (!dev->dma_parms) { + ret = -ENOMEM; + goto err_msm_uninit; + } } dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
From: Jordan Crouse jcrouse@codeaurora.org
[ Upstream commit 0478b4fc5f37f4d494245fe7bcce3f531cf380e9 ]
If the opp table specifies opp-supported-hw as a property but the driver has not set a supported hardware value the OPP subsystem will reject all the table entries.
Set a "default" value that will match the default table entries but not conflict with any possible real bin values. Also fix a small memory leak and free the buffer allocated by nvmem_cell_read().
Signed-off-by: Jordan Crouse jcrouse@codeaurora.org Reviewed-by: Eric Anholt eric@anholt.net Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index ba6f3c14495c0..dd298abc5f393 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1474,18 +1474,31 @@ static const struct adreno_gpu_funcs funcs = { static void check_speed_bin(struct device *dev) { struct nvmem_cell *cell; - u32 bin, val; + u32 val; + + /* + * If the OPP table specifies a opp-supported-hw property then we have + * to set something with dev_pm_opp_set_supported_hw() or the table + * doesn't get populated so pick an arbitrary value that should + * ensure the default frequencies are selected but not conflict with any + * actual bins + */ + val = 0x80;
cell = nvmem_cell_get(dev, "speed_bin");
- /* If a nvmem cell isn't defined, nothing to do */ - if (IS_ERR(cell)) - return; + if (!IS_ERR(cell)) { + void *buf = nvmem_cell_read(cell, NULL); + + if (!IS_ERR(buf)) { + u8 bin = *((u8 *) buf);
- bin = *((u32 *) nvmem_cell_read(cell, NULL)); - nvmem_cell_put(cell); + val = (1 << bin); + kfree(buf); + }
- val = (1 << bin); + nvmem_cell_put(cell); + }
dev_pm_opp_set_supported_hw(dev, &val, 1); }
From: Kevin Hao haokexin@gmail.com
[ Upstream commit 1413ef638abae4ab5621901cf4d8ef08a4a48ba6 ]
The struct cdev is embedded in the struct i2c_dev. In the current code, we would free the i2c_dev struct directly in put_i2c_dev(), but the cdev is manged by a kobject, and the release of it is not predictable. So it is very possible that the i2c_dev is freed before the cdev is entirely released. We can easily get the following call trace with CONFIG_DEBUG_KOBJECT_RELEASE and CONFIG_DEBUG_OBJECTS_TIMERS enabled. ODEBUG: free active (active state 0) object type: timer_list hint: delayed_work_timer_fn+0x0/0x38 WARNING: CPU: 19 PID: 1 at lib/debugobjects.c:325 debug_print_object+0xb0/0xf0 Modules linked in: CPU: 19 PID: 1 Comm: swapper/0 Tainted: G W 5.2.20-yocto-standard+ #120 Hardware name: Marvell OcteonTX CN96XX board (DT) pstate: 80c00089 (Nzcv daIf +PAN +UAO) pc : debug_print_object+0xb0/0xf0 lr : debug_print_object+0xb0/0xf0 sp : ffff00001292f7d0 x29: ffff00001292f7d0 x28: ffff800b82151788 x27: 0000000000000001 x26: ffff800b892c0000 x25: ffff0000124a2558 x24: 0000000000000000 x23: ffff00001107a1d8 x22: ffff0000116b5088 x21: ffff800bdc6afca8 x20: ffff000012471ae8 x19: ffff00001168f2c8 x18: 0000000000000010 x17: 00000000fd6f304b x16: 00000000ee79de43 x15: ffff800bc0e80568 x14: 79616c6564203a74 x13: 6e6968207473696c x12: 5f72656d6974203a x11: ffff0000113f0018 x10: 0000000000000000 x9 : 000000000000001f x8 : 0000000000000000 x7 : ffff0000101294cc x6 : 0000000000000000 x5 : 0000000000000000 x4 : 0000000000000001 x3 : 00000000ffffffff x2 : 0000000000000000 x1 : 387fc15c8ec0f200 x0 : 0000000000000000 Call trace: debug_print_object+0xb0/0xf0 __debug_check_no_obj_freed+0x19c/0x228 debug_check_no_obj_freed+0x1c/0x28 kfree+0x250/0x440 put_i2c_dev+0x68/0x78 i2cdev_detach_adapter+0x60/0xc8 i2cdev_notifier_call+0x3c/0x70 notifier_call_chain+0x8c/0xe8 blocking_notifier_call_chain+0x64/0x88 device_del+0x74/0x380 device_unregister+0x54/0x78 i2c_del_adapter+0x278/0x2d0 unittest_i2c_bus_remove+0x3c/0x80 platform_drv_remove+0x30/0x50 device_release_driver_internal+0xf4/0x1c0 driver_detach+0x58/0xa0 bus_remove_driver+0x84/0xd8 driver_unregister+0x34/0x60 platform_driver_unregister+0x20/0x30 of_unittest_overlay+0x8d4/0xbe0 of_unittest+0xae8/0xb3c do_one_initcall+0xac/0x450 do_initcall_level+0x208/0x224 kernel_init_freeable+0x2d8/0x36c kernel_init+0x18/0x108 ret_from_fork+0x10/0x1c irq event stamp: 3934661 hardirqs last enabled at (3934661): [<ffff00001009fa04>] debug_exception_exit+0x4c/0x58 hardirqs last disabled at (3934660): [<ffff00001009fb14>] debug_exception_enter+0xa4/0xe0 softirqs last enabled at (3934654): [<ffff000010081d94>] __do_softirq+0x46c/0x628 softirqs last disabled at (3934649): [<ffff0000100b4a1c>] irq_exit+0x104/0x118
This is a common issue when using cdev embedded in a struct. Fortunately, we already have a mechanism to solve this kind of issue. Please see commit 233ed09d7fda ("chardev: add helper function to register char devs with a struct device") for more detail.
In this patch, we choose to embed the struct device into the i2c_dev, and use the API provided by the commit 233ed09d7fda to make sure that the release of i2c_dev and cdev are in sequence.
Signed-off-by: Kevin Hao haokexin@gmail.com Signed-off-by: Wolfram Sang wsa@the-dreams.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/i2c-dev.c | 48 +++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 22 deletions(-)
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index cb07651f4b467..cbda91a0cb5f8 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -48,7 +48,7 @@ struct i2c_dev { struct list_head list; struct i2c_adapter *adap; - struct device *dev; + struct device dev; struct cdev cdev; };
@@ -92,12 +92,14 @@ static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap) return i2c_dev; }
-static void put_i2c_dev(struct i2c_dev *i2c_dev) +static void put_i2c_dev(struct i2c_dev *i2c_dev, bool del_cdev) { spin_lock(&i2c_dev_list_lock); list_del(&i2c_dev->list); spin_unlock(&i2c_dev_list_lock); - kfree(i2c_dev); + if (del_cdev) + cdev_device_del(&i2c_dev->cdev, &i2c_dev->dev); + put_device(&i2c_dev->dev); }
static ssize_t name_show(struct device *dev, @@ -636,6 +638,14 @@ static const struct file_operations i2cdev_fops = {
static struct class *i2c_dev_class;
+static void i2cdev_dev_release(struct device *dev) +{ + struct i2c_dev *i2c_dev; + + i2c_dev = container_of(dev, struct i2c_dev, dev); + kfree(i2c_dev); +} + static int i2cdev_attach_adapter(struct device *dev, void *dummy) { struct i2c_adapter *adap; @@ -652,27 +662,23 @@ static int i2cdev_attach_adapter(struct device *dev, void *dummy)
cdev_init(&i2c_dev->cdev, &i2cdev_fops); i2c_dev->cdev.owner = THIS_MODULE; - res = cdev_add(&i2c_dev->cdev, MKDEV(I2C_MAJOR, adap->nr), 1); - if (res) - goto error_cdev; - - /* register this i2c device with the driver core */ - i2c_dev->dev = device_create(i2c_dev_class, &adap->dev, - MKDEV(I2C_MAJOR, adap->nr), NULL, - "i2c-%d", adap->nr); - if (IS_ERR(i2c_dev->dev)) { - res = PTR_ERR(i2c_dev->dev); - goto error; + + device_initialize(&i2c_dev->dev); + i2c_dev->dev.devt = MKDEV(I2C_MAJOR, adap->nr); + i2c_dev->dev.class = i2c_dev_class; + i2c_dev->dev.parent = &adap->dev; + i2c_dev->dev.release = i2cdev_dev_release; + dev_set_name(&i2c_dev->dev, "i2c-%d", adap->nr); + + res = cdev_device_add(&i2c_dev->cdev, &i2c_dev->dev); + if (res) { + put_i2c_dev(i2c_dev, false); + return res; }
pr_debug("i2c-dev: adapter [%s] registered as minor %d\n", adap->name, adap->nr); return 0; -error: - cdev_del(&i2c_dev->cdev); -error_cdev: - put_i2c_dev(i2c_dev); - return res; }
static int i2cdev_detach_adapter(struct device *dev, void *dummy) @@ -688,9 +694,7 @@ static int i2cdev_detach_adapter(struct device *dev, void *dummy) if (!i2c_dev) /* attach_adapter must have failed */ return 0;
- cdev_del(&i2c_dev->cdev); - put_i2c_dev(i2c_dev); - device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); + put_i2c_dev(i2c_dev, true);
pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); return 0;
From: Raveendran Somu raveendran.somu@cypress.com
[ Upstream commit 93a5bfbc7cad8bf3dea81c9bc07761c1226a0860 ]
When the control transfer gets timed out, the error status was returned without killing that urb, this leads to using the same urb. This issue causes the kernel crash as the same urb is sumbitted multiple times. The fix is to kill the urb for timeout transfer before returning error
Signed-off-by: Raveendran Somu raveendran.somu@cypress.com Signed-off-by: Chi-hsien Lin chi-hsien.lin@cypress.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1585124429-97371-2-git-send-email-chi-hsien.lin@cy... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index 41254f04ab152..f395ea0b73e7d 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -339,11 +339,12 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len) return err; } timeout = brcmf_usb_ioctl_resp_wait(devinfo); - clear_bit(0, &devinfo->ctl_op); if (!timeout) { brcmf_err("Txctl wait timed out\n"); + usb_kill_urb(devinfo->ctl_urb); err = -EIO; } + clear_bit(0, &devinfo->ctl_op); return err; }
@@ -369,11 +370,12 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len) } timeout = brcmf_usb_ioctl_resp_wait(devinfo); err = devinfo->ctl_urb_status; - clear_bit(0, &devinfo->ctl_op); if (!timeout) { brcmf_err("rxctl wait timed out\n"); + usb_kill_urb(devinfo->ctl_urb); err = -EIO; } + clear_bit(0, &devinfo->ctl_op); if (!err) return devinfo->ctl_urb_actual_length; else
From: Avihai Horon avihaih@mellanox.com
[ Upstream commit 987914ab841e2ec281a35b54348ab109b4c0bb4e ]
After a successful allocation of path_rec, num_paths is set to 1, but any error after such allocation will leave num_paths uncleared.
This causes to de-referencing a NULL pointer later on. Hence, num_paths needs to be set back to 0 if such an error occurs.
The following crash from syzkaller revealed it.
kasan: CONFIG_KASAN_INLINE enabled kasan: GPF could be caused by NULL-ptr deref or user memory access general protection fault: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN PTI CPU: 0 PID: 357 Comm: syz-executor060 Not tainted 4.18.0+ #311 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.0-0-g63451fca13-prebuilt.qemu-project.org 04/01/2014 RIP: 0010:ib_copy_path_rec_to_user+0x94/0x3e0 Code: f1 f1 f1 f1 c7 40 0c 00 00 f4 f4 65 48 8b 04 25 28 00 00 00 48 89 45 c8 31 c0 e8 d7 60 24 ff 48 8d 7b 4c 48 89 f8 48 c1 e8 03 <42> 0f b6 14 30 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 RSP: 0018:ffff88006586f980 EFLAGS: 00010207 RAX: 0000000000000009 RBX: 0000000000000000 RCX: 1ffff1000d5fe475 RDX: ffff8800621e17c0 RSI: ffffffff820d45f9 RDI: 000000000000004c RBP: ffff88006586fa50 R08: ffffed000cb0df73 R09: ffffed000cb0df72 R10: ffff88006586fa70 R11: ffffed000cb0df73 R12: 1ffff1000cb0df30 R13: ffff88006586fae8 R14: dffffc0000000000 R15: ffff88006aff2200 FS: 00000000016fc880(0000) GS:ffff88006d000000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000020000040 CR3: 0000000063fec000 CR4: 00000000000006b0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: ? ib_copy_path_rec_from_user+0xcc0/0xcc0 ? __mutex_unlock_slowpath+0xfc/0x670 ? wait_for_completion+0x3b0/0x3b0 ? ucma_query_route+0x818/0xc60 ucma_query_route+0x818/0xc60 ? ucma_listen+0x1b0/0x1b0 ? sched_clock_cpu+0x18/0x1d0 ? sched_clock_cpu+0x18/0x1d0 ? ucma_listen+0x1b0/0x1b0 ? ucma_write+0x292/0x460 ucma_write+0x292/0x460 ? ucma_close_id+0x60/0x60 ? sched_clock_cpu+0x18/0x1d0 ? sched_clock_cpu+0x18/0x1d0 __vfs_write+0xf7/0x620 ? ucma_close_id+0x60/0x60 ? kernel_read+0x110/0x110 ? time_hardirqs_on+0x19/0x580 ? lock_acquire+0x18b/0x3a0 ? finish_task_switch+0xf3/0x5d0 ? _raw_spin_unlock_irq+0x29/0x40 ? _raw_spin_unlock_irq+0x29/0x40 ? finish_task_switch+0x1be/0x5d0 ? __switch_to_asm+0x34/0x70 ? __switch_to_asm+0x40/0x70 ? security_file_permission+0x172/0x1e0 vfs_write+0x192/0x460 ksys_write+0xc6/0x1a0 ? __ia32_sys_read+0xb0/0xb0 ? entry_SYSCALL_64_after_hwframe+0x3e/0xbe ? do_syscall_64+0x1d/0x470 do_syscall_64+0x9e/0x470 entry_SYSCALL_64_after_hwframe+0x49/0xbe
Fixes: 3c86aa70bf67 ("RDMA/cm: Add RDMA CM support for IBoE devices") Link: https://lore.kernel.org/r/20200318101741.47211-1-leon@kernel.org Signed-off-by: Avihai Horon avihaih@mellanox.com Reviewed-by: Maor Gottlieb maorg@mellanox.com Signed-off-by: Leon Romanovsky leonro@mellanox.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/core/cma.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index e16872e0724ff..47d6fabd82aaf 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -2753,6 +2753,7 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) err2: kfree(route->path_rec); route->path_rec = NULL; + route->num_paths = 0; err1: kfree(work); return ret;
From: Rohit Maheshwari rohitm@chelsio.com
[ Upstream commit 3a0a978389234995b64a8b8fbe343115bffb1551 ]
There is a possibility that cdev is removed before CPL_ABORT_REQ_RSS is fully processed, so it's better to save it in skb.
Added checks in handling the flow correctly, which suggests connection reset request is sent to HW, wait for HW to respond.
Signed-off-by: Rohit Maheshwari rohitm@chelsio.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/chelsio/chtls/chtls_cm.c | 29 +++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/drivers/crypto/chelsio/chtls/chtls_cm.c b/drivers/crypto/chelsio/chtls/chtls_cm.c index 28d24118c6450..6727a96e58966 100644 --- a/drivers/crypto/chelsio/chtls/chtls_cm.c +++ b/drivers/crypto/chelsio/chtls/chtls_cm.c @@ -449,6 +449,7 @@ void chtls_destroy_sock(struct sock *sk) chtls_purge_write_queue(sk); free_tls_keyid(sk); kref_put(&csk->kref, chtls_sock_release); + csk->cdev = NULL; sk->sk_prot = &tcp_prot; sk->sk_prot->destroy(sk); } @@ -763,8 +764,10 @@ static void chtls_release_resources(struct sock *sk) csk->l2t_entry = NULL; }
- cxgb4_remove_tid(tids, csk->port_id, tid, sk->sk_family); - sock_put(sk); + if (sk->sk_state != TCP_SYN_SENT) { + cxgb4_remove_tid(tids, csk->port_id, tid, sk->sk_family); + sock_put(sk); + } }
static void chtls_conn_done(struct sock *sk) @@ -1695,6 +1698,9 @@ static void chtls_peer_close(struct sock *sk, struct sk_buff *skb) { struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
+ if (csk_flag_nochk(csk, CSK_ABORT_RPL_PENDING)) + goto out; + sk->sk_shutdown |= RCV_SHUTDOWN; sock_set_flag(sk, SOCK_DONE);
@@ -1727,6 +1733,7 @@ static void chtls_peer_close(struct sock *sk, struct sk_buff *skb) else sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); } +out: kfree_skb(skb); }
@@ -1737,6 +1744,10 @@ static void chtls_close_con_rpl(struct sock *sk, struct sk_buff *skb) struct tcp_sock *tp;
csk = rcu_dereference_sk_user_data(sk); + + if (csk_flag_nochk(csk, CSK_ABORT_RPL_PENDING)) + goto out; + tp = tcp_sk(sk);
tp->snd_una = ntohl(rpl->snd_nxt) - 1; /* exclude FIN */ @@ -1766,6 +1777,7 @@ static void chtls_close_con_rpl(struct sock *sk, struct sk_buff *skb) default: pr_info("close_con_rpl in bad state %d\n", sk->sk_state); } +out: kfree_skb(skb); }
@@ -1875,6 +1887,7 @@ static void chtls_send_abort_rpl(struct sock *sk, struct sk_buff *skb, }
set_abort_rpl_wr(reply_skb, tid, status); + kfree_skb(skb); set_wr_txq(reply_skb, CPL_PRIORITY_DATA, queue); if (csk_conn_inline(csk)) { struct l2t_entry *e = csk->l2t_entry; @@ -1885,7 +1898,6 @@ static void chtls_send_abort_rpl(struct sock *sk, struct sk_buff *skb, } } cxgb4_ofld_send(cdev->lldi->ports[0], reply_skb); - kfree_skb(skb); }
/* @@ -1987,7 +1999,8 @@ static void chtls_abort_req_rss(struct sock *sk, struct sk_buff *skb) chtls_conn_done(sk); }
- chtls_send_abort_rpl(sk, skb, csk->cdev, rst_status, queue); + chtls_send_abort_rpl(sk, skb, BLOG_SKB_CB(skb)->cdev, + rst_status, queue); }
static void chtls_abort_rpl_rss(struct sock *sk, struct sk_buff *skb) @@ -2021,6 +2034,7 @@ static int chtls_conn_cpl(struct chtls_dev *cdev, struct sk_buff *skb) struct cpl_peer_close *req = cplhdr(skb) + RSS_HDR; void (*fn)(struct sock *sk, struct sk_buff *skb); unsigned int hwtid = GET_TID(req); + struct chtls_sock *csk; struct sock *sk; u8 opcode;
@@ -2030,6 +2044,8 @@ static int chtls_conn_cpl(struct chtls_dev *cdev, struct sk_buff *skb) if (!sk) goto rel_skb;
+ csk = sk->sk_user_data; + switch (opcode) { case CPL_PEER_CLOSE: fn = chtls_peer_close; @@ -2038,6 +2054,11 @@ static int chtls_conn_cpl(struct chtls_dev *cdev, struct sk_buff *skb) fn = chtls_close_con_rpl; break; case CPL_ABORT_REQ_RSS: + /* + * Save the offload device in the skb, we may process this + * message after the socket has closed. + */ + BLOG_SKB_CB(skb)->cdev = csk->cdev; fn = chtls_abort_req_rss; break; case CPL_ABORT_RPL_RSS:
From: Cezary Rojewski cezary.rojewski@intel.com
[ Upstream commit e603f11d5df8997d104ab405ff27640b90baffaa ]
Follow the recommendation set by hda_intel.c and enable HDMI/DP codec wakeup during bus initialization procedure. Disable wakeup once init completes.
Signed-off-by: Cezary Rojewski cezary.rojewski@intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20200305145314.32579-4-cezary.rojewski@intel.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/skylake/skl.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 50f16a0f6535f..463078c2346f9 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -128,6 +128,7 @@ static int skl_init_chip(struct hdac_bus *bus, bool full_reset) struct hdac_ext_link *hlink; int ret;
+ snd_hdac_set_codec_wakeup(bus, true); skl_enable_miscbdcge(bus->dev, false); ret = snd_hdac_bus_init_chip(bus, full_reset);
@@ -136,6 +137,7 @@ static int skl_init_chip(struct hdac_bus *bus, bool full_reset) bus->io_ops->reg_writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
skl_enable_miscbdcge(bus->dev, true); + snd_hdac_set_codec_wakeup(bus, false);
return ret; }
From: Quinn Tran qutran@marvell.com
[ Upstream commit ce1ee122e0f048fc67c1259489f0802a28049bfd ]
This patch fixes issue where current and original exchanges count were swapped for intiator and targets.
Also fix IOCB count for current and original which were swapped.
Link: https://lore.kernel.org/r/20200226224022.24518-9-hmadhani@marvell.com Signed-off-by: Himanshu Madhani hmadhani@marvell.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_dfs.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c index 0b190082aa8d9..4c917e43509a5 100644 --- a/drivers/scsi/qla2xxx/qla_dfs.c +++ b/drivers/scsi/qla2xxx/qla_dfs.c @@ -136,11 +136,11 @@ qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused) } else { seq_puts(s, "FW Resource count\n\n"); seq_printf(s, "Original TGT exchg count[%d]\n", mb[1]); - seq_printf(s, "current TGT exchg count[%d]\n", mb[2]); - seq_printf(s, "original Initiator Exchange count[%d]\n", mb[3]); - seq_printf(s, "Current Initiator Exchange count[%d]\n", mb[6]); - seq_printf(s, "Original IOCB count[%d]\n", mb[7]); - seq_printf(s, "Current IOCB count[%d]\n", mb[10]); + seq_printf(s, "Current TGT exchg count[%d]\n", mb[2]); + seq_printf(s, "Current Initiator Exchange count[%d]\n", mb[3]); + seq_printf(s, "Original Initiator Exchange count[%d]\n", mb[6]); + seq_printf(s, "Current IOCB count[%d]\n", mb[7]); + seq_printf(s, "Original IOCB count[%d]\n", mb[10]); seq_printf(s, "MAX VP count[%d]\n", mb[11]); seq_printf(s, "MAX FCF count[%d]\n", mb[12]); seq_printf(s, "Current free pageable XCB buffer cnt[%d]\n", @@ -151,7 +151,6 @@ qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused) mb[22]); seq_printf(s, "Original Target fast XCB buffer cnt[%d]\n", mb[23]); - }
return 0;
From: Patrick Daly pdaly@codeaurora.org
[ Upstream commit 632c99084052aef1c9dcfe43d2720306026d6d21 ]
Certain SoCs need to support a large amount of reserved memory regions. For example, Qualcomm's SM8150 SoC requires that 20 regions of memory be reserved for a variety of reasons (e.g. loading a peripheral subsystem's firmware image into a particular space).
When adding more reserved memory regions to cater to different usecases, the remaining number of reserved memory regions--12 to be exact--becomes too small. Thus, double the existing limit of reserved memory regions.
Signed-off-by: Patrick Daly pdaly@codeaurora.org Signed-off-by: Isaac J. Manjarres isaacm@codeaurora.org Signed-off-by: Rob Herring robh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/of/of_reserved_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index 895c83e0c7b6c..794308b3b8b9a 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -21,7 +21,7 @@ #include <linux/sort.h> #include <linux/slab.h>
-#define MAX_RESERVED_REGIONS 32 +#define MAX_RESERVED_REGIONS 64 static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS]; static int reserved_mem_count;
From: Etienne Carriere etienne.carriere@st.com
[ Upstream commit 8cf1e0fc50fcc25021567bb2755580504c57c83a ]
Remove reset controller reference from device instance since it is used only at probe time.
Signed-off-by: Etienne Carriere etienne.carriere@st.com Signed-off-by: Amelie Delaunay amelie.delaunay@st.com Link: https://lore.kernel.org/r/20200129153628.29329-3-amelie.delaunay@st.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/stm32-dma.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c index 4903a408fc146..e58cee8ec2410 100644 --- a/drivers/dma/stm32-dma.c +++ b/drivers/dma/stm32-dma.c @@ -207,7 +207,6 @@ struct stm32_dma_device { struct dma_device ddev; void __iomem *base; struct clk *clk; - struct reset_control *rst; bool mem2mem; struct stm32_dma_chan chan[STM32_DMA_MAX_CHANNELS]; }; @@ -1215,6 +1214,7 @@ static int stm32_dma_probe(struct platform_device *pdev) struct dma_device *dd; const struct of_device_id *match; struct resource *res; + struct reset_control *rst; int i, ret;
match = of_match_device(stm32_dma_of_match, &pdev->dev); @@ -1243,11 +1243,11 @@ static int stm32_dma_probe(struct platform_device *pdev) dmadev->mem2mem = of_property_read_bool(pdev->dev.of_node, "st,mem2mem");
- dmadev->rst = devm_reset_control_get(&pdev->dev, NULL); - if (!IS_ERR(dmadev->rst)) { - reset_control_assert(dmadev->rst); + rst = devm_reset_control_get(&pdev->dev, NULL); + if (!IS_ERR(rst)) { + reset_control_assert(rst); udelay(2); - reset_control_deassert(dmadev->rst); + reset_control_deassert(rst); }
dma_cap_set(DMA_SLAVE, dd->cap_mask);
From: Himanshu Madhani hmadhani@marvell.com
[ Upstream commit 345f574dac85276d1471492c6e90c57e3f90a4f3 ]
This patch fixes:
- qla2x00_issue_iocb_timeout will now return if chip is down
- only check for sp->qpair in abort handling
Link: https://lore.kernel.org/r/20200212214436.25532-24-hmadhani@marvell.com Signed-off-by: Himanshu Madhani hmadhani@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_mbx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index bef9faea5eeeb..0def2f7a8af28 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -1366,6 +1366,9 @@ qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc;
+ if (qla2x00_chip_is_down(vha)) + return QLA_INVALID_COMMAND; + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1038, "Entered %s.\n", __func__);
@@ -1436,7 +1439,7 @@ qla2x00_abort_command(srb_t *sp) ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103b, "Entered %s.\n", __func__);
- if (vha->flags.qpairs_available && sp->qpair) + if (sp->qpair) req = sp->qpair->req; else req = vha->req;
From: Himanshu Madhani hmadhani@marvell.com
[ Upstream commit 419ae5fe73e50084fa794934fb62fab34f564b7c ]
This patch fixes control flag options for login/logout IOCB.
Link: https://lore.kernel.org/r/20200212214436.25532-23-hmadhani@marvell.com Signed-off-by: Himanshu Madhani hmadhani@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_iocb.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 7e47321e003c8..f07aa045f3f93 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -2224,6 +2224,8 @@ qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio) struct srb_iocb *lio = &sp->u.iocb_cmd;
logio->entry_type = LOGINOUT_PORT_IOCB_TYPE; + logio->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI); + if (lio->u.logio.flags & SRB_LOGIN_PRLI_ONLY) { logio->control_flags = cpu_to_le16(LCF_COMMAND_PRLI); } else { @@ -2663,7 +2665,6 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, sp->fcport = fcport;
elsio->timeout = qla2x00_els_dcmd2_iocb_timeout; - init_completion(&elsio->u.els_plogi.comp); if (wait) sp->flags = SRB_WAKEUP_ON_COMP;
@@ -2673,7 +2674,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, elsio->u.els_plogi.tx_size = elsio->u.els_plogi.rx_size = DMA_POOL_SIZE;
ptr = elsio->u.els_plogi.els_plogi_pyld = - dma_alloc_coherent(&ha->pdev->dev, DMA_POOL_SIZE, + dma_alloc_coherent(&ha->pdev->dev, elsio->u.els_plogi.tx_size, &elsio->u.els_plogi.els_plogi_pyld_dma, GFP_KERNEL); ptr_dma = elsio->u.els_plogi.els_plogi_pyld_dma;
@@ -2683,7 +2684,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, }
resp_ptr = elsio->u.els_plogi.els_resp_pyld = - dma_alloc_coherent(&ha->pdev->dev, DMA_POOL_SIZE, + dma_alloc_coherent(&ha->pdev->dev, elsio->u.els_plogi.rx_size, &elsio->u.els_plogi.els_resp_pyld_dma, GFP_KERNEL);
if (!elsio->u.els_plogi.els_resp_pyld) { @@ -2707,6 +2708,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, (uint8_t *)elsio->u.els_plogi.els_plogi_pyld, sizeof(*elsio->u.els_plogi.els_plogi_pyld));
+ init_completion(&elsio->u.els_plogi.comp); rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) { rval = QLA_FUNCTION_FAILED;
From: Can Guo cang@codeaurora.org
[ Upstream commit c63d6099a7959ecc919b2549dc6b71f53521f819 ]
The async version of ufshcd_hold(async == true), which is only called in queuecommand path as for now, is expected to work in atomic context, thus it should not sleep or schedule out. When it runs into the condition that clocks are ON but link is still in hibern8 state, it should bail out without flushing the clock ungate work.
Fixes: f2a785ac2312 ("scsi: ufshcd: Fix race between clk scaling and ungate work") Link: https://lore.kernel.org/r/1581392451-28743-6-git-send-email-cang@codeaurora.... Reviewed-by: Hongwu Su hongwus@codeaurora.org Reviewed-by: Asutosh Das asutoshd@codeaurora.org Reviewed-by: Bean Huo beanhuo@micron.com Reviewed-by: Stanley Chu stanley.chu@mediatek.com Signed-off-by: Can Guo cang@codeaurora.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ufshcd.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index b3dee24917a86..d91209ba18c86 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1563,6 +1563,11 @@ int ufshcd_hold(struct ufs_hba *hba, bool async) */ if (ufshcd_can_hibern8_during_gating(hba) && ufshcd_is_link_hibern8(hba)) { + if (async) { + rc = -EAGAIN; + hba->clk_gating.active_reqs--; + break; + } spin_unlock_irqrestore(hba->host->host_lock, flags); flush_work(&hba->clk_gating.ungate_work); spin_lock_irqsave(hba->host->host_lock, flags);
From: John Garry john.garry@huawei.com
[ Upstream commit a6dd255bdd7d00bbdbf78ba00bde9fc64f86c3a7 ]
Some released ACPI FW for Huawei boards describes incorrect the port IO address range for child devices, in that it tells us the IO port max range is 0x3fff for each child device, which is not correct. The address range should be [e4:e8) or similar. With this incorrect upper range, the child device IO port resources overlap.
As such, the kernel thinks that the LPC host serial device is a child of the IPMI device:
root@(none)$ more /proc/ioports [...] 00ffc0e3-00ffffff : hisi-lpc-ipmi.0.auto 00ffc0e3-00ffc0e3 : ipmi_si 00ffc0e4-00ffc0e4 : ipmi_si 00ffc0e5-00ffc0e5 : ipmi_si 00ffc2f7-00ffffff : serial8250.1.auto 00ffc2f7-00ffc2fe : serial root@(none)$
They should both be siblings. Note that these are logical PIO addresses, which have a direct mapping from the FW IO port ranges.
This shows up as a real issue when we enable CONFIG_KASAN and CONFIG_DEBUG_TEST_DRIVER_REMOVE - we see use-after-free warnings in the host removal path:
================================================================== BUG: KASAN: use-after-free in release_resource+0x38/0xc8 Read of size 8 at addr ffff0026accdbc38 by task swapper/0/1
CPU: 2 PID: 1 Comm: swapper/0 Not tainted 5.5.0-rc6-00001-g68e186e77b5c-dirty #1593 Hardware name: Huawei Taishan 2180 /D03, BIOS Hisilicon D03 IT20 Nemo 2.0 RC0 03/30/2018 Call trace: dump_backtrace+0x0/0x290 show_stack+0x14/0x20 dump_stack+0xf0/0x14c print_address_description.isra.9+0x6c/0x3b8 __kasan_report+0x12c/0x23c kasan_report+0xc/0x18 __asan_load8+0x94/0xb8 release_resource+0x38/0xc8 platform_device_del.part.10+0x80/0xe0 platform_device_unregister+0x20/0x38 hisi_lpc_acpi_remove_subdev+0x10/0x20 device_for_each_child+0xc8/0x128 hisi_lpc_acpi_remove+0x4c/0xa8 hisi_lpc_remove+0xbc/0xc0 platform_drv_remove+0x3c/0x68 really_probe+0x174/0x548 driver_probe_device+0x7c/0x148 device_driver_attach+0x94/0xa0 __driver_attach+0xa4/0x110 bus_for_each_dev+0xe8/0x158 driver_attach+0x30/0x40 bus_add_driver+0x234/0x2f0 driver_register+0xbc/0x1d0 __platform_driver_register+0x7c/0x88 hisi_lpc_driver_init+0x18/0x20 do_one_initcall+0xb4/0x258 kernel_init_freeable+0x248/0x2c0 kernel_init+0x10/0x118 ret_from_fork+0x10/0x1c
...
The issue here is that the kernel created an incorrect parent-child resource dependency between two devices, and references the false parent node when deleting the second child device, when it had been deleted already.
Fix up the child device resources from FW to create proper IO port resource relationships for broken FW.
With this, the IO port layout looks more healthy:
root@(none)$ more /proc/ioports [...] 00ffc0e3-00ffc0e7 : hisi-lpc-ipmi.0.auto 00ffc0e3-00ffc0e3 : ipmi_si 00ffc0e4-00ffc0e4 : ipmi_si 00ffc0e5-00ffc0e5 : ipmi_si 00ffc2f7-00ffc2ff : serial8250.1.auto 00ffc2f7-00ffc2fe : serial
Signed-off-by: John Garry john.garry@huawei.com Signed-off-by: Wei Xu xuwei5@hisilicon.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bus/hisi_lpc.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/drivers/bus/hisi_lpc.c b/drivers/bus/hisi_lpc.c index e31c02dc77709..cbd970fb02f18 100644 --- a/drivers/bus/hisi_lpc.c +++ b/drivers/bus/hisi_lpc.c @@ -358,6 +358,26 @@ static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev, return 0; }
+/* + * Released firmware describes the IO port max address as 0x3fff, which is + * the max host bus address. Fixup to a proper range. This will probably + * never be fixed in firmware. + */ +static void hisi_lpc_acpi_fixup_child_resource(struct device *hostdev, + struct resource *r) +{ + if (r->end != 0x3fff) + return; + + if (r->start == 0xe4) + r->end = 0xe4 + 0x04 - 1; + else if (r->start == 0x2f8) + r->end = 0x2f8 + 0x08 - 1; + else + dev_warn(hostdev, "unrecognised resource %pR to fixup, ignoring\n", + r); +} + /* * hisi_lpc_acpi_set_io_res - set the resources for a child * @child: the device node to be updated the I/O resource @@ -419,8 +439,11 @@ static int hisi_lpc_acpi_set_io_res(struct device *child, return -ENOMEM; } count = 0; - list_for_each_entry(rentry, &resource_list, node) - resources[count++] = *rentry->res; + list_for_each_entry(rentry, &resource_list, node) { + resources[count] = *rentry->res; + hisi_lpc_acpi_fixup_child_resource(hostdev, &resources[count]); + count++; + }
acpi_dev_free_resource_list(&resource_list);
From: Ville Syrjälä ville.syrjala@linux.intel.com
[ Upstream commit 66e4f4a9cc389b277e187c115a285fad2cba5485 ]
cmos_interrupt() isn't always called from hardirq context, so we must use spin_lock_irqsave() & co.
================================ WARNING: inconsistent lock state 5.6.0-rc2-CI-CI_DRM_7981+ #1 Tainted: G U -------------------------------- inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. rtcwake/4315 [HC0[0]:SC0[0]:HE1:SE1] takes: ffffffff82635198 (rtc_lock){?...}, at: cmos_interrupt+0x18/0x100 {IN-HARDIRQ-W} state was registered at: lock_acquire+0xa7/0x1c0 _raw_spin_lock+0x2a/0x40 cmos_interrupt+0x18/0x100 rtc_handler+0x75/0xc0 acpi_ev_fixed_event_detect+0xf9/0x132 acpi_ev_sci_xrupt_handler+0xb/0x28 acpi_irq+0x13/0x30 __handle_irq_event_percpu+0x41/0x2c0 handle_irq_event_percpu+0x2b/0x70 handle_irq_event+0x2f/0x50 handle_fasteoi_irq+0x8e/0x150 do_IRQ+0x7e/0x160 ret_from_intr+0x0/0x35 mwait_idle+0x7e/0x200 do_idle+0x1bb/0x260 cpu_startup_entry+0x14/0x20 start_secondary+0x15f/0x1b0 secondary_startup_64+0xa4/0xb0 irq event stamp: 42003 hardirqs last enabled at (42003): [<ffffffff81a36567>] _raw_spin_unlock_irqrestore+0x47/0x60 hardirqs last disabled at (42002): [<ffffffff81a362ed>] _raw_spin_lock_irqsave+0xd/0x50 softirqs last enabled at (41848): [<ffffffff81e00385>] __do_softirq+0x385/0x47f softirqs last disabled at (41841): [<ffffffff810bab3a>] irq_exit+0xba/0xc0
other info that might help us debug this: Possible unsafe locking scenario:
CPU0 ---- lock(rtc_lock); <Interrupt> lock(rtc_lock);
*** DEADLOCK ***
6 locks held by rtcwake/4315: #0: ffff888175dc9408 (sb_writers#5){.+.+}, at: vfs_write+0x1a4/0x1d0 #1: ffff88817406ca80 (&of->mutex){+.+.}, at: kernfs_fop_write+0xdd/0x1b0 #2: ffff888179be85e0 (kn->count#236){.+.+}, at: kernfs_fop_write+0xe6/0x1b0 #3: ffffffff82641e00 (system_transition_mutex){+.+.}, at: pm_suspend+0xb3/0x3b0 #4: ffffffff826b3ee0 (acpi_scan_lock){+.+.}, at: acpi_suspend_begin+0x47/0x80 #5: ffff888178fc3960 (&dev->mutex){....}, at: device_resume+0x92/0x1c0
stack backtrace: CPU: 3 PID: 4315 Comm: rtcwake Tainted: G U 5.6.0-rc2-CI-CI_DRM_7981+ #1 Hardware name: Google Soraka/Soraka, BIOS MrChromebox-4.10 08/25/2019 Call Trace: dump_stack+0x71/0x9b mark_lock+0x49a/0x500 ? print_shortest_lock_dependencies+0x200/0x200 __lock_acquire+0x6d4/0x15d0 ? __lock_acquire+0x460/0x15d0 lock_acquire+0xa7/0x1c0 ? cmos_interrupt+0x18/0x100 _raw_spin_lock+0x2a/0x40 ? cmos_interrupt+0x18/0x100 cmos_interrupt+0x18/0x100 cmos_resume+0x1fd/0x290 ? __acpi_pm_set_device_wakeup+0x24/0x100 pnp_bus_resume+0x5e/0x90 ? pnp_bus_suspend+0x10/0x10 dpm_run_callback+0x64/0x280 device_resume+0xd4/0x1c0 ? dpm_watchdog_set+0x60/0x60 dpm_resume+0x106/0x410 ? dpm_resume_early+0x38c/0x3e0 dpm_resume_end+0x8/0x10 suspend_devices_and_enter+0x16f/0xbe0 ? rcu_read_lock_sched_held+0x4d/0x80 pm_suspend+0x344/0x3b0 state_store+0x78/0xe0 kernfs_fop_write+0x112/0x1b0 vfs_write+0xb9/0x1d0 ksys_write+0x9f/0xe0 do_syscall_64+0x4f/0x220 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x7ff934307154 Code: 89 02 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 8d 05 b1 07 2e 00 8b 00 85 c0 75 13 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 54 f3 c3 66 90 41 54 55 49 89 d4 53 48 89 f5 RSP: 002b:00007ffe2647c168 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007ff934307154 RDX: 0000000000000004 RSI: 000055de3ec4e5a0 RDI: 000000000000000a RBP: 000055de3ec4e5a0 R08: 000055de3ec4c5e0 R09: 00007ff9349f3740 R10: 000055de3ec4a010 R11: 0000000000000246 R12: 000055de3ec4c500 R13: 0000000000000004 R14: 00007ff9345df2a0 R15: 00007ff9345de760
Fixes: c6d3a278cc12 ("rtc: cmos: acknowledge ACPI driven wake alarms upon resume") Fixes: 311ee9c151ad ("rtc: cmos: allow using ACPI for RTC alarm instead of HPET") Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Link: https://lore.kernel.org/r/20200221144739.11746-1-ville.syrjala@linux.intel.c... Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rtc/rtc-cmos.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 0fa94d9e8d44d..3c3ee2b92b413 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -653,10 +653,11 @@ static struct cmos_rtc cmos_rtc;
static irqreturn_t cmos_interrupt(int irq, void *p) { + unsigned long flags; u8 irqstat; u8 rtc_control;
- spin_lock(&rtc_lock); + spin_lock_irqsave(&rtc_lock, flags);
/* When the HPET interrupt handler calls us, the interrupt * status is passed as arg1 instead of the irq number. But @@ -690,7 +691,7 @@ static irqreturn_t cmos_interrupt(int irq, void *p) hpet_mask_rtc_irq_bit(RTC_AIE); CMOS_READ(RTC_INTR_FLAGS); } - spin_unlock(&rtc_lock); + spin_unlock_irqrestore(&rtc_lock, flags);
if (is_intr(irqstat)) { rtc_update_irq(p, 1, irqstat);
From: Trond Myklebust trondmy@gmail.com
[ Upstream commit a451b12311aa8c96c6f6e01c783a86995dc3ec6b ]
In NFSv4, the lock stateids are tied to the lockowner, and the open stateid, so that the action of closing the file also results in either an automatic loss of the locks, or an error of the form NFS4ERR_LOCKS_HELD.
In practice this means we must not add new locks to the open stateid after the close process has been invoked. In fact doing so, can result in the following panic:
kernel BUG at lib/list_debug.c:51! invalid opcode: 0000 [#1] SMP NOPTI CPU: 2 PID: 1085 Comm: nfsd Not tainted 5.6.0-rc3+ #2 Hardware name: VMware, Inc. VMware7,1/440BX Desktop Reference Platform, BIOS VMW71.00V.14410784.B64.1908150010 08/15/2019 RIP: 0010:__list_del_entry_valid.cold+0x31/0x55 Code: 1a 3d 9b e8 74 10 c2 ff 0f 0b 48 c7 c7 f0 1a 3d 9b e8 66 10 c2 ff 0f 0b 48 89 f2 48 89 fe 48 c7 c7 b0 1a 3d 9b e8 52 10 c2 ff <0f> 0b 48 89 fe 4c 89 c2 48 c7 c7 78 1a 3d 9b e8 3e 10 c2 ff 0f 0b RSP: 0018:ffffb296c1d47d90 EFLAGS: 00010246 RAX: 0000000000000054 RBX: ffff8ba032456ec8 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffff8ba039e99cc8 RDI: ffff8ba039e99cc8 RBP: ffff8ba032456e60 R08: 0000000000000781 R09: 0000000000000003 R10: 0000000000000000 R11: 0000000000000001 R12: ffff8ba009a4abe0 R13: ffff8ba032456e8c R14: 0000000000000000 R15: ffff8ba00adb01d8 FS: 0000000000000000(0000) GS:ffff8ba039e80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fb213f0b008 CR3: 00000001347de006 CR4: 00000000003606e0 Call Trace: release_lock_stateid+0x2b/0x80 [nfsd] nfsd4_free_stateid+0x1e9/0x210 [nfsd] nfsd4_proc_compound+0x414/0x700 [nfsd] ? nfs4svc_decode_compoundargs+0x407/0x4c0 [nfsd] nfsd_dispatch+0xc1/0x200 [nfsd] svc_process_common+0x476/0x6f0 [sunrpc] ? svc_sock_secure_port+0x12/0x30 [sunrpc] ? svc_recv+0x313/0x9c0 [sunrpc] ? nfsd_svc+0x2d0/0x2d0 [nfsd] svc_process+0xd4/0x110 [sunrpc] nfsd+0xe3/0x140 [nfsd] kthread+0xf9/0x130 ? nfsd_destroy+0x50/0x50 [nfsd] ? kthread_park+0x90/0x90 ret_from_fork+0x1f/0x40
The fix is to ensure that lock creation tests for whether or not the open stateid is unhashed, and to fail if that is the case.
Fixes: 659aefb68eca ("nfsd: Ensure we don't recognise lock stateids after freeing them") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfsd/nfs4state.c | 73 ++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 30 deletions(-)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index ed73e86194fac..033f302d34e4c 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -469,6 +469,8 @@ find_any_file(struct nfs4_file *f) { struct file *ret;
+ if (!f) + return NULL; spin_lock(&f->fi_lock); ret = __nfs4_get_fd(f, O_RDWR); if (!ret) { @@ -1205,6 +1207,12 @@ static void nfs4_put_stateowner(struct nfs4_stateowner *sop) nfs4_free_stateowner(sop); }
+static bool +nfs4_ol_stateid_unhashed(const struct nfs4_ol_stateid *stp) +{ + return list_empty(&stp->st_perfile); +} + static bool unhash_ol_stateid(struct nfs4_ol_stateid *stp) { struct nfs4_file *fp = stp->st_stid.sc_file; @@ -1272,9 +1280,11 @@ static bool unhash_lock_stateid(struct nfs4_ol_stateid *stp) { lockdep_assert_held(&stp->st_stid.sc_client->cl_lock);
+ if (!unhash_ol_stateid(stp)) + return false; list_del_init(&stp->st_locks); nfs4_unhash_stid(&stp->st_stid); - return unhash_ol_stateid(stp); + return true; }
static void release_lock_stateid(struct nfs4_ol_stateid *stp) @@ -1339,13 +1349,12 @@ static void release_open_stateid_locks(struct nfs4_ol_stateid *open_stp, static bool unhash_open_stateid(struct nfs4_ol_stateid *stp, struct list_head *reaplist) { - bool unhashed; - lockdep_assert_held(&stp->st_stid.sc_client->cl_lock);
- unhashed = unhash_ol_stateid(stp); + if (!unhash_ol_stateid(stp)) + return false; release_open_stateid_locks(stp, reaplist); - return unhashed; + return true; }
static void release_open_stateid(struct nfs4_ol_stateid *stp) @@ -5772,21 +5781,21 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, }
static struct nfs4_ol_stateid * -find_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp) +find_lock_stateid(const struct nfs4_lockowner *lo, + const struct nfs4_ol_stateid *ost) { struct nfs4_ol_stateid *lst; - struct nfs4_client *clp = lo->lo_owner.so_client;
- lockdep_assert_held(&clp->cl_lock); + lockdep_assert_held(&ost->st_stid.sc_client->cl_lock);
- list_for_each_entry(lst, &lo->lo_owner.so_stateids, st_perstateowner) { - if (lst->st_stid.sc_type != NFS4_LOCK_STID) - continue; - if (lst->st_stid.sc_file == fp) { - refcount_inc(&lst->st_stid.sc_count); - return lst; + /* If ost is not hashed, ost->st_locks will not be valid */ + if (!nfs4_ol_stateid_unhashed(ost)) + list_for_each_entry(lst, &ost->st_locks, st_locks) { + if (lst->st_stateowner == &lo->lo_owner) { + refcount_inc(&lst->st_stid.sc_count); + return lst; + } } - } return NULL; }
@@ -5802,11 +5811,11 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo, mutex_lock_nested(&stp->st_mutex, OPEN_STATEID_MUTEX); retry: spin_lock(&clp->cl_lock); - spin_lock(&fp->fi_lock); - retstp = find_lock_stateid(lo, fp); + if (nfs4_ol_stateid_unhashed(open_stp)) + goto out_close; + retstp = find_lock_stateid(lo, open_stp); if (retstp) - goto out_unlock; - + goto out_found; refcount_inc(&stp->st_stid.sc_count); stp->st_stid.sc_type = NFS4_LOCK_STID; stp->st_stateowner = nfs4_get_stateowner(&lo->lo_owner); @@ -5815,22 +5824,26 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo, stp->st_access_bmap = 0; stp->st_deny_bmap = open_stp->st_deny_bmap; stp->st_openstp = open_stp; + spin_lock(&fp->fi_lock); list_add(&stp->st_locks, &open_stp->st_locks); list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids); list_add(&stp->st_perfile, &fp->fi_stateids); -out_unlock: spin_unlock(&fp->fi_lock); spin_unlock(&clp->cl_lock); - if (retstp) { - if (nfsd4_lock_ol_stateid(retstp) != nfs_ok) { - nfs4_put_stid(&retstp->st_stid); - goto retry; - } - /* To keep mutex tracking happy */ - mutex_unlock(&stp->st_mutex); - stp = retstp; - } return stp; +out_found: + spin_unlock(&clp->cl_lock); + if (nfsd4_lock_ol_stateid(retstp) != nfs_ok) { + nfs4_put_stid(&retstp->st_stid); + goto retry; + } + /* To keep mutex tracking happy */ + mutex_unlock(&stp->st_mutex); + return retstp; +out_close: + spin_unlock(&clp->cl_lock); + mutex_unlock(&stp->st_mutex); + return NULL; }
static struct nfs4_ol_stateid * @@ -5845,7 +5858,7 @@ find_or_create_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fi,
*new = false; spin_lock(&clp->cl_lock); - lst = find_lock_stateid(lo, fi); + lst = find_lock_stateid(lo, ost); spin_unlock(&clp->cl_lock); if (lst != NULL) { if (nfsd4_lock_ol_stateid(lst) == nfs_ok)
From: Ritesh Harjani riteshh@linux.ibm.com
[ Upstream commit f1eec3b0d0a849996ebee733b053efa71803dad5 ]
While calculating overhead for internal journal, also check that j_inum shouldn't be 0. Otherwise we get below error with xfstests generic/050 with external journal (XXX_LOGDEV config) enabled.
It could be simply reproduced with loop device with an external journal and marking blockdev as RO before mounting.
[ 3337.146838] EXT4-fs error (device pmem1p2): ext4_get_journal_inode:4634: comm mount: inode #0: comm mount: iget: illegal inode # ------------[ cut here ]------------ generic_make_request: Trying to write to read-only block-device pmem1p2 (partno 2) WARNING: CPU: 107 PID: 115347 at block/blk-core.c:788 generic_make_request_checks+0x6b4/0x7d0 CPU: 107 PID: 115347 Comm: mount Tainted: G L --------- -t - 4.18.0-167.el8.ppc64le #1 NIP: c0000000006f6d44 LR: c0000000006f6d40 CTR: 0000000030041dd4 <...> NIP [c0000000006f6d44] generic_make_request_checks+0x6b4/0x7d0 LR [c0000000006f6d40] generic_make_request_checks+0x6b0/0x7d0 <...> Call Trace: generic_make_request_checks+0x6b0/0x7d0 (unreliable) generic_make_request+0x3c/0x420 submit_bio+0xd8/0x200 submit_bh_wbc+0x1e8/0x250 __sync_dirty_buffer+0xd0/0x210 ext4_commit_super+0x310/0x420 [ext4] __ext4_error+0xa4/0x1e0 [ext4] __ext4_iget+0x388/0xe10 [ext4] ext4_get_journal_inode+0x40/0x150 [ext4] ext4_calculate_overhead+0x5a8/0x610 [ext4] ext4_fill_super+0x3188/0x3260 [ext4] mount_bdev+0x778/0x8f0 ext4_mount+0x28/0x50 [ext4] mount_fs+0x74/0x230 vfs_kern_mount.part.6+0x6c/0x250 do_mount+0x2fc/0x1280 sys_mount+0x158/0x180 system_call+0x5c/0x70 EXT4-fs (pmem1p2): no journal found EXT4-fs (pmem1p2): can't get journal size EXT4-fs (pmem1p2): mounted filesystem without journal. Opts: dax,norecovery
Fixes: 3c816ded78bb ("ext4: use journal inode to determine journal overhead") Reported-by: Harish Sriram harish@linux.ibm.com Signed-off-by: Ritesh Harjani riteshh@linux.ibm.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20200316093038.25485-1-riteshh@linux.ibm.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ext4/super.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index d44fc3f579e13..e00a9a51be42f 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3523,7 +3523,8 @@ int ext4_calculate_overhead(struct super_block *sb) */ if (sbi->s_journal && !sbi->journal_bdev) overhead += EXT4_NUM_B2C(sbi, sbi->s_journal->j_maxlen); - else if (ext4_has_feature_journal(sb) && !sbi->s_journal) { + else if (ext4_has_feature_journal(sb) && !sbi->s_journal && j_inum) { + /* j_inum for internal journal is non-zero */ j_inode = ext4_get_journal_inode(sb, j_inum); if (j_inode) { j_blocks = j_inode->i_size >> sb->s_blocksize_bits;
From: Jan Kara jack@suse.cz
[ Upstream commit d05466b27b19af8e148376590ed54d289b607f0a ]
When ext4 is running on a filesystem without a journal, it tries not to reuse recently deleted inodes to provide better chances for filesystem recovery in case of crash. However this logic forbids reuse of freed inodes for up to 5 minutes and especially for filesystems with smaller number of inodes can lead to ENOSPC errors returned when allocating new inodes.
Fix the problem by allowing to reuse recently deleted inode if there's no other inode free in the scanned range.
Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20200318121317.31941-1-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ext4/ialloc.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index dafa7e4aaecb9..659ee9c34b0b1 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -714,21 +714,34 @@ static int recently_deleted(struct super_block *sb, ext4_group_t group, int ino) static int find_inode_bit(struct super_block *sb, ext4_group_t group, struct buffer_head *bitmap, unsigned long *ino) { + bool check_recently_deleted = EXT4_SB(sb)->s_journal == NULL; + unsigned long recently_deleted_ino = EXT4_INODES_PER_GROUP(sb); + next: *ino = ext4_find_next_zero_bit((unsigned long *) bitmap->b_data, EXT4_INODES_PER_GROUP(sb), *ino); if (*ino >= EXT4_INODES_PER_GROUP(sb)) - return 0; + goto not_found;
- if ((EXT4_SB(sb)->s_journal == NULL) && - recently_deleted(sb, group, *ino)) { + if (check_recently_deleted && recently_deleted(sb, group, *ino)) { + recently_deleted_ino = *ino; *ino = *ino + 1; if (*ino < EXT4_INODES_PER_GROUP(sb)) goto next; - return 0; + goto not_found; } - + return 1; +not_found: + if (recently_deleted_ino >= EXT4_INODES_PER_GROUP(sb)) + return 0; + /* + * Not reusing recently deleted inodes is mostly a preference. We don't + * want to report ENOSPC or skew allocation patterns because of that. + * So return even recently deleted inode if we could find better in the + * given range. + */ + *ino = recently_deleted_ino; return 1; }
From: Chuck Lever chuck.lever@oracle.com
[ Upstream commit 1a33d8a284b1e85e03b8c7b1ea8fb985fccd1d71 ]
Kernel memory leak detected:
unreferenced object 0xffff888849cdf480 (size 8): comm "kworker/u8:3", pid 2086, jiffies 4297898756 (age 4269.856s) hex dump (first 8 bytes): 30 00 cd 49 88 88 ff ff 0..I.... backtrace: [<00000000acfc370b>] __kmalloc_track_caller+0x137/0x183 [<00000000a2724354>] kstrdup+0x2b/0x43 [<0000000082964f84>] xprt_rdma_format_addresses+0x114/0x17d [rpcrdma] [<00000000dfa6ed00>] xprt_setup_rdma_bc+0xc0/0x10c [rpcrdma] [<0000000073051a83>] xprt_create_transport+0x3f/0x1a0 [sunrpc] [<0000000053531a8e>] rpc_create+0x118/0x1cd [sunrpc] [<000000003a51b5f8>] setup_callback_client+0x1a5/0x27d [nfsd] [<000000001bd410af>] nfsd4_process_cb_update.isra.7+0x16c/0x1ac [nfsd] [<000000007f4bbd56>] nfsd4_run_cb_work+0x4c/0xbd [nfsd] [<0000000055c5586b>] process_one_work+0x1b2/0x2fe [<00000000b1e3e8ef>] worker_thread+0x1a6/0x25a [<000000005205fb78>] kthread+0xf6/0xfb [<000000006d2dc057>] ret_from_fork+0x3a/0x50
Introduce a call to xprt_rdma_free_addresses() similar to the way that the TCP backchannel releases a transport's peer address strings.
Fixes: 5d252f90a800 ("svcrdma: Add class for RDMA backwards direction transport") Signed-off-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/sunrpc/xprtrdma/svc_rdma_backchannel.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c index b9827665ff355..d183d4aee822c 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c +++ b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c @@ -256,6 +256,7 @@ xprt_rdma_bc_put(struct rpc_xprt *xprt) { dprintk("svcrdma: %s: xprt %p\n", __func__, xprt);
+ xprt_rdma_free_addresses(xprt); xprt_free(xprt); module_put(THIS_MODULE); }
From: Mikel Rychliski mikel@mikelr.com
[ Upstream commit 72e0ef0e5f067fd991f702f0b2635d911d0cf208 ]
On some EFI systems, the video BIOS is provided by the EFI firmware. The boot stub code stores the physical address of the ROM image in pdev->rom. Currently we attempt to access this pointer using phys_to_virt(), which doesn't work with CONFIG_HIGHMEM.
On these systems, attempting to load the radeon module on a x86_32 kernel can result in the following:
BUG: unable to handle page fault for address: 3e8ed03c #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page *pde = 00000000 Oops: 0000 [#1] PREEMPT SMP CPU: 0 PID: 317 Comm: systemd-udevd Not tainted 5.6.0-rc3-next-20200228 #2 Hardware name: Apple Computer, Inc. MacPro1,1/Mac-F4208DC8, BIOS MP11.88Z.005C.B08.0707021221 07/02/07 EIP: radeon_get_bios+0x5ed/0xe50 [radeon] Code: 00 00 84 c0 0f 85 12 fd ff ff c7 87 64 01 00 00 00 00 00 00 8b 47 08 8b 55 b0 e8 1e 83 e1 d6 85 c0 74 1a 8b 55 c0 85 d2 74 13 <80> 38 55 75 0e 80 78 01 aa 0f 84 a4 03 00 00 8d 74 26 00 68 dc 06 EAX: 3e8ed03c EBX: 00000000 ECX: 3e8ed03c EDX: 00010000 ESI: 00040000 EDI: eec04000 EBP: eef3fc60 ESP: eef3fbe0 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 EFLAGS: 00010206 CR0: 80050033 CR2: 3e8ed03c CR3: 2ec77000 CR4: 000006d0 Call Trace: r520_init+0x26/0x240 [radeon] radeon_device_init+0x533/0xa50 [radeon] radeon_driver_load_kms+0x80/0x220 [radeon] drm_dev_register+0xa7/0x180 [drm] radeon_pci_probe+0x10f/0x1a0 [radeon] pci_device_probe+0xd4/0x140
Fix the issue by updating all drivers which can access a platform provided ROM. Instead of calling the helper function pci_platform_rom() which uses phys_to_virt(), call ioremap() directly on the pdev->rom.
radeon_read_platform_bios() previously directly accessed an __iomem pointer. Avoid this by calling memcpy_fromio() instead of kmemdup().
pci_platform_rom() now has no remaining callers, so remove it.
Link: https://lore.kernel.org/r/20200319021623.5426-1-mikel@mikelr.com Signed-off-by: Mikel Rychliski mikel@mikelr.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Acked-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c | 31 +++++++++++-------- .../drm/nouveau/nvkm/subdev/bios/shadowpci.c | 17 ++++++++-- drivers/gpu/drm/radeon/radeon_bios.c | 30 +++++++++++------- drivers/pci/rom.c | 17 ---------- include/linux/pci.h | 1 - 5 files changed, 52 insertions(+), 44 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c index a5df80d50d447..6cf3dd5edffda 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c @@ -191,30 +191,35 @@ static bool amdgpu_read_bios_from_rom(struct amdgpu_device *adev)
static bool amdgpu_read_platform_bios(struct amdgpu_device *adev) { - uint8_t __iomem *bios; - size_t size; + phys_addr_t rom = adev->pdev->rom; + size_t romlen = adev->pdev->romlen; + void __iomem *bios;
adev->bios = NULL;
- bios = pci_platform_rom(adev->pdev, &size); - if (!bios) { + if (!rom || romlen == 0) return false; - }
- adev->bios = kzalloc(size, GFP_KERNEL); - if (adev->bios == NULL) + adev->bios = kzalloc(romlen, GFP_KERNEL); + if (!adev->bios) return false;
- memcpy_fromio(adev->bios, bios, size); + bios = ioremap(rom, romlen); + if (!bios) + goto free_bios;
- if (!check_atom_bios(adev->bios, size)) { - kfree(adev->bios); - return false; - } + memcpy_fromio(adev->bios, bios, romlen); + iounmap(bios);
- adev->bios_size = size; + if (!check_atom_bios(adev->bios, romlen)) + goto free_bios; + + adev->bios_size = romlen;
return true; +free_bios: + kfree(adev->bios); + return false; }
#ifdef CONFIG_ACPI diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c index 9b91da09dc5f8..8d9812a51ef63 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c @@ -101,9 +101,13 @@ platform_init(struct nvkm_bios *bios, const char *name) else return ERR_PTR(-ENODEV);
+ if (!pdev->rom || pdev->romlen == 0) + return ERR_PTR(-ENODEV); + if ((priv = kmalloc(sizeof(*priv), GFP_KERNEL))) { + priv->size = pdev->romlen; if (ret = -ENODEV, - (priv->rom = pci_platform_rom(pdev, &priv->size))) + (priv->rom = ioremap(pdev->rom, pdev->romlen))) return priv; kfree(priv); } @@ -111,11 +115,20 @@ platform_init(struct nvkm_bios *bios, const char *name) return ERR_PTR(ret); }
+static void +platform_fini(void *data) +{ + struct priv *priv = data; + + iounmap(priv->rom); + kfree(priv); +} + const struct nvbios_source nvbios_platform = { .name = "PLATFORM", .init = platform_init, - .fini = (void(*)(void *))kfree, + .fini = platform_fini, .read = pcirom_read, .rw = true, }; diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 04c0ed41374f1..dd0528cf98183 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c @@ -104,25 +104,33 @@ static bool radeon_read_bios(struct radeon_device *rdev)
static bool radeon_read_platform_bios(struct radeon_device *rdev) { - uint8_t __iomem *bios; - size_t size; + phys_addr_t rom = rdev->pdev->rom; + size_t romlen = rdev->pdev->romlen; + void __iomem *bios;
rdev->bios = NULL;
- bios = pci_platform_rom(rdev->pdev, &size); - if (!bios) { + if (!rom || romlen == 0) return false; - }
- if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { + rdev->bios = kzalloc(romlen, GFP_KERNEL); + if (!rdev->bios) return false; - } - rdev->bios = kmemdup(bios, size, GFP_KERNEL); - if (rdev->bios == NULL) { - return false; - } + + bios = ioremap(rom, romlen); + if (!bios) + goto free_bios; + + memcpy_fromio(rdev->bios, bios, romlen); + iounmap(bios); + + if (rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) + goto free_bios;
return true; +free_bios: + kfree(rdev->bios); + return false; }
#ifdef CONFIG_ACPI diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 137bf0cee897c..8fc9a4e911e3a 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c @@ -195,20 +195,3 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) pci_disable_rom(pdev); } EXPORT_SYMBOL(pci_unmap_rom); - -/** - * pci_platform_rom - provides a pointer to any ROM image provided by the - * platform - * @pdev: pointer to pci device struct - * @size: pointer to receive size of pci window over ROM - */ -void __iomem *pci_platform_rom(struct pci_dev *pdev, size_t *size) -{ - if (pdev->rom && pdev->romlen) { - *size = pdev->romlen; - return phys_to_virt((phys_addr_t)pdev->rom); - } - - return NULL; -} -EXPORT_SYMBOL(pci_platform_rom); diff --git a/include/linux/pci.h b/include/linux/pci.h index b1f297f4b7b0b..993051f60a009 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1141,7 +1141,6 @@ int pci_enable_rom(struct pci_dev *pdev); void pci_disable_rom(struct pci_dev *pdev); void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); -void __iomem __must_check *pci_platform_rom(struct pci_dev *pdev, size_t *size);
/* Power management related routines */ int pci_save_state(struct pci_dev *dev);
linux-stable-mirror@lists.linaro.org