6.1.159-rc1 review
Greg Kroah-Hartman
maintainerPATCH 420/568 mm, percpu: do not consider sleepable allocations atomic
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Hocko <[email protected]>
[ Upstream commit 9a5b183941b52f84c0f9e5f27ce44e99318c9e0f ]
28307d938fb2 ("percpu: make pcpu_alloc() aware of current gfp context") has fixed a reclaim recursion for scoped GFP_NOFS context. It has done that by avoiding taking pcpu_alloc_mutex. This is a correct solution as the worker context with full GFP_KERNEL allocation/reclaim power and which is using the same lock cannot block the NOFS pcpu_alloc caller.
On the other hand this is a very conservative approach that could lead to failures because pcpu_alloc lockless implementation is quite limited.
We have a bug report about premature failures when scsi array of 193 devices is scanned. Sometimes (not consistently) the scanning aborts because the iscsid daemon fails to create the queue for a random scsi device during the scan. iscsid itself is running with PR_SET_IO_FLUSHER set so all allocations from this process context are GFP_NOIO. This in turn makes any pcpu_alloc lockless (without pcpu_alloc_mutex) which leads to pre-mature failures.
It has turned out that iscsid has worked around this by dropping PR_SET_IO_FLUSHER (https://github.com/open-iscsi/open-iscsi/pull/382) when scanning host. But we can do better in this case on the kernel side and use pcpu_alloc_mutex for NOIO resp. NOFS constrained allocation scopes too. We just need the WQ worker to never trigger IO/FS reclaim. Achieve that by enforcing scoped GFP_NOIO for the whole execution of pcpu_balance_workfn (this will imply NOFS constrain as well). This will remove the dependency chain and preserve the full allocation power of the pcpu_alloc call.
While at it make is_atomic really test for blockable allocations.
--- mm/percpu.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
mm/percpu.c +7 -1
@@ -1737,7 +1737,7 @@ static void __percpu *pcpu_alloc(size_t gfp =current_gfp_context (gfp);/* whitelisted flags that can be passed to the backing allocators */ pcpu_gfp = gfp & (GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN); - is_atomic = (gfp &GFP_KERNEL ) !=GFP_KERNEL ; + is_atomic = !gfpflags_allow_blocking (gfp); do_warn = !(gfp & __GFP_NOWARN);/*
@@ -2237,7 +2237,12 @@ static void pcpu_balance_workfn(struct w* to grow other chunks. This then gives pcpu_reclaim_populated() time * to move fully free chunks to the active list to be freed if * appropriate. +* +* Enforce GFP_NOIO allocations because we have pcpu_alloc users +* constrained to GFP_NOIO/NOFS contexts and they could form lock +* dependency through pcpu_alloc_mutex */ +unsigned int flags =memalloc_noio_save ();mutex_lock (&pcpu_alloc_mutex);spin_lock_irq (&pcpu_lock);
@@ -2248,6 +2253,7 @@ static void pcpu_balance_workfn(struct wspin_unlock_irq (&pcpu_lock);mutex_unlock (&pcpu_alloc_mutex); +memalloc_noio_restore (flags); }/**
Greg Kroah-Hartman
maintainerPATCH 421/568 isdn: mISDN: hfcsusb: fix memory leak in hfcsusb_probe()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abdun Nihaal <[email protected]>
commit 3f978e3f1570155a1327ffa25f60968bc7b9398f upstream.
In hfcsusb_probe(), the memory allocated for ctrl_urb gets leaked when setup_instance() fails with an error code. Fix that by freeing the urb before freeing the hw structure. Also change the error paths to use the goto ladder style.
Compile tested only. Issue found using a prototype static analysis tool.
--- drivers/isdn/hardware/mISDN/hfcsusb.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
drivers/isdn/hardware/mISDN/hfcsusb.c +13 -5
@@ -1903,13 +1903,13 @@ out:mISDN_freebchannel (&hw->bch[1 ]);mISDN_freebchannel (&hw->bch[0 ]);mISDN_freedchannel (&hw->dch); -kfree (hw);return err; }static int hfcsusb_probe (struct usb_interface *intf,const struct usb_device_id *id) { +int err;struct hfcsusb *hw;struct usb_device *dev =interface_to_usbdev (intf);struct usb_host_interface *iface = intf->cur_altsetting;
@@ -2100,20 +2100,28 @@ hfcsusb_probe(struct usb_interface *intfif (!hw->ctrl_urb) {pr_warn ("%s: No memory for control urb\n" , driver_info->vend_name); -kfree (hw); -return -ENOMEM ; + err = -ENOMEM ; + goto err_free_hw; }pr_info ("%s: %s: detected \"%s\" (%s, if=%d alt=%d)\n" , hw->name, __func__, driver_info->vend_name, conf_str[small_match], ifnum, alt_used); -if (setup_instance (hw, dev->dev.parent)) -return -EIO ; +if (setup_instance (hw, dev->dev.parent)) { + err = -EIO ; + goto err_free_urb; + } hw->intf = intf;usb_set_intfdata (hw->intf, hw);return 0 ; + +err_free_urb: +usb_free_urb (hw->ctrl_urb); +err_free_hw: +kfree (hw); +return err; }/* function called when an active device is removed */
Greg Kroah-Hartman
maintainerPATCH 422/568 asm-generic: partially revert "Unify uapi bitsperlong.h for arm64, riscv and loongarch"
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit 6e8d96909a23c8078ee965bd48bb31cbef2de943 upstream.
Unifying the asm-generic headers across 32-bit and 64-bit architectures based on the compiler provided macros was a good idea and appears to work with all user space, but it caused a regression when building old kernels on systems that have the new headers installed in /usr/include, as this combination trips an inconsistency in the kernel's own tools/include headers that are a mix of userspace and kernel-internal headers.
This affects kernel builds on arm64, riscv64 and loongarch64 systems that might end up using the "#define __BITS_PER_LONG 32" default from the old tools headers. Backporting the commit into stable kernels would address this, but it would still break building kernels without that backport, and waste time for developers trying to understand the problem.
arm64 build machines are rather common, and on riscv64 this can also happen in practice, but loongarch64 is probably new enough to not be used much for building old kernels, so only revert the bits for arm64 and riscv.
--- arch/arm64/include/uapi/asm/bitsperlong.h | 24 ++++++++++++++++++++++++ arch/riscv/include/uapi/asm/bitsperlong.h | 14 ++++++++++++++ tools/arch/arm64/include/uapi/asm/bitsperlong.h | 24 ++++++++++++++++++++++++ tools/arch/riscv/include/uapi/asm/bitsperlong.h | 14 ++++++++++++++ 4 files changed, 76 insertions(+) create mode 100644 arch/arm64/include/uapi/asm/bitsperlong.h create mode 100644 arch/riscv/include/uapi/asm/bitsperlong.h create mode 100644 tools/arch/arm64/include/uapi/asm/bitsperlong.h create mode 100644 tools/arch/riscv/include/uapi/asm/bitsperlong.h
arch/arm64/include/uapi/asm/bitsperlong.h new file +24 -0
@@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* +* Copyright (C) 2012 ARM Ltd. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +#ifndef __ASM_BITSPERLONG_H +#define __ASM_BITSPERLONG_H + +#define __BITS_PER_LONG 64 + +#include <asm-generic/bitsperlong.h> + +#endif /* __ASM_BITSPERLONG_H */
arch/riscv/include/uapi/asm/bitsperlong.h new file +14 -0
@@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ +/* +* Copyright (C) 2012 ARM Ltd. +* Copyright (C) 2015 Regents of the University of California +*/ + +#ifndef _UAPI_ASM_RISCV_BITSPERLONG_H +#define _UAPI_ASM_RISCV_BITSPERLONG_H + +#define __BITS_PER_LONG (__SIZEOF_POINTER__ * 8) + +#include <asm-generic/bitsperlong.h> + +#endif /* _UAPI_ASM_RISCV_BITSPERLONG_H */
tools/arch/arm64/include/uapi/asm/bitsperlong.h new file +24 -0
@@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* +* Copyright (C) 2012 ARM Ltd. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +#ifndef __ASM_BITSPERLONG_H +#define __ASM_BITSPERLONG_H + +#define __BITS_PER_LONG 64 + +#include <asm-generic/bitsperlong.h> + +#endif /* __ASM_BITSPERLONG_H */
tools/arch/riscv/include/uapi/asm/bitsperlong.h new file +14 -0
@@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* Copyright (C) 2012 ARM Ltd. +* Copyright (C) 2015 Regents of the University of California +*/ + +#ifndef _UAPI_ASM_RISCV_BITSPERLONG_H +#define _UAPI_ASM_RISCV_BITSPERLONG_H + +#define __BITS_PER_LONG (__SIZEOF_POINTER__ * 8) + +#include <asm-generic/bitsperlong.h> + +#endif /* _UAPI_ASM_RISCV_BITSPERLONG_H */
Greg Kroah-Hartman
maintainerPATCH 423/568 net/mlx5: Fix memory leak in error flow of port set buffer
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maher Sanalla <[email protected]>
commit e3e01c1c15986f9531b854634eec8381e72cb605 upstream.
In the cited commit, shared buffer updates were added whenever port buffer gets updated.
However, in case the shared buffer update fails, exiting early from port_set_buffer() is performed without freeing previously-allocated memory.
Fix it by jumping to out label where memory is freed before returning with error.
--- drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c +2 -2
@@ -325,11 +325,11 @@ static int port_set_buffer(struct mlx5e_ err =port_update_shared_buffer (priv->mdev, current_headroom_size, new_headroom_size);if (err) -return err; + goto out; err =port_update_pool_cfg (priv->mdev, port_buffer);if (err) -return err; + goto out; err =mlx5e_port_set_pbmc (mdev, in); out:
Greg Kroah-Hartman
maintainerPATCH 424/568 net/sched: act_connmark: handle errno on tcf_idr_check_alloc
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pedro Tammela <[email protected]>
commit fb07390463c95e6eef254044d6dde050bfb9807a upstream.
Smatch reports that 'ci' can be used uninitialized.
The current code ignores errno coming from tcf_idr_check_alloc, which will lead to the incorrect usage of 'ci'. Handle the errno as it should.
--- net/sched/act_connmark.c | 3 +++ 1 file changed, 3 insertions(+)
net/sched/act_connmark.c +3 -0
@@ -156,6 +156,9 @@ static int tcf_connmark_init(struct net nparms->zone = parm->zone; ret =0 ; + }else { + err = ret; + goto out_free; } err =tcf_action_check_ctrlact (parm->action, tp, &goto_ch, extack);
Greg Kroah-Hartman
maintainerPATCH 425/568 net/mlx5e: Do not update SBCM when prio2buffer command is invalid
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maher Sanalla <[email protected]>
commit 623efc4cbd6115db36716e31037cb6d1f3ce6754 upstream.
The shared buffer pools configuration which are stored in the SBCM register are updated when the user changes the prio2buffer mapping.
However, in case the user desired prio2buffer change is invalid, which can occur due to mapping a lossless priority to a not large enough buffer, the SBCM update should not be performed, as the user command is failed.
Thus, Perform the SBCM update only after xoff threshold calculation is performed and the user prio2buffer mapping is validated.
--- drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c +2 -2
@@ -443,11 +443,11 @@ static int update_buffer_lossy(struct ml }if (changed) { - err =port_update_pool_cfg (mdev, port_buffer); + err =update_xoff_threshold (port_buffer, xoff, max_mtu, port_buff_cell_sz);if (err)return err; - err =update_xoff_threshold (port_buffer, xoff, max_mtu, port_buff_cell_sz); + err =port_update_pool_cfg (mdev, port_buffer);if (err)return err;
Greg Kroah-Hartman
maintainerPATCH 426/568 net/mlx5e: Preserve shared buffer capacity during headroom updates
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armen Ratner <[email protected]>
commit 8b0587a885fdb34fd6090a3f8625cb7ac1444826 upstream.
When port buffer headroom changes, port_update_shared_buffer() recalculates the shared buffer size and splits it in a 3:1 ratio (lossy:lossless) - Currently, the calculation is:
lossless = shared / 4;
lossy = (shared / 4) * 3;
Meaning, the calculation dropped the remainder of shared % 4 due to integer division, unintentionally reducing the total shared buffer by up to three cells on each update. Over time, this could shrink the buffer below usable size.
Fix it by changing the calculation to:
lossless = shared / 4;
lossy = shared - lossless;
This retains all buffer cells while still approximating the intended 3:1 split, preventing capacity loss over time.
While at it, perform headroom calculations in units of cells rather than in bytes for more accurate calculations avoiding extra divisions.
--- drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c | 18 ++++++--------- 1 file changed, 8 insertions(+), 10 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c +8 -10
@@ -272,8 +272,8 @@ static int port_update_shared_buffer(str/* Total shared buffer size is split in a ratio of 3:1 between * lossy and lossless pools respectively. */ - lossy_epool_size = (shared_buffer_size /4 ) *3 ; lossless_ipool_size = shared_buffer_size /4 ; + lossy_epool_size = shared_buffer_size - lossless_ipool_size;mlx5e_port_set_sbpr (mdev,0 ,MLX5_EGRESS_DIR ,MLX5_LOSSY_POOL ,0 , lossy_epool_size);
@@ -288,14 +288,12 @@ static int port_set_buffer(struct mlx5e_u16 port_buff_cell_sz = priv->dcbx.port_buff_cell_sz;struct mlx5_core_dev *mdev = priv->mdev;int sz =MLX5_ST_SZ_BYTES (pbmc_reg); -u32 new_headroom_size =0 ; -u32 current_headroom_size; +u32 current_headroom_cells =0 ; +u32 new_headroom_cells =0 ;void *in;int err;int i; - current_headroom_size = port_buffer->headroom_size; - in =kzalloc (sz,GFP_KERNEL );if (!in)return -ENOMEM ;
@@ -306,12 +304,14 @@ static int port_set_buffer(struct mlx5e_for (i =0 ; i <MLX5E_MAX_NETWORK_BUFFER ; i++) {void *buffer =MLX5_ADDR_OF (pbmc_reg, in, buffer[i]); + current_headroom_cells +=MLX5_GET (bufferx_reg, buffer, size); +u64 size = port_buffer->buffer[i].size;u64 xoff = port_buffer->buffer[i].xoff;u64 xon = port_buffer->buffer[i].xon; - new_headroom_size += size;do_div (size, port_buff_cell_sz); + new_headroom_cells += size;do_div (xoff, port_buff_cell_sz);do_div (xon, port_buff_cell_sz);MLX5_SET (bufferx_reg, buffer, size, size);
@@ -320,10 +320,8 @@ static int port_set_buffer(struct mlx5e_MLX5_SET (bufferx_reg, buffer, xon_threshold, xon); } - new_headroom_size /= port_buff_cell_sz; - current_headroom_size /= port_buff_cell_sz; - err =port_update_shared_buffer (priv->mdev, current_headroom_size, - new_headroom_size); + err =port_update_shared_buffer (priv->mdev, current_headroom_cells, + new_headroom_cells);if (err) goto out;
Greg Kroah-Hartman
maintainerPATCH 427/568 timers: Fix NULL function pointer race in timer_shutdown_sync()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yipeng Zou <[email protected]>
commit 20739af07383e6eb1ec59dcd70b72ebfa9ac362c upstream.
There is a race condition between timer_shutdown_sync() and timer expiration that can lead to hitting a WARN_ON in expire_timers().
The issue occurs when timer_shutdown_sync() clears the timer function to NULL while the timer is still running on another CPU. The race scenario looks like this:
CPU0 CPU1
<SOFTIRQ> lock_timer_base() expire_timers() base->running_timer = timer; unlock_timer_base() [call_timer_fn enter] mod_timer() ...
timer_shutdown_sync()lock_timer_base()
// For now, will not detach the timer but only clear its function to NULL if (base->running_timer != timer)
ret = detach_if_pending(timer, base, true); if (shutdown) timer->function = NULL; unlock_timer_base() [call_timer_fn exit] lock_timer_base() base->running_timer = NULL; unlock_timer_base() ... // Now timer is pending while its function set to NULL. // next timer trigger <SOFTIRQ> expire_timers() WARN_ON_ONCE(!fn) // hit ... lock_timer_base() // Now timer will detach if (base->running_timer != timer) ret = detach_if_pending(timer, base, true); if (shutdown) timer->function = NULL;
unlock_timer_base()
The problem is that timer_shutdown_sync() clears the timer function regardless of whether the timer is currently running. This can leave a pending timer with a NULL function pointer, which triggers the WARN_ON_ONCE(!fn) check in expire_timers().
Fix this by only clearing the timer function when actually detaching the timer. If the timer is running, leave the function pointer intact, which is safe because the timer will be properly detached when it finishes running.
--- kernel/time/timer.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
kernel/time/timer.c +4 -3
@@ -1413,10 +1413,11 @@ static int __try_to_del_timer_sync(struc base =lock_timer_base (timer, &flags); -if (base->running_timer != timer) +if (base->running_timer != timer) { ret =detach_if_pending (timer, base, true); -if (shutdown) - timer->function =NULL ; +if (shutdown) + timer->function =NULL ; + }raw_spin_unlock_irqrestore (&base->lock, flags);
Greg Kroah-Hartman
maintainerPATCH 428/568 HID: quirks: work around VID/PID conflict for 0x4c4a/0x4155
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Heng <[email protected]>
commit beab067dbcff642243291fd528355d64c41dc3b2 upstream.
Based on available evidence, the USB ID 4c4a:4155 used by multiple devices has been attributed to Jieli. The commit 1a8953f4f774 ("HID: Add IGNORE quirk for SMARTLINKTECHNOLOGY") affected touchscreen functionality. Added checks for manufacturer and serial number to maintain microphone compatibility, enabling both devices to function properly.
--- drivers/hid/hid-ids.h | 4 ++-- drivers/hid/hid-quirks.c | 13 ++++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-)
drivers/hid/hid-ids.h +2 -2
@@ -1460,7 +1460,7 @@#define USB_VENDOR_ID_SIGNOTEC 0x2133#define USB_DEVICE_ID_SIGNOTEC_VIEWSONIC_PD1011 0x0018 -#define USB_VENDOR_ID_SMARTLINKTECHNOLOGY 0x4c4a -#define USB_DEVICE_ID_SMARTLINKTECHNOLOGY_4155 0x4155 +#define USB_VENDOR_ID_JIELI_SDK_DEFAULT 0x4c4a +#define USB_DEVICE_ID_JIELI_SDK_4155 0x4155#endif
drivers/hid/hid-quirks.c +12 -1
@@ -888,7 +888,6 @@ static const struct hid_device_id hid_ig#endif { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_HP_5MP_CAMERA_5473) }, - { HID_USB_DEVICE(USB_VENDOR_ID_SMARTLINKTECHNOLOGY, USB_DEVICE_ID_SMARTLINKTECHNOLOGY_4155) }, { } };
@@ -1045,6 +1044,18 @@ bool hid_ignore(struct hid_device *hdev) strlen(elan_acpi_id[i].id)))return true;break ; +case USB_VENDOR_ID_JIELI_SDK_DEFAULT : +/* +* Multiple USB devices with identical IDs (mic & touchscreen). +* The touch screen requires hid core processing, but the +* microphone does not. They can be distinguished by manufacturer +* and serial number. +*/ +if (hdev->product ==USB_DEVICE_ID_JIELI_SDK_4155 && +strncmp (hdev->name,"SmartlinkTechnology" ,19 ) ==0 && +strncmp (hdev->uniq,"20201111000001" ,14 ) ==0 ) +return true; +break ; } if (hdev->type == HID_TYPE_USBMOUSE &&
Greg Kroah-Hartman
maintainerPATCH 429/568 mtd: rawnand: cadence: fix DMA device NULL pointer dereference
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niravkumar L Rabara <[email protected]>
commit 5c56bf214af85ca042bf97f8584aab2151035840 upstream.
The DMA device pointer dma_dev was being dereferenced before ensuring that cdns_ctrl->dmac is properly initialized.
Move the assignment of dma_dev after successfully acquiring the DMA channel to ensure the pointer is valid before use.
--- drivers/mtd/nand/raw/cadence-nand-controller.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/mtd/nand/raw/cadence-nand-controller.c +2 -1
@@ -2830,7 +2830,7 @@ cadence_nand_irq_cleanup(int irqnum, strstatic int cadence_nand_init (struct cdns_nand_ctrl *cdns_ctrl) {dma_cap_mask_t mask; -struct dma_device *dma_dev = cdns_ctrl->dmac->device; +struct dma_device *dma_dev;int ret; cdns_ctrl->cdma_desc = dma_alloc_coherent(cdns_ctrl->dev,
@@ -2874,6 +2874,7 @@ static int cadence_nand_init(struct cdns } } + dma_dev = cdns_ctrl->dmac->device; cdns_ctrl->io.iova_dma =dma_map_resource (dma_dev->dev, cdns_ctrl->io.dma, cdns_ctrl->io.size,DMA_BIDIRECTIONAL ,0 );
Greg Kroah-Hartman
maintainerPATCH 430/568 mtdchar: fix integer overflow in read/write ioctls
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit e4185bed738da755b191aa3f2e16e8b48450e1b8 upstream.
The "req.start" and "req.len" variables are u64 values that come from the user at the start of the function. We mask away the high 32 bits of "req.len" so that's capped at U32_MAX but the "req.start" variable can go up to U64_MAX which means that the addition can still integer overflow.
Use check_add_overflow() to fix this bug.
--- drivers/mtd/mtdchar.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/mtd/mtdchar.c +4 -2
@@ -599,6 +599,7 @@ mtdchar_write_ioctl(struct mtd_info *mtduint8_t *datbuf =NULL , *oobbuf =NULL ;size_t datbuf_len, oobbuf_len;int ret =0 ; +u64 end;if (copy_from_user (&req, argp,sizeof (req)))return -EFAULT ;
@@ -618,7 +619,7 @@ mtdchar_write_ioctl(struct mtd_info *mtd req.len &=0xffffffff ; req.ooblen &=0xffffffff ; -if (req.start + req.len > mtd->size) +if (check_add_overflow (req.start, req.len, &end) || end > mtd->size)return -EINVAL ; datbuf_len =min_t (size_t, req.len, mtd->erasesize);
@@ -698,6 +699,7 @@ mtdchar_read_ioctl(struct mtd_info *mtd,size_t datbuf_len, oobbuf_len;size_t orig_len, orig_ooblen;int ret =0 ; +u64 end;if (copy_from_user (&req, argp,sizeof (req)))return -EFAULT ;
@@ -724,7 +726,7 @@ mtdchar_read_ioctl(struct mtd_info *mtd, req.len &=0xffffffff ; req.ooblen &=0xffffffff ; -if (req.start + req.len > mtd->size) { +if (check_add_overflow (req.start, req.len, &end) || end > mtd->size) { ret = -EINVAL ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 431/568 exfat: check return value of sb_min_blocksize in exfat_read_boot_sector
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongpeng Yang <[email protected]>
commit f2c1f631630e01821fe4c3fdf6077bc7a8284f82 upstream.
sb_min_blocksize() may return 0. Check its return value to avoid accessing the filesystem super block when sb->s_blocksize is 0.
--- fs/exfat/super.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/exfat/super.c +4 -1
@@ -425,7 +425,10 @@ static int exfat_read_boot_sector(structstruct exfat_sb_info *sbi =EXFAT_SB (sb);/* set block size to read super block */ -sb_min_blocksize (sb,512 ); +if (!sb_min_blocksize (sb,512 )) { +exfat_err (sb,"unable to set blocksize" ); +return -EINVAL ; + }/* read boot sector */ sbi->boot_bh =sb_bread (sb,0 );
Greg Kroah-Hartman
maintainerPATCH 432/568 mptcp: Disallow MPTCP subflows from sockmap
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <[email protected]>
commit fbade4bd08ba52cbc74a71c4e86e736f059f99f7 upstream.
The sockmap feature allows bpf syscall from userspace, or based on bpf sockops, replacing the sk_prot of sockets during protocol stack processing with sockmap's custom read/write interfaces.
'''tcp_rcv_state_process()
subflow_syn_recv_sock()
tcp_init_transfer(BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB)
bpf_skops_established <== sockops
bpf_sock_map_update(sk) <== call bpf helper
tcp_bpf_update_proto() <== update sk_prot'''
Consider two scenarios:
1. When the server has MPTCP enabled and the client also requests MPTCP, the sk passed to the BPF program is a subflow sk. Since subflows only handle partial data, replacing their sk_prot is meaningless and will cause traffic disruption.
2. When the server has MPTCP enabled but the client sends a TCP SYN without MPTCP, subflow_syn_recv_sock() performs a fallback on the subflow, replacing the subflow sk's sk_prot with the native sk_prot. '''
subflow_ulp_fallback()
subflow_drop_ctx()
mptcp_subflow_ops_undo_override()
'''
Subsequently, accept::mptcp_stream_accept::mptcp_fallback_tcp_ops() converts the subflow to plain TCP.
For the first case, we should prevent it from being combined with sockmap by setting sk_prot->psock_update_sk_prot to NULL, which will be blocked by sockmap's own flow.
For the second case, since subflow_syn_recv_sock() has already restored sk_prot to native tcp_prot/tcpv6_prot, no further action is needed.
--- net/mptcp/subflow.c | 8 ++++++++ 1 file changed, 8 insertions(+)
net/mptcp/subflow.c +8 -0
@@ -1997,6 +1997,10 @@ void __init mptcp_subflow_init(void) tcp_prot_override = tcp_prot; tcp_prot_override.release_cb = tcp_release_cb_override; tcp_prot_override.diag_destroy = tcp_abort_override; +#ifdef CONFIG_BPF_SYSCALL +/* Disable sockmap processing for subflows */ + tcp_prot_override.psock_update_sk_prot =NULL ; +#endif #if IS_ENABLED (CONFIG_MPTCP_IPV6 )/* In struct mptcp_subflow_request_sock, we assume the TCP request sock
@@ -2033,6 +2037,10 @@ void __init mptcp_subflow_init(void) tcpv6_prot_override = tcpv6_prot; tcpv6_prot_override.release_cb = tcp_release_cb_override; tcpv6_prot_override.diag_destroy = tcp_abort_override; +#ifdef CONFIG_BPF_SYSCALL +/* Disable sockmap processing for subflows */ + tcpv6_prot_override.psock_update_sk_prot =NULL ; +#endif #endif mptcp_diag_subflow_init (&subflow_ulp_ops);
Greg Kroah-Hartman
maintainerPATCH 433/568 ata: libata-scsi: Add missing scsi_device_put() in ata_scsi_dev_rescan()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yihang Li <[email protected]>
commit b32cc17d607e8ae7af037303fe101368cb4dc44c upstream.
Call scsi_device_put() in ata_scsi_dev_rescan() if the device or its queue are not running.
--- drivers/ata/libata-scsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/ata/libata-scsi.c +3 -1
@@ -4683,8 +4683,10 @@ void ata_scsi_dev_rescan(struct work_strspin_unlock_irqrestore (ap->lock, flags);if (do_resume) { ret =scsi_resume_device (sdev); -if (ret == -EWOULDBLOCK ) +if (ret == -EWOULDBLOCK ) { +scsi_device_put (sdev); goto unlock_scan; + } dev->flags &= ~ATA_DFLAG_RESUMING ; } ret =scsi_rescan_device (sdev);
Greg Kroah-Hartman
maintainerPATCH 434/568 be2net: pass wrb_params in case of OS2BMC
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrey Vatoropin <[email protected]>
commit 7d277a7a58578dd62fd546ddaef459ec24ccae36 upstream.
be_insert_vlan_in_pkt() is called with the wrb_params argument being NULL at be_send_pkt_to_bmc() call site. This may lead to dereferencing a NULL pointer when processing a workaround for specific packet, as commit bc0c3405abbb ("be2net: fix a Tx stall bug caused by a specific ipv6 packet") states.
The correct way would be to pass the wrb_params from be_xmit().
--- drivers/net/ethernet/emulex/benet/be_main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/net/ethernet/emulex/benet/be_main.c +4 -3
@@ -1297,7 +1297,8 @@ static void be_xmit_flush(struct be_adap (adapter->bmc_filt_mask & BMC_FILT_MULTICAST)static bool be_send_pkt_to_bmc (struct be_adapter *adapter, -struct sk_buff **skb) +struct sk_buff **skb, +struct be_wrb_params *wrb_params) {struct ethhdr *eh = (struct ethhdr *)(*skb)->data;bool os2bmc = false;
@@ -1361,7 +1362,7 @@ done:* to BMC, asic expects the vlan to be inline in the packet. */ if (os2bmc) - *skb =be_insert_vlan_in_pkt (adapter, *skb,NULL ); + *skb =be_insert_vlan_in_pkt (adapter, *skb, wrb_params);return os2bmc; }
@@ -1388,7 +1389,7 @@ static netdev_tx_t be_xmit(struct sk_buf/* if os2bmc is enabled and if the pkt is destined to bmc, * enqueue the pkt a 2nd time with mgmt bit set. */ -if (be_send_pkt_to_bmc (adapter, &skb)) { +if (be_send_pkt_to_bmc (adapter, &skb, &wrb_params)) {BE_WRB_F_SET (wrb_params.features,OS2BMC ,1 ); wrb_cnt =be_xmit_enqueue (adapter, txo, skb, &wrb_params);if (unlikely (!wrb_cnt))
Greg Kroah-Hartman
maintainerPATCH 435/568 net: dsa: microchip: lan937x: Fix RGMII delay tuning
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
commit 3ceb6ac2116ecda1c5d779bb73271479e70fccb4 upstream.
Correct RGMII delay application logic in lan937x_set_tune_adj().
The function was missing data16 &= ~PORT_TUNE_ADJ before setting the new delay value. This caused the new value to be bitwise-OR'd with the existing PORT_TUNE_ADJ field instead of replacing it.
For example, when setting the RGMII 2 TX delay on port 4, the intended TUNE_ADJUST value of 0 (RGMII_2_TX_DELAY_2NS) was incorrectly OR'd with the default 0x1B (from register value 0xDA3), leaving the delay at the wrong setting.
This patch adds the missing mask to clear the field, ensuring the correct delay value is written. Physical measurements on the RGMII TX lines confirm the fix, showing the delay changing from ~1ns (before change) to ~2ns.
While testing on i.MX 8MP showed this was within the platform's timing tolerance, it did not match the intended hardware-characterized value.
--- drivers/net/dsa/microchip/lan937x_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/dsa/microchip/lan937x_main.c +1 -0
@@ -328,6 +328,7 @@ static void lan937x_set_tune_adj(structksz_pread16 (dev, port, reg, &data16);/* Update tune Adjust */ + data16 &= ~PORT_TUNE_ADJ ; data16 |=FIELD_PREP (PORT_TUNE_ADJ , val);ksz_pwrite16 (dev, port, reg, data16);
Greg Kroah-Hartman
maintainerPATCH 436/568 Input: cros_ec_keyb - fix an invalid memory access
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <[email protected]>
commit e08969c4d65ac31297fcb4d31d4808c789152f68 upstream.
If cros_ec_keyb_register_matrix() isn't called (due to buttons_switches_only) in cros_ec_keyb_probe(), ckdev->idev remains NULL. An invalid memory access is observed in cros_ec_keyb_process() when receiving an EC_MKBP_EVENT_KEY_MATRIX event in cros_ec_keyb_work() in such case.
Unable to handle kernel read from unreadable memory at virtual address 0000000000000028 ... x3 : 0000000000000000 x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000000000 Call trace: input_event cros_ec_keyb_work blocking_notifier_call_chain ec_irq_thread
It's still unknown about why the kernel receives such malformed event, in any cases, the kernel shouldn't access ckdev->idev and friends if the driver doesn't intend to initialize them.
--- drivers/input/keyboard/cros_ec_keyb.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/input/keyboard/cros_ec_keyb.c +6 -0
@@ -248,6 +248,12 @@ static int cros_ec_keyb_work(struct noticase EC_MKBP_EVENT_KEY_MATRIX :pm_wakeup_event (ckdev->dev,0 ); +if (!ckdev->idev) { +dev_warn_once (ckdev->dev, +"Unexpected key matrix event\n" ); +return NOTIFY_OK ; + } +if (ckdev->ec->event_size != ckdev->cols) {dev_err (ckdev->dev,"Discarded incomplete key matrix event.\n" );
Greg Kroah-Hartman
maintainerPATCH 437/568 Input: imx_sc_key - fix memory corruption on unload
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit d83f1512758f4ef6fc5e83219fe7eeeb6b428ea4 upstream.
This is supposed to be "priv" but we accidentally pass "&priv" which is an address in the stack and so it will lead to memory corruption when the imx_sc_key_action() function is called. Remove the &.
--- drivers/input/keyboard/imx_sc_key.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/input/keyboard/imx_sc_key.c +1 -1
@@ -158,7 +158,7 @@ static int imx_sc_key_probe(struct platfreturn error; } - error =devm_add_action_or_reset (&pdev->dev, imx_sc_key_action, &priv); + error =devm_add_action_or_reset (&pdev->dev, imx_sc_key_action, priv);if (error)return error;
Greg Kroah-Hartman
maintainerPATCH 438/568 Input: pegasus-notetaker - fix potential out-of-bounds access
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Seungjin Bae <[email protected]>
commit 69aeb507312306f73495598a055293fa749d454e upstream.
In the pegasus_notetaker driver, the pegasus_probe() function allocates the URB transfer buffer using the wMaxPacketSize value from the endpoint descriptor. An attacker can use a malicious USB descriptor to force the allocation of a very small buffer.
Subsequently, if the device sends an interrupt packet with a specific pattern (e.g., where the first byte is 0x80 or 0x42),
the pegasus_parse_packet() function parses the packet without checking the allocated buffer size. This leads to an out-of-bounds memory access.
--- drivers/input/tablet/pegasus_notetaker.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/input/tablet/pegasus_notetaker.c +9 -0
@@ -63,6 +63,9 @@#define BUTTON_PRESSED 0xb5#define COMMAND_VERSION 0xa9 +/* 1 Status + 1 Color + 2 X + 2 Y = 6 bytes */ +#define NOTETAKER_PACKET_SIZE 6 +/* in xy data packet */ #define BATTERY_NO_REPORT 0x40#define BATTERY_LOW 0x41
@@ -303,6 +306,12 @@ static int pegasus_probe(struct usb_inte } pegasus->data_len =usb_maxpacket (dev, pipe); +if (pegasus->data_len <NOTETAKER_PACKET_SIZE ) { +dev_err (&intf->dev,"packet size is too small (%d)\n" , + pegasus->data_len); + error = -EINVAL ; + goto err_free_mem; + } pegasus->data =usb_alloc_coherent (dev, pegasus->data_len,GFP_KERNEL , &pegasus->data_dma);
Greg Kroah-Hartman
maintainerPATCH 439/568 nvme: nvme-fc: Ensure ->ioerr_work is cancelled in nvme_fc_delete_ctrl()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ewan D. Milne <[email protected]>
commit 0a2c5495b6d1ecb0fa18ef6631450f391a888256 upstream.
nvme_fc_delete_assocation() waits for pending I/O to complete before returning, and an error can cause ->ioerr_work to be queued after cancel_work_sync() had been called. Move the call to cancel_work_sync() to be after nvme_fc_delete_association() to ensure ->ioerr_work is not running when the nvme_fc_ctrl object is freed. Otherwise the following can occur:
[ 1135.911754] list_del corruption, ff2d24c8093f31f8->next is NULL [ 1135.917705] ------------[ cut here ]------------ [ 1135.922336] kernel BUG at lib/list_debug.c:52! [ 1135.926784] Oops: invalid opcode: 0000 [#1] SMP NOPTI [ 1135.931851] CPU: 48 UID: 0 PID: 726 Comm: kworker/u449:23 Kdump: loaded Not tainted 6.12.0 #1 PREEMPT(voluntary) [ 1135.943490] Hardware name: Dell Inc. PowerEdge R660/0HGTK9, BIOS 2.5.4 01/16/2025 [ 1135.950969] Workqueue: 0x0 (nvme-wq) [ 1135.954673] RIP: 0010:__list_del_entry_valid_or_report.cold+0xf/0x6f [ 1135.961041] Code: c7 c7 98 68 72 94 e8 26 45 fe ff 0f 0b 48 c7 c7 70 68 72 94 e8 18 45 fe ff 0f 0b 48 89 fe 48 c7 c7 80 69 72 94 e8 07 45 fe ff <0f> 0b 48 89 d1 48 c7 c7 a0 6a 72 94 48 89 c2 e8 f3 44 fe ff 0f 0b [ 1135.979788] RSP: 0018:ff579b19482d3e50 EFLAGS: 00010046 [ 1135.985015] RAX: 0000000000000033 RBX: ff2d24c8093f31f0 RCX: 0000000000000000 [ 1135.992148] RDX: 0000000000000000 RSI: ff2d24d6bfa1d0c0 RDI: ff2d24d6bfa1d0c0 [ 1135.999278] RBP: ff2d24c8093f31f8 R08: 0000000000000000 R09: ffffffff951e2b08 [ 1136.006413] R10: ffffffff95122ac8 R11: 0000000000000003 R12: ff2d24c78697c100 [ 1136.013546] R13: fffffffffffffff8 R14: 0000000000000000 R15: ff2d24c78697c0c0 [ 1136.020677] FS: 0000000000000000(0000) GS:ff2d24d6bfa00000(0000) knlGS:0000000000000000 [ 1136.028765] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1136.034510] CR2: 00007fd207f90b80 CR3: 000000163ea22003 CR4: 0000000000f73ef0 [ 1136.041641] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 1136.048776] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 [ 1136.055910] PKRU: 55555554 [ 1136.058623] Call Trace: [ 1136.061074] <TASK> [ 1136.063179] ? show_trace_log_lvl+0x1b0/0x2f0 [ 1136.067540] ? show_trace_log_lvl+0x1b0/0x2f0 [ 1136.071898] ? move_linked_works+0x4a/0xa0 [ 1136.075998] ? __list_del_entry_valid_or_report.cold+0xf/0x6f [ 1136.081744] ? __die_body.cold+0x8/0x12 [ 1136.085584] ? die+0x2e/0x50 [ 1136.088469] ? do_trap+0xca/0x110 [ 1136.091789] ? do_error_trap+0x65/0x80 [ 1136.095543] ? __list_del_entry_valid_or_report.cold+0xf/0x6f [ 1136.101289] ? exc_invalid_op+0x50/0x70 [ 1136.105127] ? __list_del_entry_valid_or_report.cold+0xf/0x6f [ 1136.110874] ? asm_exc_invalid_op+0x1a/0x20 [ 1136.115059] ? __list_del_entry_valid_or_report.cold+0xf/0x6f [ 1136.120806] move_linked_works+0x4a/0xa0 [ 1136.124733] worker_thread+0x216/0x3a0 [ 1136.128485] ? __pfx_worker_thread+0x10/0x10 [ 1136.132758] kthread+0xfa/0x240 [ 1136.135904] ? __pfx_kthread+0x10/0x10 [ 1136.139657] ret_from_fork+0x31/0x50 [ 1136.143236] ? __pfx_kthread+0x10/0x10 [ 1136.146988] ret_from_fork_asm+0x1a/0x30 [ 1136.150915] </TASK>
--- drivers/nvme/host/fc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/nvme/host/fc.c +1 -1
@@ -3262,7 +3262,6 @@ nvme_fc_delete_ctrl(struct nvme_ctrl *nc {struct nvme_fc_ctrl *ctrl =to_fc_ctrl (nctrl); -cancel_work_sync (&ctrl->ioerr_work);cancel_delayed_work_sync (&ctrl->connect_work);/* * kill the association on the link side. this will block
@@ -3333,6 +3332,7 @@ nvme_fc_reset_ctrl_work(struct work_stru/* will block will waiting for io to terminate */ nvme_fc_delete_association (ctrl); +cancel_work_sync (&ctrl->ioerr_work);if (!nvme_change_ctrl_state (&ctrl->ctrl,NVME_CTRL_CONNECTING )) dev_err(ctrl->ctrl.device,
Greg Kroah-Hartman
maintainerPATCH 440/568 scsi: sg: Do not sleep in atomic context
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit 90449f2d1e1f020835cba5417234636937dd657e upstream.
sg_finish_rem_req() calls blk_rq_unmap_user(). The latter function may sleep. Hence, call sg_finish_rem_req() with interrupts enabled instead of disabled.
--- drivers/scsi/sg.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/scsi/sg.c +9 -1
@@ -2204,9 +2204,17 @@ sg_remove_sfp_usercontext(struct work_stwrite_lock_irqsave (&sfp->rq_list_lock, iflags);while (!list_empty (&sfp->rq_list)) { srp =list_first_entry (&sfp->rq_list, Sg_request, entry); -sg_finish_rem_req (srp);list_del (&srp->entry); +write_unlock_irqrestore (&sfp->rq_list_lock, iflags); + +sg_finish_rem_req (srp); +/* +* sg_rq_end_io() uses srp->parentfp. Hence, only clear +* srp->parentfp after blk_mq_free_request() has been called. +*/ srp->parentfp =NULL ; + +write_lock_irqsave (&sfp->rq_list_lock, iflags); }write_unlock_irqrestore (&sfp->rq_list_lock, iflags);
Greg Kroah-Hartman
maintainerPATCH 441/568 scsi: target: tcm_loop: Fix segfault in tcm_loop_tpg_address_show()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hamza Mahfooz <[email protected]>
commit e6965188f84a7883e6a0d3448e86b0cf29b24dfc upstream.
If the allocation of tl_hba->sh fails in tcm_loop_driver_probe() and we attempt to dereference it in tcm_loop_tpg_address_show() we will get a segfault, see below for an example. So, check tl_hba->sh before dereferencing it.
Unable to allocate struct scsi_host
BUG: kernel NULL pointer dereference, address: 0000000000000194 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] PREEMPT SMP NOPTI CPU: 1 PID: 8356 Comm: tokio-runtime-w Not tainted 6.6.104.2-4.azl3 #1 Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.1 09/28/2024 RIP: 0010:tcm_loop_tpg_address_show+0x2e/0x50 [tcm_loop] ... Call Trace: <TASK> configfs_read_iter+0x12d/0x1d0 [configfs] vfs_read+0x1b5/0x300 ksys_read+0x6f/0xf0
...
--- drivers/target/loopback/tcm_loop.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/target/loopback/tcm_loop.c +3 -0
@@ -934,6 +934,9 @@ static ssize_t tcm_loop_tpg_address_show struct tcm_loop_tpg, tl_se_tpg);struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba; +if (!tl_hba->sh) +return -ENODEV ; +return snprintf (page,PAGE_SIZE ,"%d:0:%d\n" , tl_hba->sh->host_no, tl_tpg->tl_tpgt); }
Greg Kroah-Hartman
maintainerPATCH 442/568 MIPS: Malta: Fix !EVA SOC-it PCI MMIO
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maciej W. Rozycki <[email protected]>
commit ebd729fef31620e0bf74cbf8a4c7fda73a2a4e7e upstream.
Fix a regression that has caused accesses to the PCI MMIO window to complete unclaimed in non-EVA configurations with the SOC-it family of system controllers, preventing PCI devices from working that use MMIO.
In the non-EVA case PHYS_OFFSET is set to 0, meaning that PCI_BAR0 is set with an empty mask (and PCI_HEAD4 matches addresses starting from 0 accordingly). Consequently all addresses are matched for incoming DMA accesses from PCI. This seems to confuse the system controller's logic and outgoing bus cycles targeting the PCI MMIO window seem not to make it to the intended devices.
This happens as well when a wider mask is used with PCI_BAR0, such as 0x80000000 or 0xe0000000, that makes addresses match that overlap with the PCI MMIO window, which starts at 0x10000000 in our configuration.
Set the mask in PCI_BAR0 to 0xf0000000 for non-EVA then, covering the non-EVA maximum 256 MiB of RAM, which is what YAMON does and which used to work correctly up to the offending commit. Set PCI_P2SCMSKL to match PCI_BAR0 as required by the system controller's specification, and match PCI_P2SCMAPL to PCI_HEAD4 for identity mapping.
Verified with:
Core board type/revision = 0x0d (Core74K) / 0x01 System controller/revision = MIPS SOC-it 101 OCP / 1.3 SDR-FW-4:1 Processor Company ID/options = 0x01 (MIPS Technologies, Inc.) / 0x1c Processor ID/revision = 0x97 (MIPS 74Kf) / 0x4c
for non-EVA and with:
Core board type/revision = 0x0c (CoreFPGA-5) / 0x00 System controller/revision = MIPS ROC-it2 / 0.0 FW-1:1 (CLK_unknown) GIC Processor Company ID/options = 0x01 (MIPS Technologies, Inc.) / 0x00 Processor ID/revision = 0xa0 (MIPS interAptiv UP) / 0x20
for EVA/non-EVA, fixing:
defxx 0000:00:12.0: assign IRQ: got 10
defxx: v1.12 2021/03/10 Lawrence V. Stefani and others 0000:00:12.0: Could not read adapter factory MAC address!
vs:
defxx 0000:00:12.0: assign IRQ: got 10
defxx: v1.12 2021/03/10 Lawrence V. Stefani and others
0000:00:12.0: DEFPA at MMIO addr = 0x10142000, IRQ = 10, Hardware addr = 00-00-f8-xx-xx-xx 0000:00:12.0: registered as fddi0
for non-EVA and causing no change for EVA.
--- arch/mips/mti-malta/malta-init.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
arch/mips/mti-malta/malta-init.c +13 -7
@@ -241,16 +241,22 @@ mips_pci_controller:#endif /* -* Setup the Malta max (2GB) memory for PCI DMA in host bridge -* in transparent addressing mode. +* Set up memory mapping in host bridge for PCI DMA masters, +* in transparent addressing mode. For EVA use the Malta +* maximum of 2 GiB memory in the alias space at 0x80000000 +* as per PHYS_OFFSET. Otherwise use 256 MiB of memory in +* the regular space, avoiding mapping the PCI MMIO window +* for DMA as it seems to confuse the system controller's +* logic, causing PCI MMIO to stop working. */ - mask =PHYS_OFFSET |PCI_BASE_ADDRESS_MEM_PREFETCH ; -MSC_WRITE (MSC01_PCI_BAR0 , mask); -MSC_WRITE (MSC01_PCI_HEAD4 , mask); + mask =PHYS_OFFSET ?PHYS_OFFSET :0xf0000000 ; +MSC_WRITE (MSC01_PCI_BAR0 , + mask |PCI_BASE_ADDRESS_MEM_PREFETCH ); +MSC_WRITE (MSC01_PCI_HEAD4 , +PHYS_OFFSET |PCI_BASE_ADDRESS_MEM_PREFETCH ); - mask &=MSC01_PCI_BAR0_SIZE_MSK ;MSC_WRITE (MSC01_PCI_P2SCMSKL , mask); -MSC_WRITE (MSC01_PCI_P2SCMAPL , mask); +MSC_WRITE (MSC01_PCI_P2SCMAPL ,PHYS_OFFSET );/* Don't handle target retries indefinitely. */ if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) ==
Greg Kroah-Hartman
maintainerPATCH 443/568 LoongArch: Dont panic if no valid cache info for PCI
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen <[email protected]>
commit a6b533adfc05ba15360631e019d3e18275080275 upstream.
If there is no valid cache info detected (may happen in virtual machine) for pci_dfl_cache_line_size, kernel shouldn't panic. Because in the PCI core it will be evaluated to (L1_CACHE_BYTES >> 2).
--- arch/loongarch/pci/pci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/loongarch/pci/pci.c +4 -4
@@ -51,11 +51,11 @@ static int __init pcibios_init(void)*/ lsize =cpu_last_level_cache_line_size (); -BUG_ON (!lsize); +if (lsize) { + pci_dfl_cache_line_size = lsize >>2 ; - pci_dfl_cache_line_size = lsize >>2 ; - -pr_debug ("PCI: pci_cache_line_size set to %d bytes\n" , lsize); +pr_debug ("PCI: pci_cache_line_size set to %d bytes\n" , lsize); + }return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 444/568 mptcp: fix race condition in mptcp_schedule_work()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
commit 035bca3f017ee9dea3a5a756e77a6f7138cc6eea upstream.
syzbot reported use-after-free in mptcp_schedule_work() [1]
Issue here is that mptcp_schedule_work() schedules a work, then gets a refcount on sk->sk_refcnt if the work was scheduled. This refcount will be released by mptcp_worker().
[A] if (schedule_work(...)) {
[B] sock_hold(sk);
return true;
}Problem is that mptcp_worker() can run immediately and complete before [B]
We need instead :
sock_hold(sk);
if (schedule_work(...))
return true;
sock_put(sk);[1]refcount_t: addition on 0; use-after-free.
WARNING: CPU: 1 PID: 29 at lib/refcount.c:25 refcount_warn_saturate+0xfa/0x1d0 lib/refcount.c:25 Call Trace: <TASK> __refcount_add include/linux/refcount.h:-1 [inline] __refcount_inc include/linux/refcount.h:366 [inline] refcount_inc include/linux/refcount.h:383 [inline] sock_hold include/net/sock.h:816 [inline] mptcp_schedule_work+0x164/0x1a0 net/mptcp/protocol.c:943 mptcp_tout_timer+0x21/0xa0 net/mptcp/protocol.c:2316 call_timer_fn+0x17e/0x5f0 kernel/time/timer.c:1747 expire_timers kernel/time/timer.c:1798 [inline] __run_timers kernel/time/timer.c:2372 [inline] __run_timer_base+0x648/0x970 kernel/time/timer.c:2384 run_timer_base kernel/time/timer.c:2393 [inline] run_timer_softirq+0xb7/0x180 kernel/time/timer.c:2403 handle_softirqs+0x22f/0x710 kernel/softirq.c:622 __do_softirq kernel/softirq.c:656 [inline] run_ktimerd+0xcf/0x190 kernel/softirq.c:1138 smpboot_thread_fn+0x542/0xa60 kernel/smpboot.c:160 kthread+0x711/0x8a0 kernel/kthread.c:463 ret_from_fork+0x4bc/0x870 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
--- net/mptcp/protocol.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)
net/mptcp/protocol.c +12 -7
@@ -966,14 +966,19 @@ static void mptcp_reset_rtx_timer(structbool mptcp_schedule_work (struct sock *sk) { -if (inet_sk_state_load (sk) !=TCP_CLOSE && -schedule_work (&mptcp_sk (sk)->work)) { -/* each subflow already holds a reference to the sk, and the -* workqueue is invoked by a subflow, so sk can't go away here. -*/ -sock_hold (sk); +if (inet_sk_state_load (sk) ==TCP_CLOSE ) +return false; + +/* Get a reference on this socket, mptcp_worker() will release it. +* As mptcp_worker() might complete before us, we can not avoid +* a sock_hold()/sock_put() if schedule_work() returns false. +*/ +sock_hold (sk); + +if (schedule_work (&mptcp_sk (sk)->work))return true; - } + +sock_put (sk);return false; }
Greg Kroah-Hartman
maintainerPATCH 445/568 mptcp: fix ack generation for fallback msk
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
commit 5e15395f6d9ec07395866c5511f4b4ac566c0c9b upstream.
mptcp_cleanup_rbuf() needs to know the last most recent, mptcp-level rcv_wnd sent, and such information is tracked into the msk->old_wspace field, updated at ack transmission time by mptcp_write_options().
Fallback socket do not add any mptcp options, such helper is never invoked, and msk->old_wspace value remain stale. That in turn makes ack generation at recvmsg() time quite random.
Address the issue ensuring mptcp_write_options() is invoked even for fallback sockets, and just update the needed info in such a case.
The issue went unnoticed for a long time, as mptcp currently overshots the fallback socket receive buffer autotune significantly. It is going to change in the near future.
--- net/mptcp/options.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-)
net/mptcp/options.c +22 -1
@@ -834,8 +834,11 @@ bool mptcp_established_options(struct so opts->suboptions =0 ; +/* Force later mptcp_write_options(), but do not use any actual +* option space. +*/ if (unlikely (__mptcp_check_fallback (msk) && !mptcp_check_infinite_map (skb))) -return false; +return true;if (unlikely (skb &&TCP_SKB_CB (skb)->tcp_flags &TCPHDR_RST )) { if (mptcp_established_options_fastclose(sk, &opt_size, remaining, opts) ||
@@ -1296,6 +1299,20 @@ update_wspace:WRITE_ONCE (msk->old_wspace, tp->rcv_wnd); } +static void mptcp_track_rwin (struct tcp_sock *tp) +{ +const struct sock *ssk = (const struct sock *)tp; +struct mptcp_subflow_context *subflow; +struct mptcp_sock *msk; + +if (!ssk) +return ; + + subflow =mptcp_subflow_ctx (ssk); + msk =mptcp_sk (subflow->conn); +WRITE_ONCE (msk->old_wspace, tp->rcv_wnd); +} +__sum16 __mptcp_make_csum (u64 data_seq,u32 subflow_seq,u16 data_len,__wsum sum) {struct csum_pseudo_header header;
@@ -1588,6 +1605,10 @@ mp_rst: opts->reset_transient, opts->reset_reason);return ; + }else if (unlikely (!opts->suboptions)) { +/* Fallback to TCP */ +mptcp_track_rwin (tp); +return ; }if (OPTION_MPTCP_PRIO & opts->suboptions) {
Greg Kroah-Hartman
maintainerPATCH 446/568 mptcp: fix premature close in case of fallback
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
commit 17393fa7b7086664be519e7230cb6ed7ec7d9462 upstream.
I'm observing very frequent self-tests failures in case of fallback when running on a CONFIG_PREEMPT kernel.
The root cause is that subflow_sched_work_if_closed() closes any subflow as soon as it is half-closed and has no incoming data pending.
That works well for regular subflows - MPTCP needs bi-directional connectivity to operate on a given subflow - but for fallback socket is race prone.
When TCP peer closes the connection before the MPTCP one, subflow_sched_work_if_closed() will schedule the MPTCP worker to gracefully close the subflow, and shortly after will do another schedule to inject and process a dummy incoming DATA_FIN.
On CONFIG_PREEMPT kernel, the MPTCP worker can kick-in and close the fallback subflow before subflow_sched_work_if_closed() is able to create the dummy DATA_FIN, unexpectedly interrupting the transfer.
Address the issue explicitly avoiding closing fallback subflows on when the peer is only half-closed.
Note that, when the subflow is able to create the DATA_FIN before the worker invocation, the worker will change the msk state before trying to close the subflow and will skip the latter operation as the msk will not match anymore the precondition in __mptcp_close_subflow().
--- net/mptcp/protocol.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/mptcp/protocol.c +2 -1
@@ -2598,7 +2598,8 @@ static void __mptcp_close_subflow(structif (ssk_state !=TCP_CLOSE && (ssk_state !=TCP_CLOSE_WAIT || -inet_sk_state_load (sk) !=TCP_ESTABLISHED )) +inet_sk_state_load (sk) !=TCP_ESTABLISHED || +__mptcp_check_fallback (msk)))continue ;/* 'subflow_data_ready' will re-sched once rx queue is empty */
Greg Kroah-Hartman
maintainerPATCH 447/568 mptcp: avoid unneeded subflow-level drops
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
commit 4f102d747cadd8f595f2b25882eed9bec1675fb1 upstream.
The rcv window is shared among all the subflows. Currently, MPTCP sync the TCP-level rcv window with the MPTCP one at tcp_transmit_skb() time.
The above means that incoming data may sporadically observe outdated TCP-level rcv window and being wrongly dropped by TCP.
Address the issue checking for the edge condition before queuing the data at TCP level, and eventually syncing the rcv window as needed.
Note that the issue is actually present from the very first MPTCP implementation, but backports older than the blamed commit below will range from impossible to useless.
Before:
$ nstat -n; sleep 1; nstat -z TcpExtBeyondWindow TcpExtBeyondWindow 14 0.0
After:
$ nstat -n; sleep 1; nstat -z TcpExtBeyondWindow TcpExtBeyondWindow 0 0.0
--- net/mptcp/options.c | 31 +++++++++++++++++++++++++++++++ net/mptcp/protocol.h | 1 + 2 files changed, 32 insertions(+)
net/mptcp/options.c +31 -0
@@ -1028,6 +1028,31 @@ u64 __mptcp_expand_seq(u64 old_seq, u64return cur_seq; } +static void rwin_update (struct mptcp_sock *msk,struct sock *ssk, +struct sk_buff *skb) +{ +struct mptcp_subflow_context *subflow =mptcp_subflow_ctx (ssk); +struct tcp_sock *tp =tcp_sk (ssk); +u64 mptcp_rcv_wnd; + +/* Avoid touching extra cachelines if TCP is going to accept this +* skb without filling the TCP-level window even with a possibly +* outdated mptcp-level rwin. +*/ +if (!skb->len || skb->len <tcp_receive_window (tp)) +return ; + + mptcp_rcv_wnd =atomic64_read (&msk->rcv_wnd_sent); +if (!after64 (mptcp_rcv_wnd, subflow->rcv_wnd_sent)) +return ; + +/* Some other subflow grew the mptcp-level rwin since rcv_wup, +* resync. +*/ + tp->rcv_wnd += mptcp_rcv_wnd - subflow->rcv_wnd_sent; + subflow->rcv_wnd_sent = mptcp_rcv_wnd; +} +static void ack_update_msk (struct mptcp_sock *msk,struct sock *ssk,struct mptcp_options_received *mp_opt)
@@ -1188,6 +1213,7 @@ bool mptcp_incoming_options(struct sock*/ if (mp_opt.use_ack)ack_update_msk (msk, sk, &mp_opt); +rwin_update (msk, sk, skb);/* Zero-data-length packets are dropped by the caller and not * propagated to the MPTCP layer, so the skb extension does not
@@ -1274,6 +1300,10 @@ static void mptcp_set_rwin(struct tcp_soif (rcv_wnd_new != rcv_wnd_old) { raise_win: +/* The msk-level rcv wnd is after the tcp level one, +* sync the latter. +*/ + rcv_wnd_new = rcv_wnd_old; win = rcv_wnd_old - ack_seq; tp->rcv_wnd =min_t (u64, win,U32_MAX ); new_win = tp->rcv_wnd;
@@ -1297,6 +1327,7 @@ raise_win: update_wspace:WRITE_ONCE (msk->old_wspace, tp->rcv_wnd); + subflow->rcv_wnd_sent = rcv_wnd_new; }static void mptcp_track_rwin (struct tcp_sock *tp)
net/mptcp/protocol.h +1 -0
@@ -458,6 +458,7 @@ struct mptcp_subflow_context {u64 remote_key;u64 idsn;u64 map_seq; +u64 rcv_wnd_sent;u32 snd_isn;u32 token;u32 rel_write_seq;
Greg Kroah-Hartman
maintainerPATCH 448/568 mptcp: do not fallback when OoO is present
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
commit 1bba3f219c5e8c29e63afa3c1fc24f875ebec119 upstream.
In case of DSS corruption, the MPTCP protocol tries to avoid the subflow reset if fallback is possible. Such corruptions happen in the receive path; to ensure fallback is possible the stack additionally needs to check for OoO data, otherwise the fallback will break the data stream.
--- net/mptcp/protocol.c | 7 +++++++ 1 file changed, 7 insertions(+)
net/mptcp/protocol.c +7 -0
@@ -911,6 +911,13 @@ static bool __mptcp_finish_join(struct mif (sk->sk_state !=TCP_ESTABLISHED )return false; +/* The caller possibly is not holding the msk socket lock, but +* in the fallback case only the current subflow is touching +* the OoO queue. +*/ +if (!RB_EMPTY_ROOT (&msk->out_of_order_queue)) +return false; +spin_lock_bh (&msk->fallback_lock);if (!msk->allow_subflows) {spin_unlock_bh (&msk->fallback_lock);
Greg Kroah-Hartman
maintainerPATCH 449/568 drm/tegra: dc: Fix reference leak in tegra_dc_couple()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit 4c5376b4b143c4834ebd392aef2215847752b16a upstream.
driver_find_device() calls get_device() to increment the reference count once a matching device is found, but there is no put_device() to balance the reference count. To avoid reference count leakage, add put_device() to decrease the reference count.
Found by code review.
--- drivers/gpu/drm/tegra/dc.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/tegra/dc.c +1 -0
@@ -3141,6 +3141,7 @@ static int tegra_dc_couple(struct tegra_ dc->client.parent = &parent->client;dev_dbg (dc->dev,"coupled to %s\n" ,dev_name (companion)); +put_device (companion); }return 0 ;
Greg Kroah-Hartman
maintainerPATCH 450/568 drm/amdgpu: Skip emit de meta data on gfx11 with rs64 enabled
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yifan Zha <[email protected]>
commit 80d8a9ad1587b64c545d515ab6cb7ecb9908e1b3 upstream.
[Why]
Accoreding to CP updated to RS64 on gfx11,WRITE_DATA with PREEMPTION_META_MEMORY(dst_sel=8) is illegal for CP FW. That packet is used for MCBP on F32 based system.
So it would lead to incorrect GRBM write and FW is not handling that extra case correctly.
[How]
With gfx11 rs64 enabled, skip emit de meta data.
--- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +2 -2
@@ -5392,9 +5392,9 @@ static void gfx_v11_0_ring_emit_ib_gfx(sif (flags &AMDGPU_IB_PREEMPTED ) control |=INDIRECT_BUFFER_PRE_RESUME (1 ); -if (vmid) +if (vmid && !ring->adev->gfx.rs64_enable)gfx_v11_0_ring_emit_de_meta (ring, - (!amdgpu_sriov_vf (ring->adev) && flags &AMDGPU_IB_PREEMPTED ) ? true : false); + !amdgpu_sriov_vf (ring->adev) && (flags &AMDGPU_IB_PREEMPTED )); }if (ring->is_mes_queue)
Greg Kroah-Hartman
maintainerPATCH 451/568 xfrm: Determine inner GSO type from packet inner protocol
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jianbo Liu <[email protected]>
[ Upstream commit 61fafbee6cfed283c02a320896089f658fa67e56 ]
The GSO segmentation functions for ESP tunnel mode (xfrm4_tunnel_gso_segment and xfrm6_tunnel_gso_segment) were determining the inner packet's L2 protocol type by checking the static x->inner_mode.family field from the xfrm state.
This is unreliable. In tunnel mode, the state's actual inner family could be defined by x->inner_mode.family or by x->inner_mode_iaf.family. Checking only the former can lead to a mismatch with the actual packet being processed, causing GSO to create segments with the wrong L2 header type.
This patch fixes the bug by deriving the inner mode directly from the packet's inner protocol stored in XFRM_MODE_SKB_CB(skb)->protocol.
Instead of replicating the code, this patch modifies the xfrm_ip2inner_mode helper function. It now correctly returns &x->inner_mode if the selector family (x->sel.family) is already specified, thereby handling both specific and AF_UNSPEC cases appropriately.
With this change, ESP GSO can use xfrm_ip2inner_mode to get the correct inner mode. It doesn't affect existing callers, as the updated logic now mirrors the checks they were already performing externally.
--- include/net/xfrm.h | 3 ++- net/ipv4/esp4_offload.c | 6 ++++-- net/ipv6/esp6_offload.c | 6 ++++-- 3 files changed, 10 insertions(+), 5 deletions(-)
include/net/xfrm.h +2 -1
@@ -446,7 +446,8 @@ static inline int xfrm_af2proto(unsigned int family)static inline const struct xfrm_mode *xfrm_ip2inner_mode (struct xfrm_state *x,int ipproto) { -if ((ipproto ==IPPROTO_IPIP && x->props.family ==AF_INET ) || +if ((x->sel.family !=AF_UNSPEC ) || + (ipproto ==IPPROTO_IPIP && x->props.family ==AF_INET ) || (ipproto ==IPPROTO_IPV6 && x->props.family ==AF_INET6 ))return &x->inner_mode;else
net/ipv4/esp4_offload.c +4 -2
@@ -110,8 +110,10 @@ static struct sk_buff *xfrm4_tunnel_gso_segment(struct xfrm_state *x, struct sk_buff *skb, netdev_features_t features) { -__be16 type = x->inner_mode.family ==AF_INET6 ?htons (ETH_P_IPV6 ) - :htons (ETH_P_IP ); +const struct xfrm_mode *inner_mode =xfrm_ip2inner_mode (x, +XFRM_MODE_SKB_CB (skb)->protocol); +__be16 type = inner_mode->family ==AF_INET6 ?htons (ETH_P_IPV6 ) + :htons (ETH_P_IP );return skb_eth_gso_segment (skb, features, type); }
net/ipv6/esp6_offload.c +4 -2
@@ -145,8 +145,10 @@ static struct sk_buff *xfrm6_tunnel_gso_segment(struct xfrm_state *x, struct sk_buff *skb, netdev_features_t features) { -__be16 type = x->inner_mode.family ==AF_INET ?htons (ETH_P_IP ) - :htons (ETH_P_IPV6 ); +const struct xfrm_mode *inner_mode =xfrm_ip2inner_mode (x, +XFRM_MODE_SKB_CB (skb)->protocol); +__be16 type = inner_mode->family ==AF_INET ?htons (ETH_P_IP ) + :htons (ETH_P_IPV6 );return skb_eth_gso_segment (skb, features, type); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 452/568 mlxsw: spectrum: Fix memory leak in mlxsw_sp_flower_stats()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zilin Guan <[email protected]>
[ Upstream commit 407a06507c2358554958e8164dc97176feddcafc ]
The function mlxsw_sp_flower_stats() calls mlxsw_sp_acl_ruleset_get() to obtain a ruleset reference. If the subsequent call to mlxsw_sp_acl_rule_lookup() fails to find a rule, the function returns an error without releasing the ruleset reference, causing a memory leak.
Fix this by using a goto to the existing error handling label, which calls mlxsw_sp_acl_ruleset_put() to properly release the reference.
--- drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +4 -2
@@ -719,8 +719,10 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp,return -EINVAL ; rule =mlxsw_sp_acl_rule_lookup (mlxsw_sp, ruleset, f->cookie); -if (!rule) -return -EINVAL ; +if (!rule) { + err = -EINVAL ; + goto err_rule_get_stats; + } err =mlxsw_sp_acl_rule_get_stats (mlxsw_sp, rule, &packets, &bytes, &drops, &lastuse, &used_hw_stats);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 453/568 gpu: host1x: Select context device based on attached IOMMU
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikko Perttunen <[email protected]>
[ Upstream commit 8935002fc37fce1ad211d98a70f2fd42083c0594 ]
On Tegra234, engines that are programmed through Host1x channels can be attached to either the NISO0 or NISO1 SMMU. Because of that, when selecting a context device to use with an engine, we need to select one that is also attached to the same SMMU.
Add a parameter to host1x_memory_context_alloc to specify which device we are allocating a context for, and use it to pick an appropriate context device.
Stable-dep-of: 6cbab9f0da72 ("drm/tegra: Add call to put_pid()")
--- drivers/gpu/drm/tegra/uapi.c | 2 +- drivers/gpu/host1x/context.c | 4 ++++ include/linux/host1x.h | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-)
drivers/gpu/drm/tegra/uapi.c +1 -1
@@ -116,7 +116,7 @@ int tegra_drm_ioctl_channel_open(struct drm_device *drm, void *data, struct drm_if (supported) context->memory_context =host1x_memory_context_alloc ( - host,get_task_pid (current,PIDTYPE_TGID )); + host, client->base.dev,get_task_pid (current,PIDTYPE_TGID ));if (IS_ERR (context->memory_context)) {if (PTR_ERR (context->memory_context) != -EOPNOTSUPP ) {
drivers/gpu/host1x/context.c +4 -0
@@ -112,6 +112,7 @@ void host1x_memory_context_list_free(struct host1x_memory_context_list *cdl) }struct host1x_memory_context *host1x_memory_context_alloc (struct host1x *host1x, +struct device *dev,struct pid *pid) {struct host1x_memory_context_list *cdl = &host1x->context_list;
@@ -126,6 +127,9 @@ struct host1x_memory_context *host1x_memory_context_alloc(struct host1x *host1x,for (i =0 ; i < cdl->len; i++) {struct host1x_memory_context *cd = &cdl->devs[i]; +if (cd->dev.iommu->iommu_dev != dev->iommu->iommu_dev) +continue ; +if (cd->owner == pid) {refcount_inc (&cd->ref);mutex_unlock (&cdl->lock);
include/linux/host1x.h +2 -0
@@ -469,11 +469,13 @@ struct host1x_memory_context {#ifdef CONFIG_IOMMU_API struct host1x_memory_context *host1x_memory_context_alloc (struct host1x *host1x, +struct device *dev,struct pid *pid);void host1x_memory_context_get (struct host1x_memory_context *cd);void host1x_memory_context_put (struct host1x_memory_context *cd);#else static inline struct host1x_memory_context *host1x_memory_context_alloc (struct host1x *host1x, +struct device *dev,struct pid *pid) {return NULL ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 454/568 drm/tegra: Add call to put_pid()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prateek Agarwal <[email protected]>
[ Upstream commit 6cbab9f0da72b4dc3c3f9161197aa3b9daa1fa3a ]
Add a call to put_pid() corresponding to get_task_pid(). host1x_memory_context_alloc() does not take ownership of the PID so we need to free it here to avoid leaking.
--- drivers/gpu/drm/tegra/uapi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/gpu/drm/tegra/uapi.c +5 -2
@@ -114,9 +114,12 @@ int tegra_drm_ioctl_channel_open(struct drm_device *drm, void *data, struct drm_if (err) goto put_channel; -if (supported) +if (supported) { +struct pid *pid =get_task_pid (current,PIDTYPE_TGID ); context->memory_context =host1x_memory_context_alloc ( - host, client->base.dev,get_task_pid (current,PIDTYPE_TGID )); + host, client->base.dev, pid); +put_pid (pid); + }if (IS_ERR (context->memory_context)) {if (PTR_ERR (context->memory_context) != -EOPNOTSUPP ) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 455/568 net: dsa: hellcreek: fix missing error handling in LED registration
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Zhigulin <[email protected]>
[ Upstream commit e6751b0b19a6baab219a62e1e302b8aa6b5a55b2 ]
The LED setup routine registered both led_sync_good and led_is_gm devices without checking the return values of led_classdev_register(). If either registration failed, the function continued silently, leaving the driver in a partially-initialized state and leaking a registered LED classdev.
Add proper error handling
--- drivers/net/dsa/hirschmann/hellcreek_ptp.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/net/dsa/hirschmann/hellcreek_ptp.c +12 -2
@@ -367,8 +367,18 @@ static int hellcreek_led_setup(struct hellcreek *hellcreek)hellcreek_set_brightness (hellcreek,STATUS_OUT_IS_GM ,1 );/* Register both leds */ -led_classdev_register (hellcreek->dev, &hellcreek->led_sync_good); -led_classdev_register (hellcreek->dev, &hellcreek->led_is_gm); + ret =led_classdev_register (hellcreek->dev, &hellcreek->led_sync_good); +if (ret) { +dev_err (hellcreek->dev,"Failed to register sync_good LED\n" ); + goto out; + } + + ret =led_classdev_register (hellcreek->dev, &hellcreek->led_is_gm); +if (ret) { +dev_err (hellcreek->dev,"Failed to register is_gm LED\n" ); +led_classdev_unregister (&hellcreek->led_sync_good); + goto out; + } ret =0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 456/568 net: mlxsw: linecards: fix missing error check in mlxsw_linecard_devlink_info_get()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Zhigulin <[email protected]>
[ Upstream commit b0c959fec18f4595a6a6317ffc30615cfa37bf69 ]
The call to devlink_info_version_fixed_put() in mlxsw_linecard_devlink_info_get() did not check for errors, although it is checked everywhere in the code.
Add missed 'err' check to the mlxsw_linecard_devlink_info_get()
--- drivers/net/ethernet/mellanox/mlxsw/core_linecards.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/core_linecards.c +2 -0
@@ -601,6 +601,8 @@ int mlxsw_linecard_devlink_info_get(struct mlxsw_linecard *linecard, err =devlink_info_version_fixed_put (req,DEVLINK_INFO_VERSION_GENERIC_FW_PSID , info->psid); +if (err) + goto unlock;sprintf (buf,"%u.%u.%u" , info->fw_major, info->fw_minor, info->fw_sub_minor);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 457/568 net: openvswitch: remove never-working support for setting nsh fields
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Maximets <[email protected]>
[ Upstream commit dfe28c4167a9259fc0c372d9f9473e1ac95cff67 ]
The validation of the set(nsh(...)) action is completely wrong. It runs through the nsh_key_put_from_nlattr() function that is the same function that validates NSH keys for the flow match and the push_nsh() action. However, the set(nsh(...)) has a very different memory layout. Nested attributes in there are doubled in size in case of the masked set(). That makes proper validation impossible.
There is also confusion in the code between the 'masked' flag, that says that the nested attributes are doubled in size containing both the value and the mask, and the 'is_mask' that says that the value we're parsing is the mask. This is causing kernel crash on trying to write into mask part of the match with SW_FLOW_KEY_PUT() during validation, while validate_nsh() doesn't allocate any memory for it:
BUG: kernel NULL pointer dereference, address: 0000000000000018 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 1c2383067 P4D 1c2383067 PUD 20b703067 PMD 0 Oops: Oops: 0000 [#1] SMP NOPTI CPU: 8 UID: 0 Kdump: loaded Not tainted 6.17.0-rc4+ #107 PREEMPT(voluntary) RIP: 0010:nsh_key_put_from_nlattr+0x19d/0x610 [openvswitch] Call Trace: <TASK> validate_nsh+0x60/0x90 [openvswitch] validate_set.constprop.0+0x270/0x3c0 [openvswitch] __ovs_nla_copy_actions+0x477/0x860 [openvswitch] ovs_nla_copy_actions+0x8d/0x100 [openvswitch] ovs_packet_cmd_execute+0x1cc/0x310 [openvswitch] genl_family_rcv_msg_doit+0xdb/0x130 genl_family_rcv_msg+0x14b/0x220 genl_rcv_msg+0x47/0xa0 netlink_rcv_skb+0x53/0x100 genl_rcv+0x24/0x40 netlink_unicast+0x280/0x3b0 netlink_sendmsg+0x1f7/0x430 ____sys_sendmsg+0x36b/0x3a0 ___sys_sendmsg+0x87/0xd0 __sys_sendmsg+0x6d/0xd0 do_syscall_64+0x7b/0x2c0 entry_SYSCALL_64_after_hwframe+0x76/0x7e
The third issue with this process is that while trying to convert the non-masked set into masked one, validate_set() copies and doubles the size of the OVS_KEY_ATTR_NSH as if it didn't have any nested attributes. It should be copying each nested attribute and doubling them in size independently. And the process must be properly reversed during the conversion back from masked to a non-masked variant during the flow dump.
In the end, the only two outcomes of trying to use this action are either validation failure or a kernel crash. And if somehow someone manages to install a flow with such an action, it will most definitely not do what it is supposed to, since all the keys and the masks are mixed up.
Fixing all the issues is a complex task as it requires re-writing most of the validation code.
Given that and the fact that this functionality never worked since introduction, let's just remove it altogether. It's better to re-introduce it later with a proper implementation instead of trying to fix it in stable releases.
--- net/openvswitch/actions.c | 68 +--------------------------------- net/openvswitch/flow_netlink.c | 64 ++++---------------------------- net/openvswitch/flow_netlink.h | 2 - 3 files changed, 9 insertions(+), 125 deletions(-)
net/openvswitch/actions.c +1 -67
@@ -595,69 +595,6 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key,return 0 ; } -static int set_nsh (struct sk_buff *skb,struct sw_flow_key *flow_key, -const struct nlattr *a) -{ -struct nshhdr *nh; -size_t length; -int err; -u8 flags; -u8 ttl; -int i; - -struct ovs_key_nsh key; -struct ovs_key_nsh mask; - - err =nsh_key_from_nlattr (a, &key, &mask); -if (err) -return err; - -/* Make sure the NSH base header is there */ -if (!pskb_may_pull (skb,skb_network_offset (skb) +NSH_BASE_HDR_LEN )) -return -ENOMEM ; - - nh =nsh_hdr (skb); - length =nsh_hdr_len (nh); - -/* Make sure the whole NSH header is there */ - err =skb_ensure_writable (skb,skb_network_offset (skb) + - length); -if (unlikely (err)) -return err; - - nh =nsh_hdr (skb); -skb_postpull_rcsum (skb, nh, length); - flags =nsh_get_flags (nh); - flags =OVS_MASKED (flags, key.base.flags, mask.base.flags); - flow_key->nsh.base.flags = flags; - ttl =nsh_get_ttl (nh); - ttl =OVS_MASKED (ttl, key.base.ttl, mask.base.ttl); - flow_key->nsh.base.ttl = ttl; -nsh_set_flags_and_ttl (nh, flags, ttl); - nh->path_hdr =OVS_MASKED (nh->path_hdr, key.base.path_hdr, - mask.base.path_hdr); - flow_key->nsh.base.path_hdr = nh->path_hdr; -switch (nh->mdtype) { -case NSH_M_TYPE1 : -for (i =0 ; i <NSH_MD1_CONTEXT_SIZE ; i++) { - nh->md1.context[i] = -OVS_MASKED (nh->md1.context[i], key.context[i], - mask.context[i]); - } -memcpy (flow_key->nsh.context, nh->md1.context, -sizeof (nh->md1.context)); -break ; -case NSH_M_TYPE2 : -memset (flow_key->nsh.context,0 , -sizeof (flow_key->nsh.context)); -break ; -default : -return -EINVAL ; - } -skb_postpush_rcsum (skb, nh, length); -return 0 ; -} -/* Must follow skb_ensure_writable() since that can move the skb data. */ static void set_tp_port (struct sk_buff *skb,__be16 *port,__be16 new_port,__sum16 *check)
@@ -1130,10 +1067,6 @@ static int execute_masked_set_action(struct sk_buff *skb, get_mask(a, struct ovs_key_ethernet *));break ; -case OVS_KEY_ATTR_NSH : - err =set_nsh (skb, flow_key, a); -break ; -case OVS_KEY_ATTR_IPV4 : err =set_ipv4 (skb, flow_key,nla_data (a), get_mask(a, struct ovs_key_ipv4 *));
@@ -1170,6 +1103,7 @@ static int execute_masked_set_action(struct sk_buff *skb,case OVS_KEY_ATTR_CT_LABELS :case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4 :case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6 : +case OVS_KEY_ATTR_NSH : err = -EINVAL ;break ; }
net/openvswitch/flow_netlink.c +8 -56
105 lines not on this page · raw message
net/openvswitch/flow_netlink.h +0 -2
@@ -65,8 +65,6 @@ int ovs_nla_put_actions(const struct nlattr *attr,void ovs_nla_free_flow_actions (struct sw_flow_actions *);void ovs_nla_free_flow_actions_rcu (struct sw_flow_actions *); -int nsh_key_from_nlattr (const struct nlattr *attr,struct ovs_key_nsh *nsh, -struct ovs_key_nsh *nsh_mask);int nsh_hdr_from_nlattr (const struct nlattr *attr,struct nshhdr *nh,size_t size);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 458/568 nvme-multipath: fix lockdep WARN due to partition scan work
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shin'ichiro Kawasaki <[email protected]>
[ Upstream commit 6d87cd5335784351280f82c47cc8a657271929c3 ]
Blktests test cases nvme/014, 057 and 058 fail occasionally due to a lockdep WARN. As reported in the Closes tag URL, the WARN indicates that a deadlock can happen due to the dependency among disk->open_mutex, kblockd workqueue completion and partition_scan_work completion.
To avoid the lockdep WARN and the potential deadlock, cut the dependency by running the partition_scan_work not by kblockd workqueue but by nvme_wq.
--- drivers/nvme/host/multipath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/nvme/host/multipath.c +1 -1
@@ -577,7 +577,7 @@ static void nvme_mpath_set_live(struct nvme_ns *ns)return ; }nvme_add_ns_head_cdev (head); -kblockd_schedule_work (&head->partition_scan_work); +queue_work (nvme_wq, &head->partition_scan_work); }mutex_lock (&head->lock);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 459/568 s390/ctcm: Fix double-kfree
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksei Nikiforov <[email protected]>
[ Upstream commit da02a1824884d6c84c5e5b5ac373b0c9e3288ec2 ]
The function 'mpc_rcvd_sweep_req(mpcginfo)' is called conditionally from function 'ctcmpc_unpack_skb'. It frees passed mpcginfo. After that a call to function 'kfree' in function 'ctcmpc_unpack_skb' frees it again.
Remove 'kfree' call in function 'mpc_rcvd_sweep_req(mpcginfo)'.
Bug detected by the clang static analyzer.
--- drivers/s390/net/ctcm_mpc.c | 1 - 1 file changed, 1 deletion(-)
drivers/s390/net/ctcm_mpc.c +0 -1
@@ -698,7 +698,6 @@ static void mpc_rcvd_sweep_req(struct mpcg_info *mpcginfo) grp->sweep_req_pend_num--;ctcmpc_send_sweep_resp (ch); -kfree (mpcginfo);return ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 460/568 platform/x86/intel/speed_select_if: Convert PCIBIOS_* return codes to errnos
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit d8bb447efc5622577994287dc77c684fa8840b30 ]
isst_if_probe() uses pci_read_config_dword() that returns PCIBIOS_* codes. The return code is returned from the probe function as is but probe functions should return normal errnos. A proper implementation can be found in drivers/leds/leds-ss4200.c.
Convert PCIBIOS_* return codes using pcibios_err_to_errno() into normal errno before returning.
--- drivers/platform/x86/intel/speed_select_if/isst_if_mmio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/platform/x86/intel/speed_select_if/isst_if_mmio.c +2 -2
@@ -106,11 +106,11 @@ static int isst_if_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ret =pci_read_config_dword (pdev,0xD0 , &mmio_base);if (ret) -return ret; +return pcibios_err_to_errno (ret); ret =pci_read_config_dword (pdev,0xFC , &pcu_base);if (ret) -return ret; +return pcibios_err_to_errno (ret); pcu_base &=GENMASK (10 ,0 ); base_addr = (u64 )mmio_base <<23 | (u64 ) pcu_base <<12 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 461/568 kernel.h: Move ARRAY_SIZE() to a separate header
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alejandro Colomar <[email protected]>
[ Upstream commit 3cd39bc3b11b8d34b7d7c961a35fdfd18b0ebf75 ]
Touching files so used for the kernel,
forces 'make' to recompile most of the kernel.
Having those definitions in more granular files
helps avoid recompiling so much of the kernel.
Stable-dep-of: 896f1a2493b5 ("net: qlogic/qede: fix potential out-of-bounds read in qede_tpa_cont() and qede_tpa_end()")
--- include/linux/array_size.h | 13 +++++++++++++ include/linux/kernel.h | 7 +------ include/linux/string.h | 1 + 3 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 include/linux/array_size.h
include/linux/array_size.h new file +13 -0
@@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_ARRAY_SIZE_H +#define _LINUX_ARRAY_SIZE_H + +#include <linux/compiler.h> + +/** +* ARRAY_SIZE - get the number of elements in array @arr +* @arr: array to be sized +*/ +#define ARRAY_SIZE (arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) + +#endif /* _LINUX_ARRAY_SIZE_H */
include/linux/kernel.h +1 -6
@@ -13,6 +13,7 @@#include <linux/stdarg.h> #include <linux/align.h> +#include <linux/array_size.h> #include <linux/limits.h> #include <linux/linkage.h> #include <linux/stddef.h>
@@ -48,12 +49,6 @@#define READ 0#define WRITE 1 -/** -* ARRAY_SIZE - get the number of elements in array @arr -* @arr: array to be sized -*/ -#define ARRAY_SIZE (arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) -#define PTR_IF (cond, ptr) ((cond) ? (ptr) : NULL)#define u64_to_user_ptr (x) ( \
include/linux/string.h +1 -0
@@ -2,6 +2,7 @@#ifndef _LINUX_STRING_H_#define _LINUX_STRING_H_ +#include <linux/array_size.h> #include <linux/compiler.h> /* for inline */ #include <linux/types.h> /* for size_t */ #include <linux/stddef.h> /* for NULL */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 462/568 net: qlogic/qede: fix potential out-of-bounds read in qede_tpa_cont() and qede_tpa_end()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Zhigulin <[email protected]>
[ Upstream commit 896f1a2493b59beb2b5ccdf990503dbb16cb2256 ]
The loops in 'qede_tpa_cont()' and 'qede_tpa_end()', iterate over 'cqe->len_list[]' using only a zero-length terminator as the stopping condition. If the terminator was missing or malformed, the loop could run past the end of the fixed-size array.
Add an explicit bound check using ARRAY_SIZE() in both loops to prevent a potential out-of-bounds access.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/net/ethernet/qlogic/qede/qede_fp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/ethernet/qlogic/qede/qede_fp.c +3 -2
@@ -4,6 +4,7 @@* Copyright (c) 2019-2020 Marvell International Ltd. */ +#include <linux/array_size.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h>
@@ -960,7 +961,7 @@ static inline void qede_tpa_cont(struct qede_dev *edev, {int i; -for (i =0 ; cqe->len_list[i]; i++) +for (i =0 ; cqe->len_list[i] && i <ARRAY_SIZE (cqe->len_list); i++)qede_fill_frag_skb (edev, rxq, cqe->tpa_agg_index,le16_to_cpu (cqe->len_list[i]));
@@ -985,7 +986,7 @@ static int qede_tpa_end(struct qede_dev *edev,dma_unmap_page (rxq->dev, tpa_info->buffer.mapping,PAGE_SIZE , rxq->data_direction); -for (i =0 ; cqe->len_list[i]; i++) +for (i =0 ; cqe->len_list[i] && i <ARRAY_SIZE (cqe->len_list); i++)qede_fill_frag_skb (edev, rxq, cqe->tpa_agg_index,le16_to_cpu (cqe->len_list[i]));if (unlikely (i >1 ))
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 463/568 vsock: Ignore signal/timeout on connect() if already established
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Luczaj <[email protected]>
[ Upstream commit 002541ef650b742a198e4be363881439bb9d86b4 ]
During connect(), acting on a signal/timeout by disconnecting an already established socket leads to several issues:
1. connect() invoking vsock_transport_cancel_pkt() -> virtio_transport_purge_skbs() may race with sendmsg() invoking virtio_transport_get_credit(). This results in a permanently elevated vvs->bytes_unsent. Which, in turn, confuses the SOCK_LINGER handling.
2. connect() resetting a connected socket's state may race with socket being placed in a sockmap. A disconnected socket remaining in a sockmap breaks sockmap's assumptions. And gives rise to WARNs.
3. connect() transitioning SS_CONNECTED -> SS_UNCONNECTED allows for a transport change/drop after TCP_ESTABLISHED. Which poses a problem for any simultaneous sendmsg() or connect() and may result in a use-after-free/null-ptr-deref.
Do not disconnect socket on signal/timeout. Keep the logic for unconnected
sockets: they don't linger, can't be placed in a sockmap, are rejected by sendmsg().
[1]: https://lore.kernel.org/netdev/[email protected]/
[2]: https://lore.kernel.org/netdev/[email protected]/
[3]: https://lore.kernel.org/netdev/[email protected]/
--- net/vmw_vsock/af_vsock.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-)
net/vmw_vsock/af_vsock.c +31 -9
@@ -1502,18 +1502,40 @@ static int vsock_connect(struct socket *sock, struct sockaddr *addr, timeout =schedule_timeout (timeout);lock_sock (sk); -if (signal_pending (current)) { - err =sock_intr_errno (timeout); - sk->sk_state = sk->sk_state ==TCP_ESTABLISHED ?TCP_CLOSING :TCP_CLOSE ; - sock->state =SS_UNCONNECTED ; -vsock_transport_cancel_pkt (vsk); -vsock_remove_connected (vsk); - goto out_wait; - }else if ((sk->sk_state !=TCP_ESTABLISHED ) && (timeout ==0 )) { - err = -ETIMEDOUT ; +/* Connection established. Whatever happens to socket once we +* release it, that's not connect()'s concern. No need to go +* into signal and timeout handling. Call it a day. +* +* Note that allowing to "reset" an already established socket +* here is racy and insecure. +*/ +if (sk->sk_state ==TCP_ESTABLISHED ) +break ; + +/* If connection was _not_ established and a signal/timeout came +* to be, we want the socket's state reset. User space may want +* to retry. +* +* sk_state != TCP_ESTABLISHED implies that socket is not on +* vsock_connected_table. We keep the binding and the transport +* assigned. +*/ +if (signal_pending (current) || timeout ==0 ) { + err = timeout ==0 ? -ETIMEDOUT :sock_intr_errno (timeout); + +/* Listener might have already responded with +* VIRTIO_VSOCK_OP_RESPONSE. Its handling expects our +* sk_state == TCP_SYN_SENT, which hereby we break. +* In such case VIRTIO_VSOCK_OP_RST will follow. +*/ sk->sk_state =TCP_CLOSE ; sock->state =SS_UNCONNECTED ; + +/* Try to cancel VIRTIO_VSOCK_OP_REQUEST skb sent out by +* transport->connect(). +*/ vsock_transport_cancel_pkt (vsk); + goto out_wait; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 464/568 bcma: dont register devices disabled in OF
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafał Miłecki <[email protected]>
[ Upstream commit a2a69add80411dd295c9088c1bcf925b1f4e53d7 ]
Some bus devices can be marked as disabled for specific SoCs or models. Those should not be registered to avoid probing them.
--- drivers/bcma/main.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/bcma/main.c +6 -0
@@ -293,6 +293,8 @@ static int bcma_register_devices(struct bcma_bus *bus)int err;list_for_each_entry (core, &bus->cores, list) { +struct device_node *np; +/* We support that core ourselves */ switch (core->id.id) {case BCMA_CORE_4706_CHIPCOMMON :
@@ -310,6 +312,10 @@ static int bcma_register_devices(struct bcma_bus *bus)if (bcma_is_core_needed_early (core->id.id))continue ; + np = core->dev.of_node; +if (np && !of_device_is_available (np)) +continue ; +/* Only first GMAC core on BCM4706 is connected and working */ if (core->id.id ==BCMA_CORE_4706_MAC_GBIT && core->core_unit >0 )
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 465/568 cifs: fix typo in enable_gcm_256 module parameter
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve French <[email protected]>
[ Upstream commit f765fdfcd8b5bce92c6aa1a517ff549529ddf590 ]
Fix typo in description of enable_gcm_256 module parameter
--- fs/smb/client/cifsfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/smb/client/cifsfs.c +1 -1
@@ -128,7 +128,7 @@ module_param(enable_oplocks, bool, 0644);MODULE_PARM_DESC (enable_oplocks,"Enable or disable oplocks. Default: y/Y/1" );module_param (enable_gcm_256, bool,0644 ); -MODULE_PARM_DESC (enable_gcm_256,"Enable requesting strongest (256 bit) GCM encryption. Default: y/Y/0" ); +MODULE_PARM_DESC (enable_gcm_256,"Enable requesting strongest (256 bit) GCM encryption. Default: y/Y/1" );module_param (require_gcm_256, bool,0644 );MODULE_PARM_DESC (require_gcm_256,"Require strongest (256 bit) GCM encryption. Default: n/N/0" );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 466/568 scsi: core: Fix a regression triggered by scsi_host_busy()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
[ Upstream commit a0b7780602b1b196f47e527fec82166a7e67c4d0 ]
Commit 995412e23bb2 ("blk-mq: Replace tags->lock with SRCU for tag iterators") introduced the following regression:
Call trace: __srcu_read_lock+0x30/0x80 (P) blk_mq_tagset_busy_iter+0x44/0x300 scsi_host_busy+0x38/0x70 ufshcd_print_host_state+0x34/0x1bc ufshcd_link_startup.constprop.0+0xe4/0x2e0 ufshcd_init+0x944/0xf80 ufshcd_pltfrm_init+0x504/0x820 ufs_rockchip_probe+0x2c/0x88 platform_probe+0x5c/0xa4 really_probe+0xc0/0x38c __driver_probe_device+0x7c/0x150 driver_probe_device+0x40/0x120 __driver_attach+0xc8/0x1e0 bus_for_each_dev+0x7c/0xdc driver_attach+0x24/0x30 bus_add_driver+0x110/0x230 driver_register+0x68/0x130 __platform_driver_register+0x20/0x2c ufs_rockchip_pltform_init+0x1c/0x28 do_one_initcall+0x60/0x1e0 kernel_init_freeable+0x248/0x2c4 kernel_init+0x20/0x140 ret_from_fork+0x10/0x20
Fix this regression by making scsi_host_busy() check whether the SCSI host tag set has already been initialized. tag_set->ops is set by scsi_mq_setup_tags() just before blk_mq_alloc_tag_set() is called. This fix is based on the assumption that scsi_host_busy() and scsi_mq_setup_tags() calls are serialized. This is the case in the UFS driver.
--- drivers/scsi/hosts.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/scsi/hosts.c +3 -2
@@ -600,8 +600,9 @@ int scsi_host_busy(struct Scsi_Host *shost) {int cnt =0 ; -blk_mq_tagset_busy_iter (&shost->tag_set, - scsi_host_check_in_flight, &cnt); +if (shost->tag_set.ops) +blk_mq_tagset_busy_iter (&shost->tag_set, + scsi_host_check_in_flight, &cnt);return cnt; }EXPORT_SYMBOL (scsi_host_busy);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 467/568 selftests: net: use BASH for bareudp testing
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Po-Hsu Lin <[email protected]>
[ Upstream commit 9311e9540a8b406d9f028aa87fb072a3819d4c82 ]
In bareudp.sh, this script uses /bin/sh and it will load another lib.sh BASH script at the very beginning.
But on some operating systems like Ubuntu, /bin/sh is actually pointed to DASH, thus it will try to run BASH commands with DASH and consequently leads to syntax issues:
# ./bareudp.sh: 4: ./lib.sh: Bad substitution
# ./bareudp.sh: 5: ./lib.sh: source: not found
# ./bareudp.sh: 24: ./lib.sh: Syntax error: "(" unexpected
Fix this by explicitly using BASH for bareudp.sh. This fixes test execution failures on systems where /bin/sh is not BASH.
--- tools/testing/selftests/net/bareudp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/net/bareudp.sh +1 -1
@@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # SPDX-License-Identifier: GPL-2.0 # Test various bareudp tunnel configurations.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 468/568 net: tls: Cancel RX async resync request on rcd_delta overflow
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shahar Shitrit <[email protected]>
[ Upstream commit c15d5c62ab313c19121f10e25d4fec852bd1c40c ]
When a netdev issues a RX async resync request for a TLS connection, the TLS module handles it by logging record headers and attempting to match them to the tcp_sn provided by the device. If a match is found, the TLS module approves the tcp_sn for resynchronization.
While waiting for a device response, the TLS module also increments rcd_delta each time a new TLS record is received, tracking the distance from the original resync request.
However, if the device response is delayed or fails (e.g due to unstable connection and device getting out of tracking, hardware errors, resource exhaustion etc.), the TLS module keeps logging and incrementing, which can lead to a WARN() when rcd_delta exceeds the threshold.
To address this, introduce tls_offload_rx_resync_async_request_cancel() to explicitly cancel resync requests when a device response failure is detected. Call this helper also as a final safeguard when rcd_delta crosses its threshold, as reaching this point implies that earlier cancellation did not occur.
--- include/net/tls.h | 6 ++++++ net/tls/tls_device.c | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-)
include/net/tls.h +6 -0
@@ -475,6 +475,12 @@ tls_offload_rx_resync_async_request_end(struct sock *sk, __be32 seq) ((u64)ntohl(seq) << 32) | RESYNC_REQ); } +static inline void +tls_offload_rx_resync_async_request_cancel (struct tls_offload_resync_async *resync_async) +{ +atomic64_set (&resync_async->req,0 ); +} +static inline void tls_offload_rx_resync_set_type (struct sock *sk,enum tls_offload_sync_type type) {
net/tls/tls_device.c +3 -1
@@ -739,8 +739,10 @@ tls_device_rx_resync_async(struct tls_offload_resync_async *resync_async,/* shouldn't get to wraparound: * too long in async stage, something bad happened */ -if (WARN_ON_ONCE (resync_async->rcd_delta ==USHRT_MAX )) +if (WARN_ON_ONCE (resync_async->rcd_delta ==USHRT_MAX )) { +tls_offload_rx_resync_async_request_cancel (resync_async);return false; + }/* asynchronous stage: log all headers seq such that * req_seq <= seq <= end_seq, and wait for real resync request
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 469/568 kconfig/mconf: Initialize the default locale at startup
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Horký <[email protected]>
[ Upstream commit 3927c4a1084c48ef97f11281a0a43ecb2cb4d6f1 ]
Fix bug where make menuconfig doesn't initialize the default locale, which causes ncurses menu borders to be displayed incorrectly (lqqqqk) in UTF-8 terminals that don't support VT100 ACS by default, such as PuTTY.
--- scripts/kconfig/mconf.c | 3 +++ 1 file changed, 3 insertions(+)
scripts/kconfig/mconf.c +3 -0
@@ -12,6 +12,7 @@#include <errno.h> #include <fcntl.h> #include <limits.h> +#include <locale.h> #include <stdarg.h> #include <stdlib.h> #include <string.h>
@@ -1005,6 +1006,8 @@ int main(int ac, char **av)signal (SIGINT , sig_handler); +setlocale (LC_ALL ,"" ); +if (ac >1 &&strcmp (av[1 ],"-s" ) ==0 ) { silent =1 ;/* Silence conf_read() until the real callback is set up */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 470/568 kconfig/nconf: Initialize the default locale at startup
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Horký <[email protected]>
[ Upstream commit 43c2931a95e6b295bfe9e3b90dbe0f7596933e91 ]
Fix bug where make nconfig doesn't initialize the default locale, which causes ncurses menu borders to be displayed incorrectly (lqqqqk) in UTF-8 terminals that don't support VT100 ACS by default, such as PuTTY.
--- scripts/kconfig/nconf.c | 3 +++ 1 file changed, 3 insertions(+)
scripts/kconfig/nconf.c +3 -0
@@ -7,6 +7,7 @@#ifndef _GNU_SOURCE#define _GNU_SOURCE#endif +#include <locale.h> #include <string.h> #include <strings.h> #include <stdlib.h>
@@ -1476,6 +1477,8 @@ int main(int ac, char **av)int lines, columns;char *mode; +setlocale (LC_ALL ,"" ); +if (ac >1 &&strcmp (av[1 ],"-s" ) ==0 ) {/* Silence conf_read() until the real callback is set up */ conf_set_message_callback (NULL );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 471/568 mm/secretmem: fix use-after-free race in fault handler
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lance Yang <[email protected]>
[ Upstream commit 6f86d0534fddfbd08687fa0f01479d4226bc3c3d ]
When a page fault occurs in a secret memory file created with memfd_secret(2), the kernel will allocate a new page for it, mark the underlying page as not-present in the direct map, and add it to the file mapping.
If two tasks cause a fault in the same page concurrently, both could end up allocating a page and removing the page from the direct map, but only one would succeed in adding the page to the file mapping. The task that failed undoes the effects of its attempt by (a) freeing the page again and (b) putting the page back into the direct map. However, by doing these two operations in this order, the page becomes available to the allocator again before it is placed back in the direct mapping.
If another task attempts to allocate the page between (a) and (b), and the kernel tries to access it via the direct map, it would result in a supervisor not-present page fault.
Fix the ordering to restore the direct map before the page is freed.
--- mm/secretmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/secretmem.c +1 -1
@@ -82,13 +82,13 @@ static vm_fault_t secretmem_fault(struct vm_fault *vmf)__SetPageUptodate (page); err =add_to_page_cache_lru (page, mapping, offset, gfp);if (unlikely (err)) { -put_page (page);/* * If a split of large page was required, it * already happened when we marked the page invalid * which guarantees that this call won't fail */ set_direct_map_default_noflush (page); +put_page (page);if (err == -EEXIST ) goto retry;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 472/568 mm/mm_init: fix hash table order logging in alloc_large_system_hash()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Isaac J. Manjarres <[email protected]>
[ Upstream commit 0d6c356dd6547adac2b06b461528e3573f52d953 ]
When emitting the order of the allocation for a hash table, alloc_large_system_hash() unconditionally subtracts PAGE_SHIFT from log base 2 of the allocation size. This is not correct if the allocation size is smaller than a page, and yields a negative value for the order as seen below:
TCP established hash table entries: 32 (order: -4, 256 bytes, linear) TCP bind hash table entries: 32 (order: -2, 1024 bytes, linear)
Use get_order() to compute the order when emitting the hash table information to correctly handle cases where the allocation size is smaller than a page:
TCP established hash table entries: 32 (order: 0, 256 bytes, linear) TCP bind hash table entries: 32 (order: 0, 1024 bytes, linear)
--- mm/page_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/page_alloc.c +1 -1
@@ -9225,7 +9225,7 @@ void *__init alloc_large_system_hash(const char *tablename,panic ("Failed to allocate %s hash table\n" , tablename);pr_info ("%s hash table entries: %ld (order: %d, %lu bytes, %s)\n" , - tablename,1UL << log2qty,ilog2 (size) -PAGE_SHIFT , size, + tablename,1UL << log2qty,get_order (size), size, virt ? (huge ?"vmalloc hugepage" :"vmalloc" ) :"linear" );if (_hash_shift)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 473/568 ALSA: usb-audio: fix uac2 clock source at terminal parser
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: René Rebe <[email protected]>
[ Upstream commit d26e9f669cc0a6a85cf17180c09a6686db9f4002 ]
Since 8b3a087f7f65 ("ALSA: usb-audio: Unify virtual type units type to UAC3 values") usb-audio is using UAC3_CLOCK_SOURCE instead of bDescriptorSubtype, later refactored with e0ccdef9265 ("ALSA: usb-audio:
Clean up check_input_term()") into parse_term_uac2_clock_source().
This breaks the clock source selection for at least my 1397:0003 BEHRINGER International GmbH FCA610 Pro.
Fix by using UAC2_CLOCK_SOURCE in parse_term_uac2_clock_source().
--- sound/usb/mixer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/mixer.c +1 -1
@@ -930,7 +930,7 @@ static int parse_term_uac2_clock_source(struct mixer_build *state, {struct uac_clock_source_descriptor *d = p1; - term->type =UAC3_CLOCK_SOURCE <<16 ;/* virtual type */ + term->type =UAC2_CLOCK_SOURCE <<16 ;/* virtual type */ term->id = id; term->name = d->iClockSource;return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 474/568 net: ethernet: ti: netcp: Standardize knav_dma_open_channel to return NULL on error
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nishanth Menon <[email protected]>
[ Upstream commit 90a88306eb874fe4bbdd860e6c9787f5bbc588b5 ]
Make knav_dma_open_channel consistently return NULL on error instead of ERR_PTR. Currently the header include/linux/soc/ti/knav_dma.h returns NULL when the driver is disabled, but the driver implementation does not even return NULL or ERR_PTR on failure, causing inconsistency in the users. This results in a crash in netcp_free_navigator_resources as followed (trimmed):
Unhandled fault: alignment exception (0x221) at 0xfffffff2 [fffffff2] *pgd=80000800207003, *pmd=82ffda003, *pte=00000000
Internal error: : 221 [#1] SMP ARM Modules linked in: CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.17.0-rc7 #1 NONE Hardware name: Keystone PC is at knav_dma_close_channel+0x30/0x19c LR is at netcp_free_navigator_resources+0x2c/0x28c
[... TRIM...]
Call trace: knav_dma_close_channel from netcp_free_navigator_resources+0x2c/0x28c netcp_free_navigator_resources from netcp_ndo_open+0x430/0x46c netcp_ndo_open from __dev_open+0x114/0x29c __dev_open from __dev_change_flags+0x190/0x208 __dev_change_flags from netif_change_flags+0x1c/0x58 netif_change_flags from dev_change_flags+0x38/0xa0 dev_change_flags from ip_auto_config+0x2c4/0x11f0 ip_auto_config from do_one_initcall+0x58/0x200 do_one_initcall from kernel_init_freeable+0x1cc/0x238 kernel_init_freeable from kernel_init+0x1c/0x12c kernel_init from ret_from_fork+0x14/0x38
[... TRIM...]
Standardize the error handling by making the function return NULL on all error conditions. The API is used in just the netcp_core.c so the impact is limited.
Note, this change, in effect reverts commit 5b6cb43b4d62 ("net:
ethernet: ti: netcp_core: return error while dma channel open issue"), but provides a less error prone implementation.
--- drivers/net/ethernet/ti/netcp_core.c | 10 +++++----- drivers/soc/ti/knav_dma.c | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-)
drivers/net/ethernet/ti/netcp_core.c +5 -5
@@ -1338,10 +1338,10 @@ int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe) tx_pipe->dma_channel =knav_dma_open_channel (dev, tx_pipe->dma_chan_name, &config); -if (IS_ERR (tx_pipe->dma_channel)) { +if (!tx_pipe->dma_channel) {dev_err (dev,"failed opening tx chan(%s)\n" , tx_pipe->dma_chan_name); - ret =PTR_ERR (tx_pipe->dma_channel); + ret = -EINVAL ; goto err; }
@@ -1359,7 +1359,7 @@ int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe)return 0 ; err: -if (!IS_ERR_OR_NULL (tx_pipe->dma_channel)) +if (tx_pipe->dma_channel)knav_dma_close_channel (tx_pipe->dma_channel); tx_pipe->dma_channel =NULL ;return ret;
@@ -1678,10 +1678,10 @@ static int netcp_setup_navigator_resources(struct net_device *ndev) netcp->rx_channel =knav_dma_open_channel (netcp->netcp_device->device, netcp->dma_chan_name, &config); -if (IS_ERR (netcp->rx_channel)) { +if (!netcp->rx_channel) {dev_err (netcp->ndev_dev,"failed opening rx chan(%s\n" , netcp->dma_chan_name); - ret =PTR_ERR (netcp->rx_channel); + ret = -EINVAL ; goto fail; }
drivers/soc/ti/knav_dma.c +7 -7
@@ -402,7 +402,7 @@ static int of_channel_match_helper(struct device_node *np, const char *name,* @name: slave channel name * @config: dma configuration parameters * -* Returns pointer to appropriate DMA channel on success or error. +* Return: Pointer to appropriate DMA channel on success or NULL on error. */ void *knav_dma_open_channel (struct device *dev,const char *name,struct knav_dma_cfg *config)
@@ -414,13 +414,13 @@ void *knav_dma_open_channel(struct device *dev, const char *name,if (!kdev) {pr_err ("keystone-navigator-dma driver not registered\n" ); -return (void *)-EINVAL ; +return NULL ; } chan_num =of_channel_match_helper (dev->of_node, name, &instance);if (chan_num <0 ) {dev_err (kdev->dev,"No DMA instance with name %s\n" , name); -return (void *)-EINVAL ; +return NULL ; } dev_dbg(kdev->dev, "initializing %s channel %d from DMA %s\n",
@@ -431,7 +431,7 @@ void *knav_dma_open_channel(struct device *dev, const char *name,if (config->direction !=DMA_MEM_TO_DEV && config->direction !=DMA_DEV_TO_MEM ) {dev_err (kdev->dev,"bad direction\n" ); -return (void *)-EINVAL ; +return NULL ; }/* Look for correct dma instance */
@@ -443,7 +443,7 @@ void *knav_dma_open_channel(struct device *dev, const char *name, }if (!dma) {dev_err (kdev->dev,"No DMA instance with name %s\n" , instance); -return (void *)-EINVAL ; +return NULL ; }/* Look for correct dma channel from dma instance */
@@ -463,14 +463,14 @@ void *knav_dma_open_channel(struct device *dev, const char *name,if (!chan) {dev_err (kdev->dev,"channel %d is not in DMA %s\n" , chan_num, instance); -return (void *)-EINVAL ; +return NULL ; }if (atomic_read (&chan->ref_count) >=1 ) {if (!check_config (chan, config)) {dev_err (kdev->dev,"channel %d config miss-match\n" , chan_num); -return (void *)-EINVAL ; +return NULL ; } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 475/568 tracing/tools: Fix incorrcet short option in usage text for --threads
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Chujun <[email protected]>
[ Upstream commit 53afec2c8fb2a562222948cb1c2aac48598578c9 ]
The help message incorrectly listed '-t' as the short option for --threads, but the actual getopt_long configuration uses '-e'. This mismatch can confuse users and lead to incorrect command-line usage. This patch updates the usage string to correctly show:
"-e, --threads NRTHR"
to match the implementation.
Note: checkpatch.pl reports a false-positive spelling warning on 'Run', which is intentional.
--- tools/tracing/latency/latency-collector.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/tracing/latency/latency-collector.c +1 -1
@@ -1725,7 +1725,7 @@ static void show_usage(void)"-n, --notrace\t\tIf latency is detected, do not print out the content of\n" "\t\t\tthe trace file to standard output\n\n" -"-t, --threads NRTHR\tRun NRTHR threads for printing. Default is %d.\n\n" +"-e, --threads NRTHR\tRun NRTHR threads for printing. Default is %d.\n\n" "-r, --random\t\tArbitrarily sleep a certain amount of time, default\n" "\t\t\t%ld ms, before reading the trace file. The\n"
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 476/568 uio_hv_generic: Set event for all channels on the device
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li <[email protected]>
commit d062463edf1770427dc2d637df4088df4835aa47 upstream.
Hyper-V may offer a non latency sensitive device with subchannels without monitor bit enabled. The decision is entirely on the Hyper-V host not configurable within guest.
When a device has subchannels, also signal events for the subchannel if its monitor bit is disabled.
This patch also removes the memory barrier when monitor bit is enabled as it is not necessary. The memory barrier is only needed between setting up interrupt mask and calling vmbus_set_event() when monitor bit is disabled.
--- drivers/uio/uio_hv_generic.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
drivers/uio/uio_hv_generic.c +17 -4
@@ -80,9 +80,15 @@ hv_uio_irqcontrol(struct uio_info *info, {struct hv_uio_private_data *pdata = info->priv;struct hv_device *dev = pdata->device; +struct vmbus_channel *primary, *sc; - dev->channel->inbound.ring_buffer->interrupt_mask = !irq_state; -virt_mb (); + primary = dev->channel; + primary->inbound.ring_buffer->interrupt_mask = !irq_state; + +mutex_lock (&vmbus_connection.channel_mutex); +list_for_each_entry (sc, &primary->sc_list, sc_list) + sc->inbound.ring_buffer->interrupt_mask = !irq_state; +mutex_unlock (&vmbus_connection.channel_mutex);return 0 ; }
@@ -93,11 +99,18 @@ hv_uio_irqcontrol(struct uio_info *info,static void hv_uio_channel_cb (void *context) {struct vmbus_channel *chan = context; -struct hv_device *hv_dev = chan->device_obj; -struct hv_uio_private_data *pdata =hv_get_drvdata (hv_dev); +struct hv_device *hv_dev; +struct hv_uio_private_data *pdata;virt_mb (); +/* +* The callback may come from a subchannel, in which case look +* for the hv device in the primary channel +*/ + hv_dev = chan->primary_channel ? + chan->primary_channel->device_obj : chan->device_obj; + pdata =hv_get_drvdata (hv_dev);uio_event_notify (&pdata->info); }
Greg Kroah-Hartman
maintainerPATCH 477/568 mm/truncate: unmap large folio on split failure
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kiryl Shutsemau <[email protected]>
commit fa04f5b60fda62c98a53a60de3a1e763f11feb41 upstream.
Accesses within VMA, but beyond i_size rounded up to PAGE_SIZE are supposed to generate SIGBUS.
This behavior might not be respected on truncation.
During truncation, the kernel splits a large folio in order to reclaim memory. As a side effect, it unmaps the folio and destroys PMD mappings of the folio. The folio will be refaulted as PTEs and SIGBUS semantics are preserved.
However, if the split fails, PMD mappings are preserved and the user will not receive SIGBUS on any accesses within the PMD.
Unmap the folio on split failure. It will lead to refault as PTEs and preserve SIGBUS semantics.
Make an exception for shmem/tmpfs that for long time intentionally mapped with PMDs across i_size.
--- mm/truncate.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
mm/truncate.c +26 -1
@@ -196,6 +196,31 @@ int truncate_inode_folio(struct address_return 0 ; } +static int try_folio_split_or_unmap (struct folio *folio) +{ +enum ttu_flags ttu_flags = +TTU_SYNC | +TTU_SPLIT_HUGE_PMD | +TTU_IGNORE_MLOCK ; +int ret; + + ret =split_folio (folio); + +/* +* If the split fails, unmap the folio, so it will be refaulted +* with PTEs to respect SIGBUS semantics. +* +* Make an exception for shmem/tmpfs that for long time +* intentionally mapped with PMDs across i_size. +*/ +if (ret && !shmem_mapping (folio->mapping)) { +try_to_unmap (folio, ttu_flags); +WARN_ON (folio_mapped (folio)); + } + +return ret; +} +/* * Handle partial folios. The folio may be entirely within the * range if a split has raced with us. If not, we zero the part of the
@@ -239,7 +264,7 @@ bool truncate_inode_partial_folio(structfolio_invalidate (folio, offset, length);if (!folio_test_large (folio))return true; -if (split_folio (folio) ==0 ) +if (try_folio_split_or_unmap (folio) ==0 )return true;if (folio_test_dirty (folio))return false;
Greg Kroah-Hartman
maintainerPATCH 478/568 maple_tree: fix tracepoint string pointers
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Kaiser <[email protected]>
commit 91a54090026f84ceffaa12ac53c99b9f162946f6 upstream.
maple_tree tracepoints contain pointers to function names. Such a pointer is saved when a tracepoint logs an event. There's no guarantee that it's still valid when the event is parsed later and the pointer is dereferenced.
The kernel warns about these unsafe pointers.
event 'ma_read' has unsafe pointer field 'fn' WARNING: kernel/trace/trace.c:3779 at ignore_event+0x1da/0x1e4
Mark the function names as tracepoint_string() to fix the events.
One case that doesn't work without my patch would be trace-cmd record to save the binary ringbuffer and trace-cmd report to parse it in userspace. The address of __func__ can't be dereferenced from userspace but tracepoint_string will add an entry to /sys/kernel/tracing/printk_formats
--- lib/maple_tree.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-)
lib/maple_tree.c +16 -14
@@ -62,6 +62,8 @@#define CREATE_TRACE_POINTS #include <trace/events/maple_tree.h> +#define TP_FCT tracepoint_string(__func__) +#define MA_ROOT_PARENT 1/*
@@ -3165,7 +3167,7 @@ static inline int mas_rebalance(struct mMA_STATE (l_mas, mas->tree, mas->index, mas->last);MA_STATE (r_mas, mas->tree, mas->index, mas->last); -trace_ma_op (__func__, mas); +trace_ma_op (TP_FCT , mas);/* * Rebalancing occurs if a node is insufficient. Data is rebalanced
@@ -3542,7 +3544,7 @@ static int mas_split(struct ma_state *maMA_STATE (prev_r_mas, mas->tree, mas->index, mas->last);MA_TOPIARY (mat, mas->tree); -trace_ma_op (__func__, mas); +trace_ma_op (TP_FCT , mas); mas->depth =mas_mt_height (mas);/* Allocation failures will happen early. */ mas_node_count (mas,1 + mas->depth *2 );
@@ -3786,7 +3788,7 @@ static bool mas_is_span_wr(struct ma_wr_return false; } -trace_ma_write (__func__, wr_mas->mas, piv, entry); +trace_ma_write (TP_FCT , wr_mas->mas, piv, entry);return true; }
@@ -4035,7 +4037,7 @@ static inline int mas_wr_spanning_store(* of data may happen. */ mas = wr_mas->mas; -trace_ma_op (__func__, mas); +trace_ma_op (TP_FCT , mas);if (unlikely (!mas->index && mas->last ==ULONG_MAX ))return mas_new_root (mas, wr_mas->entry);
@@ -4221,7 +4223,7 @@ done: }else {memcpy (wr_mas->node, newnode,sizeof (struct maple_node )); } -trace_ma_write (__func__, mas,0 , wr_mas->entry); +trace_ma_write (TP_FCT , mas,0 , wr_mas->entry);mas_update_gap (mas);return true; }
@@ -4276,7 +4278,7 @@ static inline bool mas_wr_slot_store(str mas->offset++;/* Keep mas accurate. */ done: -trace_ma_write (__func__, mas,0 , wr_mas->entry); +trace_ma_write (TP_FCT , mas,0 , wr_mas->entry);mas_update_gap (mas);return true; }
@@ -4377,7 +4379,7 @@ static void mas_wr_bnode(struct ma_wr_st {struct maple_big_node b_node; -trace_ma_write (__func__, wr_mas->mas,0 , wr_mas->entry); +trace_ma_write (TP_FCT , wr_mas->mas,0 , wr_mas->entry);memset (&b_node,0 ,sizeof (struct maple_big_node ));mas_store_b_node (wr_mas, &b_node, wr_mas->offset_end);mas_commit_b_node (wr_mas, &b_node, wr_mas->node_end);
@@ -5722,7 +5724,7 @@ void *mas_store(struct ma_state *mas, vo {MA_WR_STATE (wr_mas, mas, entry); -trace_ma_write (__func__, mas,0 , entry); +trace_ma_write (TP_FCT , mas,0 , entry);#ifdef CONFIG_DEBUG_MAPLE_TREE if (mas->index > mas->last)pr_err ("Error %lu > %lu %p\n" , mas->index, mas->last, entry);
@@ -5760,7 +5762,7 @@ int mas_store_gfp(struct ma_state *mas,MA_WR_STATE (wr_mas, mas, entry);mas_wr_store_setup (&wr_mas); -trace_ma_write (__func__, mas,0 , entry); +trace_ma_write (TP_FCT , mas,0 , entry); retry:mas_wr_store_entry (&wr_mas);if (unlikely (mas_nomem (mas, gfp)))
@@ -5784,7 +5786,7 @@ void mas_store_prealloc(struct ma_stateMA_WR_STATE (wr_mas, mas, entry);mas_wr_store_setup (&wr_mas); -trace_ma_write (__func__, mas,0 , entry); +trace_ma_write (TP_FCT , mas,0 , entry);mas_wr_store_entry (&wr_mas);BUG_ON (mas_is_err (mas));mas_destroy (mas);
@@ -6249,7 +6251,7 @@ void *mtree_load(struct maple_tree *mt,MA_STATE (mas, mt, index, index);void *entry; -trace_ma_read (__func__, &mas); +trace_ma_read (TP_FCT , &mas);rcu_read_lock (); retry: entry =mas_start (&mas);
@@ -6292,7 +6294,7 @@ int mtree_store_range(struct maple_treeMA_STATE (mas, mt, index, last);MA_WR_STATE (wr_mas, &mas, entry); -trace_ma_write (__func__, &mas,0 , entry); +trace_ma_write (TP_FCT , &mas,0 , entry);if (WARN_ON_ONCE (xa_is_advanced (entry)))return -EINVAL ;
@@ -6467,7 +6469,7 @@ void *mtree_erase(struct maple_tree *mt,void *entry =NULL ;MA_STATE (mas, mt, index, index); -trace_ma_op (__func__, &mas); +trace_ma_op (TP_FCT , &mas);mtree_lock (mt); entry =mas_erase (&mas);
@@ -6527,7 +6529,7 @@ void *mt_find(struct maple_tree *mt, unsunsigned long copy = *index;#endif -trace_ma_read (__func__, &mas); +trace_ma_read (TP_FCT , &mas);if ((*index) > max)return NULL ;
Greg Kroah-Hartman
maintainerPATCH 479/568 mptcp: decouple mptcp fastclose from tcp close
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
[ Upstream commit fff0c87996672816a84c3386797a5e69751c5888 ]
With the current fastclose implementation, the mptcp_do_fastclose() helper is in charge of two distinct actions: send the fastclose reset and cleanup the subflows.
Formally decouple the two steps, ensuring that mptcp explicitly closes all the subflows after the mentioned helper.
This will make the upcoming fix simpler, and allows dropping the 2nd argument from mptcp_destroy_common(). The Fixes tag is then the same as in the next commit to help with the backports.
--- net/mptcp/protocol.c | 13 +++++++++---- net/mptcp/protocol.h | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-)
net/mptcp/protocol.c +9 -4
@@ -2826,8 +2826,12 @@ static void mptcp_worker(struct work_str__mptcp_close_subflow (sk);if (mptcp_close_tout_expired (sk)) { +struct mptcp_subflow_context *subflow, *tmp; +inet_sk_state_store (sk,TCP_CLOSE );mptcp_do_fastclose (sk); +mptcp_for_each_subflow_safe (msk, subflow, tmp) +__mptcp_close_ssk (sk, subflow->tcp_sock, subflow,0 );mptcp_close_wake_up (sk); }
@@ -3233,7 +3237,8 @@ static int mptcp_disconnect(struct sock/* msk->subflow is still intact, the following will not free the first * subflow */ -mptcp_destroy_common (msk,MPTCP_CF_FASTCLOSE ); +mptcp_do_fastclose (sk); +mptcp_destroy_common (msk); msk->last_snd =NULL ;/* The first subflow is already in TCP_CLOSE status, the following
@@ -3456,7 +3461,7 @@ out:return newsk; } -void mptcp_destroy_common (struct mptcp_sock *msk,unsigned int flags) +void mptcp_destroy_common (struct mptcp_sock *msk) {struct mptcp_subflow_context *subflow, *tmp;struct sock *sk = (struct sock *)msk;
@@ -3465,7 +3470,7 @@ void mptcp_destroy_common(struct mptcp_s/* join list will be eventually flushed (with rst) at sock lock release time */ mptcp_for_each_subflow_safe (msk, subflow, tmp) -__mptcp_close_ssk (sk,mptcp_subflow_tcp_sock (subflow), subflow, flags); +__mptcp_close_ssk (sk,mptcp_subflow_tcp_sock (subflow), subflow,0 );/* move to sk_receive_queue, sk_stream_kill_queues will purge it */ mptcp_data_lock (sk);
@@ -3492,7 +3497,7 @@ static void mptcp_destroy(struct sock *s/* allow the following to close even the initial subflow */ msk->free_first =1 ; -mptcp_destroy_common (msk,0 ); +mptcp_destroy_common (msk);sk_sockets_allocated_dec (sk); }
net/mptcp/protocol.h +1 -1
@@ -762,7 +762,7 @@ static inline void mptcp_write_space(str } } -void mptcp_destroy_common (struct mptcp_sock *msk,unsigned int flags); +void mptcp_destroy_common (struct mptcp_sock *msk);#define MPTCP_TOKEN_MAX_RETRIES 4
Greg Kroah-Hartman
maintainerPATCH 480/568 mptcp: fix a race in mptcp_pm_del_add_timer()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 426358d9be7ce3518966422f87b96f1bad27295f ]
mptcp_pm_del_add_timer() can call sk_stop_timer_sync(sk, &entry->add_timer) while another might have free entry already, as reported by syzbot.
Add RCU protection to fix this issue.
Also change confusing add_timer variable with stop_timer boolean.
syzbot report:
BUG: KASAN: slab-use-after-free in __timer_delete_sync+0x372/0x3f0 kernel/time/timer.c:1616
Read of size 4 at addr ffff8880311e4150 by task kworker/1:1/44
CPU: 1 UID: 0 PID: 44 Comm: kworker/1:1 Not tainted syzkaller #0 PREEMPT_{RT,(full)}
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/02/2025
Workqueue: events mptcp_worker
Call Trace:
<TASK>
dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0xca/0x240 mm/kasan/report.c:482
kasan_report+0x118/0x150 mm/kasan/report.c:595
__timer_delete_sync+0x372/0x3f0 kernel/time/timer.c:1616
sk_stop_timer_sync+0x1b/0x90 net/core/sock.c:3631
mptcp_pm_del_add_timer+0x283/0x310 net/mptcp/pm.c:362
mptcp_incoming_options+0x1357/0x1f60 net/mptcp/options.c:1174
tcp_data_queue+0xca/0x6450 net/ipv4/tcp_input.c:5361
tcp_rcv_established+0x1335/0x2670 net/ipv4/tcp_input.c:6441
tcp_v4_do_rcv+0x98b/0xbf0 net/ipv4/tcp_ipv4.c:1931
tcp_v4_rcv+0x252a/0x2dc0 net/ipv4/tcp_ipv4.c:2374
ip_protocol_deliver_rcu+0x221/0x440 net/ipv4/ip_input.c:205
ip_local_deliver_finish+0x3bb/0x6f0 net/ipv4/ip_input.c:239
NF_HOOK+0x30c/0x3a0 include/linux/netfilter.h:318
NF_HOOK+0x30c/0x3a0 include/linux/netfilter.h:318
__netif_receive_skb_one_core net/core/dev.c:6079 [inline]
__netif_receive_skb+0x143/0x380 net/core/dev.c:6192
process_backlog+0x31e/0x900 net/core/dev.c:6544
__napi_poll+0xb6/0x540 net/core/dev.c:7594
napi_poll net/core/dev.c:7657 [inline]
net_rx_action+0x5f7/0xda0 net/core/dev.c:7784
handle_softirqs+0x22f/0x710 kernel/softirq.c:622
__do_softirq kernel/softirq.c:656 [inline]
__local_bh_enable_ip+0x1a0/0x2e0 kernel/softirq.c:302
mptcp_pm_send_ack net/mptcp/pm.c:210 [inline]
mptcp_pm_addr_send_ack+0x41f/0x500 net/mptcp/pm.c:-1
mptcp_pm_worker+0x174/0x320 net/mptcp/pm.c:1002
mptcp_worker+0xd5/0x1170 net/mptcp/protocol.c:2762
process_one_work kernel/workqueue.c:3263 [inline]
process_scheduled_works+0xae1/0x17b0 kernel/workqueue.c:3346
worker_thread+0x8a0/0xda0 kernel/workqueue.c:3427
kthread+0x711/0x8a0 kernel/kthread.c:463
ret_from_fork+0x4bc/0x870 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>
Allocated by task 44:
kasan_save_stack mm/kasan/common.c:56 [inline]
kasan_save_track+0x3e/0x80 mm/kasan/common.c:77
poison_kmalloc_redzone mm/kasan/common.c:400 [inline]
__kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:417
kasan_kmalloc include/linux/kasan.h:262 [inline]
__kmalloc_cache_noprof+0x1ef/0x6c0 mm/slub.c:5748
kmalloc_noprof include/linux/slab.h:957 [inline]
mptcp_pm_alloc_anno_list+0x104/0x460 net/mptcp/pm.c:385
mptcp_pm_create_subflow_or_signal_addr+0xf9d/0x1360 net/mptcp/pm_kernel.c:355
mptcp_pm_nl_fully_established net/mptcp/pm_kernel.c:409 [inline]
__mptcp_pm_kernel_worker+0x417/0x1ef0 net/mptcp/pm_kernel.c:1529
mptcp_pm_worker+0x1ee/0x320 net/mptcp/pm.c:1008
mptcp_worker+0xd5/0x1170 net/mptcp/protocol.c:2762
process_one_work kernel/workqueue.c:3263 [inline]
process_scheduled_works+0xae1/0x17b0 kernel/workqueue.c:3346
worker_thread+0x8a0/0xda0 kernel/workqueue.c:3427
kthread+0x711/0x8a0 kernel/kthread.c:463
ret_from_fork+0x4bc/0x870 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
Freed by task 6630:
kasan_save_stack mm/kasan/common.c:56 [inline]
kasan_save_track+0x3e/0x80 mm/kasan/common.c:77
__kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:587
kasan_save_free_info mm/kasan/kasan.h:406 [inline]
poison_slab_object mm/kasan/common.c:252 [inline]
__kasan_slab_free+0x5c/0x80 mm/kasan/common.c:284
kasan_slab_free include/linux/kasan.h:234 [inline]
slab_free_hook mm/slub.c:2523 [inline]
slab_free mm/slub.c:6611 [inline]
kfree+0x197/0x950 mm/slub.c:6818
mptcp_remove_anno_list_by_saddr+0x2d/0x40 net/mptcp/pm.c:158
mptcp_pm_flush_addrs_and_subflows net/mptcp/pm_kernel.c:1209 [inline]
mptcp_nl_flush_addrs_list net/mptcp/pm_kernel.c:1240 [inline]
mptcp_pm_nl_flush_addrs_doit+0x593/0xbb0 net/mptcp/pm_kernel.c:1281
genl_family_rcv_msg_doit+0x215/0x300 net/netlink/genetlink.c:1115
genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline]
genl_rcv_msg+0x60e/0x790 net/netlink/genetlink.c:1210
netlink_rcv_skb+0x208/0x470 net/netlink/af_netlink.c:2552
genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219
netlink_unicast_kernel net/netlink/af_netlink.c:1320 [inline]
netlink_unicast+0x846/0xa10 net/netlink/af_netlink.c:1346
netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1896
sock_sendmsg_nosec net/socket.c:727 [inline]
__sock_sendmsg+0x21c/0x270 net/socket.c:742
____sys_sendmsg+0x508/0x820 net/socket.c:2630
___sys_sendmsg+0x21f/0x2a0 net/socket.c:2684
__sys_sendmsg net/socket.c:2716 [inline]
__do_sys_sendmsg net/socket.c:2721 [inline]
__se_sys_sendmsg net/socket.c:2719 [inline]
__x64_sys_sendmsg+0x1a1/0x260 net/socket.c:2719
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xfa/0xfa0 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f--- net/mptcp/pm_netlink.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
net/mptcp/pm_netlink.c +13 -7
@@ -28,6 +28,7 @@ struct mptcp_pm_add_entry {struct timer_list add_timer;struct mptcp_sock *sock;u8 retrans_times; +struct rcu_head rcu; };struct pm_nl_pernet {
@@ -354,22 +355,27 @@ mptcp_pm_del_add_timer(struct mptcp_sock {struct mptcp_pm_add_entry *entry;struct sock *sk = (struct sock *)msk; -struct timer_list *add_timer =NULL ; +bool stop_timer = false; + +rcu_read_lock ();spin_lock_bh (&msk->pm.lock); entry =mptcp_lookup_anno_list_by_saddr (msk, addr);if (entry && (!check_id || entry->addr.id == addr->id)) { entry->retrans_times =ADD_ADDR_RETRANS_MAX ; - add_timer = &entry->add_timer; + stop_timer = true; }if (!check_id && entry)list_del (&entry->list);spin_unlock_bh (&msk->pm.lock); -/* no lock, because sk_stop_timer_sync() is calling del_timer_sync() */ -if (add_timer) -sk_stop_timer_sync (sk, add_timer); +/* Note: entry might have been removed by another thread. +* We hold rcu_read_lock() to ensure it is not freed under us. +*/ +if (stop_timer) +sk_stop_timer_sync (sk, &entry->add_timer); +rcu_read_unlock ();return entry; }
@@ -425,7 +431,7 @@ void mptcp_pm_free_anno_list(struct mptclist_for_each_entry_safe (entry, tmp, &free_list, list) {sk_stop_timer_sync (sk, &entry->add_timer); -kfree (entry); +kfree_rcu (entry, rcu); } }
@@ -1569,7 +1575,7 @@ static bool remove_anno_list_by_saddr(st entry =mptcp_pm_del_add_timer (msk, addr, false);if (entry) { -kfree (entry); +kfree_rcu (entry, rcu);return true; }
Greg Kroah-Hartman
maintainerPATCH 481/568 mm/mempool: replace kmap_atomic() with kmap_local_page()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Fabio M. De Francesco" <[email protected]>
[ Upstream commit f2bcc99a5e901a13b754648d1dbab60f4adf9375 ]
kmap_atomic() has been deprecated in favor of kmap_local_page().
Therefore, replace kmap_atomic() with kmap_local_page().
kmap_atomic() is implemented like a kmap_local_page() which also disables page-faults and preemption (the latter only in !PREEMPT_RT kernels). The kernel virtual addresses returned by these two API are only valid in the context of the callers (i.e., they cannot be handed to other threads).
With kmap_local_page() the mappings are per thread and CPU local like in kmap_atomic(); however, they can handle page-faults and can be called from any context (including interrupts). The tasks that call kmap_local_page() can be preempted and, when they are scheduled to run again, the kernel virtual addresses are restored and are still valid.
The code blocks between the mappings and un-mappings don't rely on the above-mentioned side effects of kmap_atomic(), so that mere replacements of the old API with the new one is all that they require (i.e., there is no need to explicitly call pagefault_disable() and/or preempt_disable()).
Stable-dep-of: ec33b59542d9 ("mm/mempool: fix poisoning order>0 pages with HIGHMEM")
--- mm/mempool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
mm/mempool.c +4 -4
@@ -62,10 +62,10 @@ static void check_element(mempool_t *poo }else if (pool->free == mempool_free_pages) {/* Mempools backed by page allocator */ int order = (int )(long )pool->pool_data; -void *addr =kmap_atomic ((struct page *)element); +void *addr =kmap_local_page ((struct page *)element);__check_element (pool, addr,1UL << (PAGE_SHIFT + order)); -kunmap_atomic (addr); +kunmap_local (addr); } }
@@ -85,10 +85,10 @@ static void poison_element(mempool_t *po } else if (pool->alloc == mempool_alloc_pages) {/* Mempools backed by page allocator */ int order = (int )(long )pool->pool_data; -void *addr =kmap_atomic ((struct page *)element); +void *addr =kmap_local_page ((struct page *)element);__poison_element (addr,1UL << (PAGE_SHIFT + order)); -kunmap_atomic (addr); +kunmap_local (addr); } }#else /* CONFIG_DEBUG_SLAB || CONFIG_SLUB_DEBUG_ON */
Greg Kroah-Hartman
maintainerPATCH 482/568 mm/mempool: fix poisoning order>0 pages with HIGHMEM
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vlastimil Babka <[email protected]>
[ Upstream commit ec33b59542d96830e3c89845ff833cf7b25ef172 ]
The kernel test has reported:
BUG: unable to handle page fault for address: fffba000 #PF: supervisor write access in kernel mode #PF: error_code(0x0002) - not-present page *pde = 03171067 *pte = 00000000 Oops: Oops: 0002 [#1] CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Tainted: G T 6.18.0-rc2-00031-gec7f31b2a2d3 #1 NONE a1d066dfe789f54bc7645c7989957d2bdee593ca Tainted: [T]=RANDSTRUCT Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 EIP: memset (arch/x86/include/asm/string_32.h:168 arch/x86/lib/memcpy_32.c:17) Code: a5 8b 4d f4 83 e1 03 74 02 f3 a4 83 c4 04 5e 5f 5d 2e e9 73 41 01 00 90 90 90 3e 8d 74 26 00 55 89 e5 57 56 89 c6 89 d0 89 f7 <f3> aa 89 f0 5e 5f 5d 2e e9 53 41 01 00 cc cc cc 55 89 e5 53 57 56 EAX: 0000006b EBX: 00000015 ECX: 001fefff EDX: 0000006b ESI: fffb9000 EDI: fffba000 EBP: c611fbf0 ESP: c611fbe8 DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068 EFLAGS: 00010287 CR0: 80050033 CR2: fffba000 CR3: 0316e000 CR4: 00040690 Call Trace: poison_element (mm/mempool.c:83 mm/mempool.c:102) mempool_init_node (mm/mempool.c:142 mm/mempool.c:226) mempool_init_noprof (mm/mempool.c:250 (discriminator 1)) ? mempool_alloc_pages (mm/mempool.c:640) bio_integrity_initfn (block/bio-integrity.c:483 (discriminator 8)) ? mempool_alloc_pages (mm/mempool.c:640) do_one_initcall (init/main.c:1283)
Christoph found out this is due to the poisoning code not dealing properly with CONFIG_HIGHMEM because only the first page is mapped but then the whole potentially high-order page is accessed.
We could give up on HIGHMEM here, but it's straightforward to fix this with a loop that's mapping, poisoning or checking and unmapping individual pages.
--- mm/mempool.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-)
mm/mempool.c +26 -6
@@ -62,10 +62,20 @@ static void check_element(mempool_t *poo }else if (pool->free == mempool_free_pages) {/* Mempools backed by page allocator */ int order = (int )(long )pool->pool_data; -void *addr =kmap_local_page ((struct page *)element); -__check_element (pool, addr,1UL << (PAGE_SHIFT + order)); -kunmap_local (addr); +#ifdef CONFIG_HIGHMEM +for (int i =0 ; i < (1 << order); i++) { +struct page *page = (struct page *)element; +void *addr =kmap_local_page (page + i); + +__check_element (pool, addr,PAGE_SIZE ); +kunmap_local (addr); + } +#else +void *addr =page_address ((struct page *)element); + +__check_element (pool, addr,PAGE_SIZE << order); +#endif } }
@@ -85,10 +95,20 @@ static void poison_element(mempool_t *po } else if (pool->alloc == mempool_alloc_pages) {/* Mempools backed by page allocator */ int order = (int )(long )pool->pool_data; -void *addr =kmap_local_page ((struct page *)element); -__poison_element (addr,1UL << (PAGE_SHIFT + order)); -kunmap_local (addr); +#ifdef CONFIG_HIGHMEM +for (int i =0 ; i < (1 << order); i++) { +struct page *page = (struct page *)element; +void *addr =kmap_local_page (page + i); + +__poison_element (addr,PAGE_SIZE ); +kunmap_local (addr); + } +#else +void *addr =page_address ((struct page *)element); + +__poison_element (addr,PAGE_SIZE << order); +#endif } }#else /* CONFIG_DEBUG_SLAB || CONFIG_SLUB_DEBUG_ON */
Greg Kroah-Hartman
maintainerPATCH 483/568 dt-bindings: pinctrl: toshiba,visconti: Fix number of items in groups
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 316e361b5d2cdeb8d778983794a1c6eadcb26814 ]
The "groups" property can hold multiple entries (e.g. toshiba/tmpv7708-rm-mbrc.dts file), so allow that by dropping incorrect type (pinmux-node.yaml schema already defines that as string-array) and adding constraints for items. This fixes dtbs_check warnings like:
toshiba/tmpv7708-rm-mbrc.dtb: pinctrl@24190000 (toshiba,tmpv7708-pinctrl):
pwm-pins:groups: ['pwm0_gpio16_grp', 'pwm1_gpio17_grp', 'pwm2_gpio18_grp', 'pwm3_gpio19_grp'] is too long
--- Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml | 26 +++++----- 1 file changed, 14 insertions(+), 12 deletions(-)
Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml +14 -12
@@ -50,18 +50,20 @@ patternProperties: groups: description: Name of the pin group to use for the functions. - $ref: "/schemas/types.yaml#/definitions/string" - enum: [i2c0_grp, i2c1_grp, i2c2_grp, i2c3_grp, i2c4_grp, - i2c5_grp, i2c6_grp, i2c7_grp, i2c8_grp, - spi0_grp, spi0_cs0_grp, spi0_cs1_grp, spi0_cs2_grp, - spi1_grp, spi2_grp, spi3_grp, spi4_grp, spi5_grp, spi6_grp, - uart0_grp, uart1_grp, uart2_grp, uart3_grp, - pwm0_gpio4_grp, pwm0_gpio8_grp, pwm0_gpio12_grp, - pwm0_gpio16_grp, pwm1_gpio5_grp, pwm1_gpio9_grp, - pwm1_gpio13_grp, pwm1_gpio17_grp, pwm2_gpio6_grp, - pwm2_gpio10_grp, pwm2_gpio14_grp, pwm2_gpio18_grp, - pwm3_gpio7_grp, pwm3_gpio11_grp, pwm3_gpio15_grp, - pwm3_gpio19_grp, pcmif_out_grp, pcmif_in_grp] + items: + enum: [i2c0_grp, i2c1_grp, i2c2_grp, i2c3_grp, i2c4_grp, + i2c5_grp, i2c6_grp, i2c7_grp, i2c8_grp, + spi0_grp, spi0_cs0_grp, spi0_cs1_grp, spi0_cs2_grp, + spi1_grp, spi2_grp, spi3_grp, spi4_grp, spi5_grp, spi6_grp, + uart0_grp, uart1_grp, uart2_grp, uart3_grp, + pwm0_gpio4_grp, pwm0_gpio8_grp, pwm0_gpio12_grp, + pwm0_gpio16_grp, pwm1_gpio5_grp, pwm1_gpio9_grp, + pwm1_gpio13_grp, pwm1_gpio17_grp, pwm2_gpio6_grp, + pwm2_gpio10_grp, pwm2_gpio14_grp, pwm2_gpio18_grp, + pwm3_gpio7_grp, pwm3_gpio11_grp, pwm3_gpio15_grp, + pwm3_gpio19_grp, pcmif_out_grp, pcmif_in_grp] + minItems: 1 + maxItems: 8 drive-strength: enum: [2, 4, 6, 8, 16, 24, 32]
Greg Kroah-Hartman
maintainerPATCH 484/568 ata: libata-scsi: Fix system suspend for a security locked drive
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Cassel <[email protected]>
[ Upstream commit b11890683380a36b8488229f818d5e76e8204587 ]
Commit cf3fc037623c ("ata: libata-scsi: Fix ata_to_sense_error() status handling") fixed ata_to_sense_error() to properly generate sense key ABORTED COMMAND (without any additional sense code), instead of the previous bogus sense key ILLEGAL REQUEST with the additional sense code UNALIGNED WRITE COMMAND, for a failed command.
However, this broke suspend for Security locked drives (drives that have Security enabled, and have not been Security unlocked by boot firmware).
The reason for this is that the SCSI disk driver, for the Synchronize Cache command only, treats any sense data with sense key ILLEGAL REQUEST as a successful command (regardless of ASC / ASCQ).
After commit cf3fc037623c ("ata: libata-scsi: Fix ata_to_sense_error() status handling") the code that treats any sense data with sense key ILLEGAL REQUEST as a successful command is no longer applicable, so the command fails, which causes the system suspend to be aborted:
sd 1:0:0:0: PM: dpm_run_callback(): scsi_bus_suspend returns -5 sd 1:0:0:0: PM: failed to suspend async: error -5
PM: Some devices failed to suspend, or early wake event detected
To make suspend work once again, for a Security locked device only, return sense data LOGICAL UNIT ACCESS NOT AUTHORIZED, the actual sense data which a real SCSI device would have returned if locked. The SCSI disk driver treats this sense data as a successful command.
--- drivers/ata/libata-scsi.c | 8 ++++++++ include/linux/ata.h | 1 + 2 files changed, 9 insertions(+)
drivers/ata/libata-scsi.c +8 -0
@@ -996,6 +996,14 @@ static void ata_gen_ata_sense(struct ataata_scsi_set_sense (dev, cmd,NOT_READY ,0x04 ,0x21 );return ; } + +if (ata_id_is_locked (dev->id)) { +/* Security locked */ +/* LOGICAL UNIT ACCESS NOT AUTHORIZED */ +ata_scsi_set_sense (dev, cmd,DATA_PROTECT ,0x74 ,0x71 ); +return ; + } +/* Use ata_to_sense_error() to map status register bits * onto sense key, asc & ascq. */
include/linux/ata.h +1 -0
@@ -558,6 +558,7 @@ struct ata_bmdma_prd {#define ata_id_has_ncq (id) ((id)[ATA_ID_SATA_CAPABILITY] & (1 << 8))#define ata_id_queue_depth (id) (((id)[ATA_ID_QUEUE_DEPTH] & 0x1f) + 1)#define ata_id_removable (id) ((id)[ATA_ID_CONFIG] & (1 << 7)) +#define ata_id_is_locked (id) (((id)[ATA_ID_DLF] & 0x7) == 0x7)#define ata_id_has_atapi_AN (id) \ ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \
Greg Kroah-Hartman
maintainerPATCH 485/568 HID: amd_sfh: Stop sensor before starting
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Mario Limonciello (AMD)" <[email protected]>
[ Upstream commit 4d3a13afa8b64dc49293b3eab3e7beac11072c12 ]
Titas reports that the accelerometer sensor on their laptop only works after a warm boot or unloading/reloading the amd-sfh kernel module.
Presumably the sensor is in a bad state on cold boot and failing to start, so explicitly stop it before starting.
--- drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c +2 -0
@@ -163,6 +163,8 @@ static int amd_sfh1_1_hid_client_init(stif (rc) goto cleanup; + mp2_ops->stop (privdata, cl_data->sensor_idx[i]); +amd_sfh_wait_for_response (privdata, cl_data->sensor_idx[i],DISABLE_SENSOR );writel (0 , privdata->mmio +AMD_P2C_MSG (0 )); mp2_ops->start (privdata, info); status = amd_sfh_wait_for_response
Greg Kroah-Hartman
maintainerPATCH 486/568 selftests: mptcp: join: rm: set backup flag
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Matthieu Baerts (NGI0)" <[email protected]>
[ Upstream commit aea73bae662a0e184393d6d7d0feb18d2577b9b9 ]
Some of these 'remove' tests rarely fail because a subflow has been reset instead of cleanly removed. This can happen when one extra subflow which has never carried data is being closed (FIN) on one side, while the other is sending data for the first time.
To avoid such subflows to be used right at the end, the backup flag has been added. With that, data will be only carried on the initial subflow.
--- tools/testing/selftests/net/mptcp/mptcp_join.sh | 54 ++++++++++++------------ 1 file changed, 27 insertions(+), 27 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_join.sh +27 -27
@@ -2332,7 +2332,7 @@ remove_tests() if reset "remove single subflow"; then pm_nl_set_limits $ns1 0 1 pm_nl_set_limits $ns2 0 1 - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup run_tests $ns1 $ns2 10.0.1.1 0 0 -1 slow chk_join_nr 1 1 1 chk_rm_nr 1 1
@@ -2343,8 +2343,8 @@ remove_tests() if reset "remove multiple subflows"; then pm_nl_set_limits $ns1 0 2 pm_nl_set_limits $ns2 0 2 - pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,backup + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup run_tests $ns1 $ns2 10.0.1.1 0 0 -2 slow chk_join_nr 2 2 2 chk_rm_nr 2 2
@@ -2354,7 +2354,7 @@ remove_tests() # single address, remove if reset "remove single address"; then pm_nl_set_limits $ns1 0 1 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup pm_nl_set_limits $ns2 1 1 run_tests $ns1 $ns2 10.0.1.1 0 -1 0 slow chk_join_nr 1 1 1
@@ -2366,9 +2366,9 @@ remove_tests() # subflow and signal, remove if reset "remove subflow and signal"; then pm_nl_set_limits $ns1 0 2 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup pm_nl_set_limits $ns2 1 2 - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup run_tests $ns1 $ns2 10.0.1.1 0 -1 -1 slow chk_join_nr 2 2 2 chk_add_nr 1 1
@@ -2379,10 +2379,10 @@ remove_tests() # subflows and signal, remove if reset "remove subflows and signal"; then pm_nl_set_limits $ns1 0 3 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup pm_nl_set_limits $ns2 1 3 - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow - pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup + pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow,backup run_tests $ns1 $ns2 10.0.1.1 0 -1 -2 speed_10 chk_join_nr 3 3 3 chk_add_nr 1 1
@@ -2393,9 +2393,9 @@ remove_tests() # addresses remove if reset "remove addresses"; then pm_nl_set_limits $ns1 3 3 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal id 250 - pm_nl_add_endpoint $ns1 10.0.3.1 flags signal - pm_nl_add_endpoint $ns1 10.0.4.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup id 250 + pm_nl_add_endpoint $ns1 10.0.3.1 flags signal,backup + pm_nl_add_endpoint $ns1 10.0.4.1 flags signal,backup pm_nl_set_limits $ns2 3 3 run_tests $ns1 $ns2 10.0.1.1 0 -3 0 speed_10 chk_join_nr 3 3 3
@@ -2407,10 +2407,10 @@ remove_tests() # invalid addresses remove if reset "remove invalid addresses"; then pm_nl_set_limits $ns1 3 3 - pm_nl_add_endpoint $ns1 10.0.12.1 flags signal + pm_nl_add_endpoint $ns1 10.0.12.1 flags signal,backup # broadcast IP: no packet for this address will be received on ns1 - pm_nl_add_endpoint $ns1 224.0.0.1 flags signal - pm_nl_add_endpoint $ns1 10.0.3.1 flags signal + pm_nl_add_endpoint $ns1 224.0.0.1 flags signal,backup + pm_nl_add_endpoint $ns1 10.0.3.1 flags signal,backup pm_nl_set_limits $ns2 2 2 run_tests $ns1 $ns2 10.0.1.1 0 -3 0 speed_10 chk_join_nr 1 1 1
@@ -2422,10 +2422,10 @@ remove_tests() # subflows and signal, flush if reset "flush subflows and signal"; then pm_nl_set_limits $ns1 0 3 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup pm_nl_set_limits $ns2 1 3 - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow - pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup + pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow,backup run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow chk_join_nr 3 3 3 chk_add_nr 1 1
@@ -2437,9 +2437,9 @@ remove_tests() if reset "flush subflows"; then pm_nl_set_limits $ns1 3 3 pm_nl_set_limits $ns2 3 3 - pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow id 150 - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow - pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,backup id 150 + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup + pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow,backup run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow chk_join_nr 3 3 3
@@ -2454,9 +2454,9 @@ remove_tests() # addresses flush if reset "flush addresses"; then pm_nl_set_limits $ns1 3 3 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal id 250 - pm_nl_add_endpoint $ns1 10.0.3.1 flags signal - pm_nl_add_endpoint $ns1 10.0.4.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup id 250 + pm_nl_add_endpoint $ns1 10.0.3.1 flags signal,backup + pm_nl_add_endpoint $ns1 10.0.4.1 flags signal,backup pm_nl_set_limits $ns2 3 3 run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow chk_join_nr 3 3 3
@@ -2468,9 +2468,9 @@ remove_tests() # invalid addresses flush if reset "flush invalid addresses"; then pm_nl_set_limits $ns1 3 3 - pm_nl_add_endpoint $ns1 10.0.12.1 flags signal - pm_nl_add_endpoint $ns1 10.0.3.1 flags signal - pm_nl_add_endpoint $ns1 10.0.14.1 flags signal + pm_nl_add_endpoint $ns1 10.0.12.1 flags signal,backup + pm_nl_add_endpoint $ns1 10.0.3.1 flags signal,backup + pm_nl_add_endpoint $ns1 10.0.14.1 flags signal,backup pm_nl_set_limits $ns2 3 3 run_tests $ns1 $ns2 10.0.1.1 0 -8 0 slow chk_join_nr 1 1 1
Greg Kroah-Hartman
maintainerPATCH 487/568 selftests: mptcp: connect: fix fallback note due to OoO
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Matthieu Baerts (NGI0)" <[email protected]>
[ Upstream commit 63c643aa7b7287fdbb0167063785f89ece3f000f ]
The "fallback due to TCP OoO" was never printed because the stat_ooo_now variable was checked twice: once in the parent if-statement, and one in the child one. The second condition was then always true then, and the 'else' branch was never taken.
The idea is that when there are more ACK + MP_CAPABLE than expected, the test either fails if there was no out of order packets, or a notice is printed.
--- tools/testing/selftests/net/mptcp/mptcp_connect.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/net/mptcp/mptcp_connect.sh +1 -1
@@ -523,7 +523,7 @@ do_transfer() "${stat_synrx_now_l}" "${expect_synrx}" 1>&2 retc=1 fi - if [ ${stat_ackrx_now_l} -lt ${expect_ackrx} -a ${stat_ooo_now} -eq 0 ]; then + if [ ${stat_ackrx_now_l} -lt ${expect_ackrx} ]; then if [ ${stat_ooo_now} -eq 0 ]; then printf "[ FAIL ] lower MPC ACK rx (%d) than expected (%d)\n" \ "${stat_ackrx_now_l}" "${expect_ackrx}" 1>&2
Greg Kroah-Hartman
maintainerPATCH 488/568 pmdomain: samsung: plug potential memleak during probe
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Draszik <[email protected]>
[ Upstream commit 90c82941adf1986364e0f82c35cf59f2bf5f6a1d ]
of_genpd_add_provider_simple() could fail, in which case this code leaks the domain name, pd->pd.name.
Use devm_kstrdup_const() to plug this leak. As a side-effect, we can simplify existing error handling.
--- drivers/soc/samsung/pm_domains.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/soc/samsung/pm_domains.c +5 -6
@@ -91,13 +91,14 @@ static const struct of_device_id exynos_ { }, }; -static const char *exynos_get_domain_name (struct device_node *node) +static const char *exynos_get_domain_name (struct device *dev, +struct device_node *node) {const char *name;if (of_property_read_string (node,"label" , &name) <0 ) name =kbasename (node->full_name); -return kstrdup_const (name,GFP_KERNEL ); +return devm_kstrdup_const (dev, name,GFP_KERNEL ); }static int exynos_pd_probe (struct platform_device *pdev)
@@ -114,15 +115,13 @@ static int exynos_pd_probe(struct platfoif (!pd)return -ENOMEM ; - pd->pd.name =exynos_get_domain_name (np); + pd->pd.name =exynos_get_domain_name (dev, np);if (!pd->pd.name)return -ENOMEM ; pd->base =of_iomap (np,0 ); -if (!pd->base) { -kfree_const (pd->pd.name); +if (!pd->base)return -ENODEV ; - } pd->pd.power_off = exynos_pd_power_off; pd->pd.power_on = exynos_pd_power_on;
Greg Kroah-Hartman
maintainerPATCH 489/568 pmdomain: arm: scmi: Fix genpd leak on provider registration failure
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sudeep Holla <[email protected]>
[ Upstream commit 7458f72cc28f9eb0de811effcb5376d0ec19094a ]
If of_genpd_add_provider_onecell() fails during probe, the previously created generic power domains are not removed, leading to a memory leak and potential kernel crash later in genpd_debug_add().
Add proper error handling to unwind the initialized domains before returning from probe to ensure all resources are correctly released on failure.
Example crash trace observed without this fix:
| Unable to handle kernel paging request at virtual address fffffffffffffc70 | CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.18.0-rc1 #405 PREEMPT | Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development Platform | pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) | pc : genpd_debug_add+0x2c/0x160 | lr : genpd_debug_init+0x74/0x98 | Call trace: | genpd_debug_add+0x2c/0x160 (P) | genpd_debug_init+0x74/0x98 | do_one_initcall+0xd0/0x2d8 | do_initcall_level+0xa0/0x140 | do_initcalls+0x60/0xa8 | do_basic_setup+0x28/0x40 | kernel_init_freeable+0xe8/0x170 | kernel_init+0x2c/0x140 | ret_from_fork+0x10/0x20
--- drivers/firmware/arm_scmi/scmi_pm_domain.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/firmware/arm_scmi/scmi_pm_domain.c +11 -2
@@ -54,7 +54,7 @@ static int scmi_pd_power_off(struct genestatic int scmi_pm_domain_probe (struct scmi_device *sdev) { -int num_domains, i; +int num_domains, i, ret;struct device *dev = &sdev->dev;struct device_node *np = dev->of_node;struct scmi_pm_domain *scmi_pd;
@@ -112,9 +112,18 @@ static int scmi_pm_domain_probe(struct s scmi_pd_data->domains = domains; scmi_pd_data->num_domains = num_domains; + ret =of_genpd_add_provider_onecell (np, scmi_pd_data); +if (ret) + goto err_rm_genpds; +dev_set_drvdata (dev, scmi_pd_data); -return of_genpd_add_provider_onecell (np, scmi_pd_data); +return 0 ; +err_rm_genpds: +for (i = num_domains -1 ; i >=0 ; i--) +pm_genpd_remove (domains[i]); + +return ret; }static void scmi_pm_domain_remove (struct scmi_device *sdev)
Greg Kroah-Hartman
maintainerPATCH 490/568 pmdomain: imx: Fix reference count leak in imx_gpc_remove
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miaoqian Lin <[email protected]>
[ Upstream commit bbde14682eba21d86f5f3d6fe2d371b1f97f1e61 ]
of_get_child_by_name() returns a node pointer with refcount incremented, we should use of_node_put() on it when not needed anymore. Add the missing of_node_put() to avoid refcount leak.
--- drivers/soc/imx/gpc.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/soc/imx/gpc.c +2 -0
@@ -541,6 +541,8 @@ static int imx_gpc_remove(struct platforreturn ret; } +of_node_put (pgc_node); +return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 491/568 filemap: cap PTE range to be created to allowed zero fill in folio_map_range()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pankaj Raghav <[email protected]>
[ Upstream commit 743a2753a02e805347969f6f89f38b736850d808 ]
Usually the page cache does not extend beyond the size of the inode, therefore, no PTEs are created for folios that extend beyond the size.
But with LBS support, we might extend page cache beyond the size of the inode as we need to guarantee folios of minimum order. While doing a read, do_fault_around() can create PTEs for pages that lie beyond the EOF leading to incorrect error return when accessing a page beyond the mapped file.
Cap the PTE range to be created for the page cache up to the end of file(EOF) in filemap_map_pages() so that return error codes are consistent with POSIX[1] for LBS configurations.
generic/749 has been created to trigger this edge case. This also fixes generic/749 for tmpfs with huge=always on systems with 4k base page size.
[1](from mmap(2)) SIGBUS
Attempted access to a page of the buffer that lies beyond the end of the mapped file. For an explanation of the treatment of the bytes in the page that corresponds to the end of a mapped file that is not a multiple of the page size, see NOTES.
--- mm/filemap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
mm/filemap.c +6 -1
@@ -3460,7 +3460,7 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf,struct vm_area_struct *vma = vmf->vma;struct file *file = vma->vm_file;struct address_space *mapping = file->f_mapping; -pgoff_t last_pgoff = start_pgoff; +pgoff_t file_end, last_pgoff = start_pgoff;unsigned long addr;XA_STATE (xas, &mapping->i_pages, start_pgoff);struct folio *folio;
@@ -3480,6 +3480,11 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf, addr = vma->vm_start + ((start_pgoff - vma->vm_pgoff) <<PAGE_SHIFT ); vmf->pte =pte_offset_map_lock (vma->vm_mm, vmf->pmd, addr, &vmf->ptl); + + file_end =DIV_ROUND_UP (i_size_read (mapping->host),PAGE_SIZE ) -1 ; +if (end_pgoff > file_end) + end_pgoff = file_end; + do { again: page = folio_file_page(folio, xas.xa_index);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 492/568 mm/memory: do not populate page table entries beyond i_size
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kiryl Shutsemau <[email protected]>
[ Upstream commit 74207de2ba10c2973334906822dc94d2e859ffc5 ]
Patch series "Fix SIGBUS semantics with large folios", v3.
Accessing memory within a VMA, but beyond i_size rounded up to the next page size, is supposed to generate SIGBUS.
Darrick reported[1] an xfstests regression in v6.18-rc1. generic/749 failed due to missing SIGBUS. This was caused by my recent changes that try to fault in the whole folio where possible:
19773df031bc ("mm/fault: try to map the entire file folio in finish_fault()") 357b92761d94 ("mm/filemap: map entire large folio faultaround")
These changes did not consider i_size when setting up PTEs, leading to xfstest breakage.
However, the problem has been present in the kernel for a long time - since huge tmpfs was introduced in 2016. The kernel happily maps PMD-sized folios as PMD without checking i_size. And huge=always tmpfs allocates PMD-size folios on any writes.
I considered this corner case when I implemented a large tmpfs, and my conclusion was that no one in their right mind should rely on receiving a SIGBUS signal when accessing beyond i_size. I cannot imagine how it could be useful for the workload.
But apparently filesystem folks care a lot about preserving strict SIGBUS semantics.
Generic/749 was introduced last year with reference to POSIX, but no real workloads were mentioned. It also acknowledged the tmpfs deviation from the test case.
POSIX indeed says[3]:
References within the address range starting at pa and continuing for len bytes to whole pages following the end of an object shall result in delivery of a SIGBUS signal.
The patchset fixes the regression introduced by recent changes as well as more subtle SIGBUS breakage due to split failure on truncation.
This patch (of 2):
Accesses within VMA, but beyond i_size rounded up to PAGE_SIZE are supposed to generate SIGBUS.
Recent changes attempted to fault in full folio where possible. They did not respect i_size, which led to populating PTEs beyond i_size and breaking SIGBUS semantics.
Darrick reported generic/749 breakage because of this.
However, the problem existed before the recent changes. With huge=always tmpfs, any write to a file leads to PMD-size allocation. Following the fault-in of the folio will install PMD mapping regardless of i_size.
Fix filemap_map_pages() and finish_fault() to not install:
- PTEs beyond i_size;
- PMD mappings across i_size;
Make an exception for shmem/tmpfs that for long time intentionally mapped with PMDs across i_size.
--- mm/filemap.c | 20 +++++++++++++++----- mm/memory.c | 24 +++++++++++++++++++++++- 2 files changed, 38 insertions(+), 6 deletions(-)
mm/filemap.c +15 -5
@@ -3467,13 +3467,27 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf,struct page *page;unsigned int mmap_miss =READ_ONCE (file->f_ra.mmap_miss);vm_fault_t ret =0 ; +bool can_map_large;rcu_read_lock (); folio =first_map_page (mapping, &xas, end_pgoff);if (!folio) goto out; -if (filemap_map_pmd (vmf, &folio->page)) { + file_end =DIV_ROUND_UP (i_size_read (mapping->host),PAGE_SIZE ) -1 ; + end_pgoff =min (end_pgoff, file_end); + +/* +* Do not allow to map with PTEs beyond i_size and with PMD +* across i_size to preserve SIGBUS semantics. +* +* Make an exception for shmem/tmpfs that for long time +* intentionally mapped with PMDs across i_size. +*/ + can_map_large =shmem_mapping (mapping) || + file_end >=folio_next_index (folio); + +if (can_map_large &&filemap_map_pmd (vmf, &folio->page)) { ret =VM_FAULT_NOPAGE ; goto out; }
@@ -3481,10 +3495,6 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf, addr = vma->vm_start + ((start_pgoff - vma->vm_pgoff) <<PAGE_SHIFT ); vmf->pte =pte_offset_map_lock (vma->vm_mm, vmf->pmd, addr, &vmf->ptl); - file_end =DIV_ROUND_UP (i_size_read (mapping->host),PAGE_SIZE ) -1 ; -if (end_pgoff > file_end) - end_pgoff = file_end; - do { again: page = folio_file_page(folio, xas.xa_index);
mm/memory.c +23 -1
@@ -67,6 +67,7 @@#include <linux/gfp.h> #include <linux/migrate.h> #include <linux/string.h> +#include <linux/shmem_fs.h> #include <linux/memory-tiers.h> #include <linux/debugfs.h> #include <linux/userfaultfd_k.h>
@@ -4452,6 +4453,8 @@ static bool vmf_pte_changed(struct vm_fault *vmf)vm_fault_t finish_fault (struct vm_fault *vmf) {struct vm_area_struct *vma = vmf->vma; +bool needs_fallback = false; +struct folio *folio;struct page *page;vm_fault_t ret;
@@ -4461,6 +4464,8 @@ vm_fault_t finish_fault(struct vm_fault *vmf)else page = vmf->page; + folio =page_folio (page); +/* * check even for read faults because we might have lost our CoWed * page
@@ -4471,8 +4476,25 @@ vm_fault_t finish_fault(struct vm_fault *vmf)return ret; } +if (!needs_fallback && vma->vm_file) { +struct address_space *mapping = vma->vm_file->f_mapping; +pgoff_t file_end; + + file_end =DIV_ROUND_UP (i_size_read (mapping->host),PAGE_SIZE ); + +/* +* Do not allow to map with PTEs beyond i_size and with PMD +* across i_size to preserve SIGBUS semantics. +* +* Make an exception for shmem/tmpfs that for long time +* intentionally mapped with PMDs across i_size. +*/ + needs_fallback = !shmem_mapping (mapping) && + file_end <folio_next_index (folio); + } +if (pmd_none (*vmf->pmd)) { -if (PageTransCompound (page)) { +if (!needs_fallback &&PageTransCompound (page)) { ret =do_set_pmd (vmf, page);if (ret !=VM_FAULT_FALLBACK )return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 493/568 can: kvaser_usb: leaf: Fix potential infinite loop in command parsers
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Seungjin Bae <[email protected]>
[ Upstream commit 0c73772cd2b8cc108d5f5334de89ad648d89b9ec ]
The kvaser_usb_leaf_wait_cmd() and kvaser_usb_leaf_read_bulk_callback functions contain logic to zero-length commands. These commands are used to align data to the USB endpoint's wMaxPacketSize boundary.
The driver attempts to skip these placeholders by aligning the buffer position pos to the next packet boundary using round_up() function.
However, if zero-length command is found exactly on a packet boundary (i.e., pos is a multiple of wMaxPacketSize, including 0), round_up function will return the unchanged value of pos. This prevents pos to be increased, causing an infinite loop in the parsing logic.
This patch fixes this in the function by using pos + 1 instead. This ensures that even if pos is on a boundary, the calculation is based on pos + 1, forcing round_up() to always return the next aligned boundary.
--- drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +2 -2
@@ -608,7 +608,7 @@ static int kvaser_usb_leaf_wait_cmd(const struct kvaser_usb *dev, u8 id,* for further details. */ if (tmp->len ==0 ) { - pos =round_up (pos, + pos =round_up (pos +1 ,le16_to_cpu (dev->bulk_in->wMaxPacketSize));continue ;
@@ -1567,7 +1567,7 @@ static void kvaser_usb_leaf_read_bulk_callback(struct kvaser_usb *dev,* number of events in case of a heavy rx load on the bus. */ if (cmd->len ==0 ) { - pos =round_up (pos,le16_to_cpu + pos =round_up (pos +1 ,le16_to_cpu (dev->bulk_in->wMaxPacketSize));continue ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 494/568 can: gs_usb: gs_usb_xmit_callback(): fix handling of failed transmitted URBs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Kleine-Budde <[email protected]>
[ Upstream commit 516a0cd1c03fa266bb67dd87940a209fd4e53ce7 ]
The driver lacks the cleanup of failed transfers of URBs. This reduces the number of available URBs per error by 1. This leads to reduced performance and ultimately to a complete stop of the transmission.
If the sending of a bulk URB fails do proper cleanup:
- increase netdev stats
- mark the echo_sbk as free
- free the driver's context and do accounting
- wake the send queue
--- drivers/net/can/usb/gs_usb.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
drivers/net/can/usb/gs_usb.c +15 -2
@@ -707,8 +707,21 @@ static void gs_usb_xmit_callback(struct urb *urb)struct gs_can *dev = txc->dev;struct net_device *netdev = dev->netdev; -if (urb->status) -netdev_info (netdev,"usb xmit fail %u\n" , txc->echo_id); +if (!urb->status) +return ; + +if (urb->status != -ESHUTDOWN &&net_ratelimit ()) +netdev_info (netdev,"failed to xmit URB %u: %pe\n" , + txc->echo_id,ERR_PTR (urb->status)); + + netdev->stats.tx_dropped++; + netdev->stats.tx_errors++; + +can_free_echo_skb (netdev, txc->echo_id,NULL ); +gs_free_tx_context (txc); +atomic_dec (&dev->active_tx_urbs); + +netif_wake_queue (netdev); } static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 495/568 can: gs_usb: gs_usb_receive_bulk_callback(): check actual_length before accessing header
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Kleine-Budde <[email protected]>
[ Upstream commit 6fe9f3279f7d2518439a7962c5870c6e9ecbadcf ]
The driver expects to receive a struct gs_host_frame in gs_usb_receive_bulk_callback().
Use struct_group to describe the header of the struct gs_host_frame and check that we have at least received the header before accessing any members of it.
To resubmit the URB, do not dereference the pointer chain "dev->parent->hf_size_rx" but use "parent->hf_size_rx" instead. Since "urb->context" contains "parent", it is always defined, while "dev" is not defined if the URB it too short.
--- drivers/net/can/usb/gs_usb.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-)
drivers/net/can/usb/gs_usb.c +19 -7
@@ -252,13 +252,15 @@ struct canfd_quirk { } __packed;struct gs_host_frame { -u32 echo_id; -__le32 can_id; + struct_group(header, + u32 echo_id; +__le32 can_id; -u8 can_dlc; -u8 channel; -u8 flags; -u8 reserved; +u8 can_dlc; +u8 channel; +u8 flags; +u8 reserved; + );union { DECLARE_FLEX_ARRAY(struct classic_can, classic_can);
@@ -528,6 +530,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)int rc;struct net_device_stats *stats;struct gs_host_frame *hf = urb->transfer_buffer; +unsigned int minimum_length;struct gs_tx_context *txc;struct can_frame *cf;struct canfd_frame *cfd;
@@ -546,6 +549,15 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)return ; } + minimum_length =sizeof (hf->header); +if (urb->actual_length < minimum_length) { +dev_err_ratelimited (&parent->udev->dev, +"short read (actual_length=%u, minimum_length=%u)\n" , + urb->actual_length, minimum_length); + + goto resubmit_urb; + } +/* device reports out of range channel id */ if (hf->channel >= parent->channel_cnt) goto device_detach;
@@ -642,7 +654,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) resubmit_urb:usb_fill_bulk_urb (urb, parent->udev, parent->pipe_in, - hf, dev->parent->hf_size_rx, + hf, parent->hf_size_rx, gs_usb_receive_bulk_callback, parent); rc =usb_submit_urb (urb,GFP_ATOMIC );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 496/568 Bluetooth: SMP: Fix not generating mackey and ltk when repairing
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 545d7827b2cd5de5eb85580cebeda6b35b3ff443 ]
The change eed467b517e8 ("Bluetooth: fix passkey uninitialized when used") introduced a goto that bypasses the creation of temporary mackey and ltk which are later used by the likes of DHKey Check step.
Later ffee202a78c2 ("Bluetooth: Always request for user confirmation for Just Works (LE SC)") which means confirm_hint is always set in case JUST_WORKS so the branch checking for an existing LTK becomes pointless as confirm_hint will always be set, so this just merge both cases of malicious or legitimate devices to be confirmed before continuing with the pairing procedure.
--- net/bluetooth/smp.c | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-)
net/bluetooth/smp.c +7 -24
@@ -2130,7 +2130,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)struct smp_chan *smp = chan->data;struct hci_conn *hcon = conn->hcon;u8 *pkax, *pkbx, *na, *nb, confirm_hint; -u32 passkey; +u32 passkey =0 ;int err;bt_dev_dbg (hcon->hdev,"conn %p" , conn);
@@ -2182,24 +2182,6 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)smp_send_cmd (conn,SMP_CMD_PAIRING_RANDOM ,sizeof (smp->prnd), smp->prnd);SMP_ALLOW_CMD (smp,SMP_CMD_DHKEY_CHECK ); - -/* Only Just-Works pairing requires extra checks */ -if (smp->method !=JUST_WORKS ) - goto mackey_and_ltk; - -/* If there already exists long term key in local host, leave -* the decision to user space since the remote device could -* be legitimate or malicious. -*/ -if (hci_find_ltk (hcon->hdev, &hcon->dst, hcon->dst_type, - hcon->role)) { -/* Set passkey to 0. The value can be any number since -* it'll be ignored anyway. -*/ - passkey =0 ; - confirm_hint =1 ; - goto confirm; - } } mackey_and_ltk:
@@ -2220,11 +2202,12 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)if (err)return SMP_UNSPECIFIED ; - confirm_hint =0 ; - -confirm: -if (smp->method ==JUST_WORKS ) - confirm_hint =1 ; +/* Always require user confirmation for Just-Works pairing to prevent +* impersonation attacks, or in case of a legitimate device that is +* repairing use the confirmation as acknowledgment to proceed with the +* creation of new keys. +*/ + confirm_hint = smp->method ==JUST_WORKS ?1 :0 ; err =mgmt_user_confirm_request (hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type, passkey, confirm_hint);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 497/568 platform/x86: intel: punit_ipc: fix memory corruption
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 9b9c0adbc3f8a524d291baccc9d0c04097fb4869 ]
This passes the address of the pointer "&punit_ipcdev" when the intent was to pass the pointer itself "punit_ipcdev" (without the ampersand). This means that the:
complete(&ipcdev->cmd_complete);
in intel_punit_ioc() will write to a wrong memory address corrupting it.
--- drivers/platform/x86/intel/punit_ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/platform/x86/intel/punit_ipc.c +1 -1
@@ -283,7 +283,7 @@ static int intel_punit_ipc_probe(struct platform_device *pdev) }else { ret =devm_request_irq (&pdev->dev, irq, intel_punit_ioc,IRQF_NO_SUSPEND ,"intel_punit_ipc" , - &punit_ipcdev); + punit_ipcdev);if (ret) {dev_err (&pdev->dev,"Failed to request irq: %d\n" , irq);return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 498/568 net: aquantia: Add missing descriptor cache invalidation on ATL2
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kai-Heng Feng <[email protected]>
[ Upstream commit 7526183cfdbe352c51c285762f0e15b7c428ea06 ]
ATL2 hardware was missing descriptor cache invalidation in hw_stop(), causing SMMU translation faults during device shutdown and module removal:
[ 70.355743] arm-smmu-v3 arm-smmu-v3.5.auto: event 0x10 received: [ 70.361893] arm-smmu-v3 arm-smmu-v3.5.auto: 0x0002060000000010 [ 70.367948] arm-smmu-v3 arm-smmu-v3.5.auto: 0x0000020000000000 [ 70.374002] arm-smmu-v3 arm-smmu-v3.5.auto: 0x00000000ff9bc000 [ 70.380055] arm-smmu-v3 arm-smmu-v3.5.auto: 0x0000000000000000 [ 70.386109] arm-smmu-v3 arm-smmu-v3.5.auto: event: F_TRANSLATION client: 0001:06:00.0 sid: 0x20600 ssid: 0x0 iova: 0xff9bc000 ipa: 0x0 [ 70.398531] arm-smmu-v3 arm-smmu-v3.5.auto: unpriv data write s1 "Input address caused fault" stag: 0x0
Commit 7a1bb49461b1 ("net: aquantia: fix potential IOMMU fault after driver unbind") and commit ed4d81c4b3f2 ("net: aquantia: when cleaning hw cache it should be toggled") fixed cache invalidation for ATL B0, but ATL2 was left with only interrupt disabling. This allowed hardware to write to cached descriptors after DMA memory was unmapped, triggering SMMU faults. Once cache invalidation is applied to ATL2, the translation fault can't be observed anymore.
Add shared aq_hw_invalidate_descriptor_cache() helper and use it in both ATL B0 and ATL2 hw_stop() implementations for consistent behavior.
--- .../ethernet/aquantia/atlantic/aq_hw_utils.c | 22 +++++++++++++++++++ .../ethernet/aquantia/atlantic/aq_hw_utils.h | 1 + .../aquantia/atlantic/hw_atl/hw_atl_b0.c | 19 +--------------- .../aquantia/atlantic/hw_atl2/hw_atl2.c | 2 +- 4 files changed, 25 insertions(+), 19 deletions(-)
drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c +22 -0
@@ -15,6 +15,7 @@#include "aq_hw.h" #include "aq_nic.h" +#include "hw_atl/hw_atl_llh.h" void aq_hw_write_reg_bit (struct aq_hw_s *aq_hw,u32 addr,u32 msk,u32 shift,u32 val)
@@ -81,6 +82,27 @@ void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value)lo_hi_writeq (value, hw->mmio + reg); } +int aq_hw_invalidate_descriptor_cache (struct aq_hw_s *hw) +{ +int err; +u32 val; + +/* Invalidate Descriptor Cache to prevent writing to the cached +* descriptors and to the data pointer of those descriptors +*/ +hw_atl_rdm_rx_dma_desc_cache_init_tgl (hw); + + err =aq_hw_err_from_flags (hw); +if (err) + goto err_exit; + +readx_poll_timeout_atomic (hw_atl_rdm_rx_dma_desc_cache_init_done_get, + hw, val, val ==1 ,1000U ,10000U ); + +err_exit: +return err; +} +int aq_hw_err_from_flags (struct aq_hw_s *hw) {int err =0 ;
drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h +1 -0
@@ -35,6 +35,7 @@ u32 aq_hw_read_reg(struct aq_hw_s *hw, u32 reg);void aq_hw_write_reg (struct aq_hw_s *hw,u32 reg,u32 value);u64 aq_hw_read_reg64 (struct aq_hw_s *hw,u32 reg);void aq_hw_write_reg64 (struct aq_hw_s *hw,u32 reg,u64 value); +int aq_hw_invalidate_descriptor_cache (struct aq_hw_s *hw);int aq_hw_err_from_flags (struct aq_hw_s *hw);int aq_hw_num_tcs (struct aq_hw_s *hw);int aq_hw_q_per_tc (struct aq_hw_s *hw);
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +1 -18
@@ -1198,26 +1198,9 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self)static int hw_atl_b0_hw_stop (struct aq_hw_s *self) { -int err; -u32 val; -hw_atl_b0_hw_irq_disable (self,HW_ATL_B0_INT_MASK ); -/* Invalidate Descriptor Cache to prevent writing to the cached -* descriptors and to the data pointer of those descriptors -*/ -hw_atl_rdm_rx_dma_desc_cache_init_tgl (self); - - err =aq_hw_err_from_flags (self); - -if (err) - goto err_exit; - -readx_poll_timeout_atomic (hw_atl_rdm_rx_dma_desc_cache_init_done_get, - self, val, val ==1 ,1000U ,10000U ); - -err_exit: -return err; +return aq_hw_invalidate_descriptor_cache (self); }int hw_atl_b0_hw_ring_tx_stop (struct aq_hw_s *self,struct aq_ring_s *ring)
drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c +1 -1
@@ -759,7 +759,7 @@ static int hw_atl2_hw_stop(struct aq_hw_s *self) {hw_atl_b0_hw_irq_disable (self,HW_ATL2_INT_MASK ); -return 0 ; +return aq_hw_invalidate_descriptor_cache (self); }static struct aq_stats_s *hw_atl2_utils_get_hw_stats (struct aq_hw_s *self)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 499/568 net: lan966x: Fix the initialization of taprio
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Horatiu Vultur <[email protected]>
[ Upstream commit 9780f535f8e0f20b4632b5a173ead71aa8f095d2 ]
To initialize the taprio block in lan966x, it is required to configure the register REVISIT_DLY. The purpose of this register is to set the delay before revisit the next gate and the value of this register depends on the system clock. The problem is that the we calculated wrong the value of the system clock period in picoseconds. The actual system clock is ~165.617754MHZ and this correspond to a period of 6038 pico seconds and not 15125 as currently set.
--- drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c +4 -1
@@ -1,9 +1,12 @@// SPDX-License-Identifier: GPL-2.0+ #include <linux/ptp_classify.h> +#include <linux/units.h> #include "lan966x_main.h" +#define LAN9X66_CLOCK_RATE 165617754 +#define LAN966X_MAX_PTP_ID 512/* Represents 1ppm adjustment in 2^59 format with 6.037735849ns as reference
@@ -896,5 +899,5 @@ void lan966x_ptp_rxtstamp(struct lan966x *lan966x, struct sk_buff *skb,u32 lan966x_ptp_get_period_ps (void ) {/* This represents the system clock period in picoseconds */ -return 15125 ; +return PICO /LAN9X66_CLOCK_RATE ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 500/568 net/mlx5e: Fix validation logic in rate limiting
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danielle Costantino <[email protected]>
[ Upstream commit d2099d9f16dbfa1c5266d4230ff7860047bb0b68 ]
The rate limiting validation condition currently checks the output variable max_bw_value[i] instead of the input value maxrate->tc_maxrate[i]. This causes the validation to compare an uninitialized or stale value rather than the actual requested rate.
The condition should check the input rate to properly validate against the upper limit:
} else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) {This aligns with the pattern used in the first branch, which correctly checks maxrate->tc_maxrate[i] against upper_limit_mbps.
The current implementation can lead to unreliable validation behavior:
- For rates between 25.5 Gbps and 255 Gbps, if max_bw_value[i] is 0 from initialization, the GBPS path may be taken regardless of whether the actual rate is within bounds
- When processing multiple TCs (i > 0), max_bw_value[i] contains the value computed for the previous TC, affecting the validation logic
- The overflow check for rates exceeding 255 Gbps may not trigger consistently depending on previous array values
This patch ensures the validation correctly examines the requested rate value for proper bounds checking.
--- drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +1 -1
@@ -619,7 +619,7 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev, MLX5E_100MB); max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] :1 ; max_bw_unit[i] =MLX5_100_MBPS_UNIT ; - }else if (max_bw_value[i] <= upper_limit_gbps) { + }else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) { max_bw_value[i] =div_u64 (maxrate->tc_maxrate[i],MLX5E_1GB ); max_bw_unit[i] =MLX5_GBPS_UNIT ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 501/568 net: sxgbe: fix potential NULL dereference in sxgbe_rx()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Kodanev <[email protected]>
[ Upstream commit f5bce28f6b9125502abec4a67d68eabcd24b3b17 ]
Currently, when skb is null, the driver prints an error and then dereferences skb on the next line.
To fix this, let's add a 'break' after the error message to switch to sxgbe_rx_refill(), which is similar to the approach taken by the other drivers in this particular case, e.g. calxeda with xgmac_rx().
Found during a code review.
--- drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +3 -1
@@ -1521,8 +1521,10 @@ static int sxgbe_rx(struct sxgbe_priv_data *priv, int limit) skb = priv->rxq[qnum]->rx_skbuff[entry]; -if (unlikely (!skb)) +if (unlikely (!skb)) {netdev_err (priv->dev,"rx descriptor is not consistent\n" ); +break ; + }prefetch (skb->data -NET_IP_ALIGN ); priv->rxq[qnum]->rx_skbuff[entry] =NULL ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 502/568 drm/amdgpu: fix cyan_skillfish2 gpu info fw handling
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
[ Upstream commit 7fa666ab07ba9e08f52f357cb8e1aad753e83ac6 ]
If the board supports IP discovery, we don't need to parse the gpu info firmware.
Backport to 6.18.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +2 -0
@@ -2021,6 +2021,8 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev) chip_name ="navi12" ;break ;case CHIP_CYAN_SKILLFISH : +if (adev->mman.discovery_bin) +return 0 ; chip_name ="cyan_skillfish" ;break ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 503/568 net: dsa: sja1105: simplify static configuration reload
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Russell King (Oracle) <[email protected]>
[ Upstream commit a18891b55703a45b700618ef40edd5e9aaecc345 ]
The static configuration reload saves the port speed in the static configuration tables by first converting it from the internal respresentation to the SPEED_xxx ethtool representation, and then converts it back to restore the setting. This is because sja1105_adjust_port_config() takes the speed as SPEED_xxx.
However, this is unnecessarily complex. If we split sja1105_adjust_port_config() up, we can simply save and restore the mac[port].speed member in the static configuration tables.
Stable-dep-of: da62abaaa268 ("net: dsa: sja1105: fix SGMII linking at 10M or 100M but not passing traffic")
--- drivers/net/dsa/sja1105/sja1105_main.c | 65 ++++++++++++++------------ 1 file changed, 34 insertions(+), 31 deletions(-)
drivers/net/dsa/sja1105/sja1105_main.c +34 -31
@@ -1262,29 +1262,11 @@ static int sja1105_parse_dt(struct sja1105_private *priv)return rc; } -/* Convert link speed from SJA1105 to ethtool encoding */ -static int sja1105_port_speed_to_ethtool (struct sja1105_private *priv, -u64 speed) -{ -if (speed == priv->info->port_speed[SJA1105_SPEED_10MBPS ]) -return SPEED_10 ; -if (speed == priv->info->port_speed[SJA1105_SPEED_100MBPS ]) -return SPEED_100 ; -if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS ]) -return SPEED_1000 ; -if (speed == priv->info->port_speed[SJA1105_SPEED_2500MBPS ]) -return SPEED_2500 ; -return SPEED_UNKNOWN ; -} - -/* Set link speed in the MAC configuration for a specific port. */ -static int sja1105_adjust_port_config (struct sja1105_private *priv,int port, -int speed_mbps) +static int sja1105_set_port_speed (struct sja1105_private *priv,int port, +int speed_mbps) {struct sja1105_mac_config_entry *mac; -struct device *dev = priv->ds->dev;u64 speed; -int rc;/* On P/Q/R/S, one can read from the device via the MAC reconfiguration * tables. On E/T, MAC reconfig tables are not readable, only writable.
@@ -1318,7 +1300,7 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS ];break ;default : -dev_err (dev,"Invalid speed %iMbps\n" , speed_mbps); +dev_err (priv->ds->dev,"Invalid speed %iMbps\n" , speed_mbps);return -EINVAL ; }
@@ -1330,11 +1312,31 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,* we need to configure the PCS only (if even that). */ if (priv->phy_mode[port] ==PHY_INTERFACE_MODE_SGMII ) - mac[port].speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS ]; + speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS ];else if (priv->phy_mode[port] ==PHY_INTERFACE_MODE_2500BASEX ) - mac[port].speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS ]; -else - mac[port].speed = speed; + speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS ]; + + mac[port].speed = speed; + +return 0 ; +} + +/* Write the MAC Configuration Table entry and, if necessary, the CGU settings, +* after a link speedchange for this port. +*/ +static int sja1105_set_port_config (struct sja1105_private *priv,int port) +{ +struct sja1105_mac_config_entry *mac; +struct device *dev = priv->ds->dev; +int rc; + +/* On P/Q/R/S, one can read from the device via the MAC reconfiguration +* tables. On E/T, MAC reconfig tables are not readable, only writable. +* We have to *know* what the MAC looks like. For the sake of keeping +* the code common, we'll use the static configuration tables as a +* reasonable approximation for both E/T and P/Q/R/S. +*/ + mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG ].entries;/* Write to the dynamic reconfiguration tables */ rc = sja1105_dynamic_config_write(priv, BLK_IDX_MAC_CONFIG, port,
@@ -1384,7 +1386,8 @@ static void sja1105_mac_link_up(struct dsa_switch *ds, int port, {struct sja1105_private *priv = ds->priv; -sja1105_adjust_port_config (priv, port, speed); +if (!sja1105_set_port_speed (priv, port, speed)) +sja1105_set_port_config (priv, port);sja1105_inhibit_tx (priv,BIT (port), false); }
@@ -2291,8 +2294,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv, {struct ptp_system_timestamp ptp_sts_before;struct ptp_system_timestamp ptp_sts_after; -int speed_mbps[SJA1105_MAX_NUM_PORTS ];u16 bmcr[SJA1105_MAX_NUM_PORTS ] = {0 }; +u64 mac_speed[SJA1105_MAX_NUM_PORTS ];struct sja1105_mac_config_entry *mac;struct dsa_switch *ds = priv->ds;s64 t1, t2, t3, t4;
@@ -2305,14 +2308,13 @@ int sja1105_static_config_reload(struct sja1105_private *priv, mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG ].entries; -/* Back up the dynamic link speed changed by sja1105_adjust_port_config +/* Back up the dynamic link speed changed by sja1105_set_port_speed() * in order to temporarily restore it to SJA1105_SPEED_AUTO - which the * switch wants to see in the static config in order to allow us to * change it through the dynamic interface later. */ for (i =0 ; i < ds->num_ports; i++) { - speed_mbps[i] =sja1105_port_speed_to_ethtool (priv, - mac[i].speed); + mac_speed[i] = mac[i].speed; mac[i].speed = priv->info->port_speed[SJA1105_SPEED_AUTO ];if (priv->xpcs[i])
@@ -2375,7 +2377,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv,struct dw_xpcs *xpcs = priv->xpcs[i];unsigned int mode; - rc =sja1105_adjust_port_config (priv, i, speed_mbps[i]); + mac[i].speed = mac_speed[i]; + rc =sja1105_set_port_config (priv, i);if (rc <0 ) goto out;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 504/568 net: dsa: sja1105: fix SGMII linking at 10M or 100M but not passing traffic
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Oltean <[email protected]>
[ Upstream commit da62abaaa268357b1aa66b372ace562189a05df1 ]
When using the SGMII PCS as a fixed-link chip-to-chip connection, it is easy to miss the fact that traffic passes only at 1G, since that's what any normal such connection would use.
When using the SGMII PCS connected towards an on-board PHY or an SFP module, it is immediately noticeable that when the link resolves to a speed other than 1G, traffic from the MAC fails to pass: TX counters increase, but nothing gets decoded by the other end, and no local RX counters increase either.
Artificially lowering a fixed-link rate to speed = <100> makes us able to see the same issue as in the case of having an SGMII PHY.
Some debugging shows that the XPCS configuration is A-OK, but that the MAC Configuration Table entry for the port has the SPEED bits still set to 1000Mbps, due to a special condition in the driver. Deleting that condition, and letting the resolved link speed be programmed directly into the MAC speed field, results in a functional link at all 3 speeds.
This piece of evidence, based on testing on both generations with SGMII support (SJA1105S and SJA1110A) directly contradicts the statement from the blamed commit that "the MAC is fixed at 1 Gbps and we need to configure the PCS only (if even that)". Worse, that statement is not backed by any documentation, and no one from NXP knows what it might refer to.
I am unable to recall sufficient context regarding my testing from March 2020 to understand what led me to draw such a braindead and factually incorrect conclusion. Yet, there is nothing of value regarding forcing the MAC speed, either for SGMII or 2500Base-X (introduced at a later stage), so remove all such logic.
--- drivers/net/dsa/sja1105/sja1105_main.c | 7 ------- 1 file changed, 7 deletions(-)
drivers/net/dsa/sja1105/sja1105_main.c +0 -7
@@ -1308,14 +1308,7 @@ static int sja1105_set_port_speed(struct sja1105_private *priv, int port,* table, since this will be used for the clocking setup, and we no * longer need to store it in the static config (already told hardware * we want auto during upload phase). -* Actually for the SGMII port, the MAC is fixed at 1 Gbps and -* we need to configure the PCS only (if even that). */ -if (priv->phy_mode[port] ==PHY_INTERFACE_MODE_SGMII ) - speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS ]; -else if (priv->phy_mode[port] ==PHY_INTERFACE_MODE_2500BASEX ) - speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS ]; - mac[port].speed = speed;return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 505/568 net: atlantic: fix fragment overflow handling in RX path
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiefeng Zhang <[email protected]>
[ Upstream commit 5ffcb7b890f61541201461580bb6622ace405aec ]
The atlantic driver can receive packets with more than MAX_SKB_FRAGS (17) fragments when handling large multi-descriptor packets. This causes an out-of-bounds write in skb_add_rx_frag_netmem() leading to kernel panic.
The issue occurs because the driver doesn't check the total number of fragments before calling skb_add_rx_frag(). When a packet requires more than MAX_SKB_FRAGS fragments, the fragment index exceeds the array bounds.
Fix by assuming there will be an extra frag if buff->len > AQ_CFG_RX_HDR_SIZE, then all fragments are accounted for. And reusing the existing check to prevent the overflow earlier in the code path.
This crash occurred in production with an Aquantia AQC113 10G NIC.
Stack trace from production environment:
``` RIP: 0010:skb_add_rx_frag_netmem+0x29/0xd0 Code: 90 f3 0f 1e fa 0f 1f 44 00 00 48 89 f8 41 89 ca 48 89 d7 48 63 ce 8b 90 c0 00 00 00 48 c1 e1 04 48 01 ca 48 03 90 c8 00 00 00 <48> 89 7a 30 44 89 52 3c 44 89 42 38 40 f6 c7 01 75 74 48 89 fa 83 RSP: 0018:ffffa9bec02a8d50 EFLAGS: 00010287 RAX: ffff925b22e80a00 RBX: ffff925ad38d2700 RCX: fffffffe0a0c8000 RDX: ffff9258ea95bac0 RSI: ffff925ae0a0c800 RDI: 0000000000037a40 RBP: 0000000000000024 R08: 0000000000000000 R09: 0000000000000021 R10: 0000000000000848 R11: 0000000000000000 R12: ffffa9bec02a8e24 R13: ffff925ad8615570 R14: 0000000000000000 R15: ffff925b22e80a00 FS: 0000000000000000(0000) GS:ffff925e47880000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffff9258ea95baf0 CR3: 0000000166022004 CR4: 0000000000f72ef0 PKRU: 55555554 Call Trace: <IRQ> aq_ring_rx_clean+0x175/0xe60 [atlantic] ? aq_ring_rx_clean+0x14d/0xe60 [atlantic] ? aq_ring_tx_clean+0xdf/0x190 [atlantic] ? kmem_cache_free+0x348/0x450 ? aq_vec_poll+0x81/0x1d0 [atlantic] ? __napi_poll+0x28/0x1c0 ? net_rx_action+0x337/0x420 ```
Changes in v4:
- Add Fixes: tag to satisfy patch validation requirements.
Changes in v3:
- Fix by assuming there will be an extra frag if buff->len > AQ_CFG_RX_HDR_SIZE, then all fragments are accounted for.
--- drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/ethernet/aquantia/atlantic/aq_ring.c +5 -0
@@ -547,6 +547,11 @@ static int __aq_ring_rx_clean(struct aq_ring_s *self, struct napi_struct *napi,if (!buff->is_eop) {unsigned int frag_cnt =0U ; + +/* There will be an extra fragment */ +if (buff->len >AQ_CFG_RX_HDR_SIZE ) + frag_cnt++; + buff_ = buff; do { bool is_rsc_completed = true;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 506/568 mailbox: mailbox-test: Fix debugfs_create_dir error checking
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit 3acf1028f5003731977f750a7070f3321a9cb740 ]
The debugfs_create_dir() function returns ERR_PTR() on error, not NULL. The current null-check fails to catch errors.
Use IS_ERR() to correctly check for errors.
--- drivers/mailbox/mailbox-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mailbox/mailbox-test.c +1 -1
@@ -267,7 +267,7 @@ static int mbox_test_add_debugfs(struct platform_device *pdev,return 0 ; tdev->root_debugfs_dir =debugfs_create_dir (dev_name (&pdev->dev),NULL ); -if (!tdev->root_debugfs_dir) { +if (IS_ERR (tdev->root_debugfs_dir)) {dev_err (&pdev->dev,"Failed to create Mailbox debugfs\n" );return -EINVAL ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 507/568 mailbox: Allow direct registration to a channel
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Elliot Berman <[email protected]>
[ Upstream commit 85a953806557dbf25d16e8c132b5b9b100d16496 ]
Support virtual mailbox controllers and clients which are not platform devices or come from the devicetree by allowing them to match client to channel via some other mechanism.
Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register")
--- drivers/mailbox/mailbox.c | 96 ++++++++++++++++++++++++---------- include/linux/mailbox_client.h | 1 + 2 files changed, 69 insertions(+), 28 deletions(-)
drivers/mailbox/mailbox.c +68 -28
@@ -317,6 +317,71 @@ int mbox_flush(struct mbox_chan *chan, unsigned long timeout) }EXPORT_SYMBOL_GPL (mbox_flush); +static int __mbox_bind_client (struct mbox_chan *chan,struct mbox_client *cl) +{ +struct device *dev = cl->dev; +unsigned long flags; +int ret; + +if (chan->cl || !try_module_get (chan->mbox->dev->driver->owner)) { +dev_dbg (dev,"%s: mailbox not free\n" , __func__); +return -EBUSY ; + } + +spin_lock_irqsave (&chan->lock, flags); + chan->msg_free =0 ; + chan->msg_count =0 ; + chan->active_req =NULL ; + chan->cl = cl; +init_completion (&chan->tx_complete); + +if (chan->txdone_method ==TXDONE_BY_POLL && cl->knows_txdone) + chan->txdone_method =TXDONE_BY_ACK ; + +spin_unlock_irqrestore (&chan->lock, flags); + +if (chan->mbox->ops->startup) { + ret = chan->mbox->ops->startup (chan); + +if (ret) { +dev_err (dev,"Unable to startup the chan (%d)\n" , ret); +mbox_free_channel (chan); +return ret; + } + } + +return 0 ; +} + +/** +* mbox_bind_client - Request a mailbox channel. +* @chan: The mailbox channel to bind the client to. +* @cl: Identity of the client requesting the channel. +* +* The Client specifies its requirements and capabilities while asking for +* a mailbox channel. It can't be called from atomic context. +* The channel is exclusively allocated and can't be used by another +* client before the owner calls mbox_free_channel. +* After assignment, any packet received on this channel will be +* handed over to the client via the 'rx_callback'. +* The framework holds reference to the client, so the mbox_client +* structure shouldn't be modified until the mbox_free_channel returns. +* +* Return: 0 if the channel was assigned to the client successfully. +* <0 for request failure. +*/ +int mbox_bind_client (struct mbox_chan *chan,struct mbox_client *cl) +{ +int ret; + +mutex_lock (&con_mutex); + ret =__mbox_bind_client (chan, cl); +mutex_unlock (&con_mutex); + +return ret; +} +EXPORT_SYMBOL_GPL (mbox_bind_client); +/** * mbox_request_channel - Request a mailbox channel. * @cl: Identity of the client requesting the channel.
@@ -340,7 +405,6 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)struct mbox_controller *mbox;struct of_phandle_args spec;struct mbox_chan *chan; -unsigned long flags;int ret;if (!dev || !dev->of_node) {
@@ -373,33 +437,9 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)return chan; } -if (chan->cl || !try_module_get (mbox->dev->driver->owner)) { -dev_dbg (dev,"%s: mailbox not free\n" , __func__); -mutex_unlock (&con_mutex); -return ERR_PTR (-EBUSY ); - } - -spin_lock_irqsave (&chan->lock, flags); - chan->msg_free =0 ; - chan->msg_count =0 ; - chan->active_req =NULL ; - chan->cl = cl; -init_completion (&chan->tx_complete); - -if (chan->txdone_method ==TXDONE_BY_POLL && cl->knows_txdone) - chan->txdone_method =TXDONE_BY_ACK ; - -spin_unlock_irqrestore (&chan->lock, flags); - -if (chan->mbox->ops->startup) { - ret = chan->mbox->ops->startup (chan); - -if (ret) { -dev_err (dev,"Unable to startup the chan (%d)\n" , ret); -mbox_free_channel (chan); - chan =ERR_PTR (ret); - } - } + ret =__mbox_bind_client (chan, cl); +if (ret) + chan =ERR_PTR (ret);mutex_unlock (&con_mutex);return chan;
include/linux/mailbox_client.h +1 -0
@@ -37,6 +37,7 @@ struct mbox_client {void (*tx_done)(struct mbox_client *cl,void *mssg,int r); }; +int mbox_bind_client (struct mbox_chan *chan,struct mbox_client *cl);struct mbox_chan *mbox_request_channel_byname (struct mbox_client *cl,const char *name);struct mbox_chan *mbox_request_channel (struct mbox_client *cl,int index);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 508/568 mailbox: pcc: Use mbox_bind_client
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Elliot Berman <[email protected]>
[ Upstream commit 76d4adacd52e78bea2e393081f2a5766261d1e3a ]
Use generic mbox_bind_client() to bind omap mailbox channel to a client.
mbox_bind_client is identical to the replaced lines, except that it:
- Does the operation under con_mutex which prevents possible races in removal path
- Sets TXDONE_BY_ACK if pcc uses TXDONE_BY_POLL and the client knows when tx is done. TXDONE_BY_ACK is already set if there's no interrupt, so this is not applicable.
- Calls chan->mbox->ops->startup. This is usecase for requesting irq:
move the devm_request_irq into the startup callback and unregister it in the shutdown path.
Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register")
--- drivers/mailbox/pcc.c | 84 +++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 39 deletions(-)
drivers/mailbox/pcc.c +45 -39
@@ -282,8 +282,7 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id) {struct pcc_chan_info *pchan;struct mbox_chan *chan; -struct device *dev; -unsigned long flags; +int rc;if (subspace_id <0 || subspace_id >= pcc_chan_count)return ERR_PTR (-ENOENT );
@@ -294,32 +293,10 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)pr_err ("Channel not found for idx: %d\n" , subspace_id);return ERR_PTR (-EBUSY ); } - dev = chan->mbox->dev; -spin_lock_irqsave (&chan->lock, flags); - chan->msg_free =0 ; - chan->msg_count =0 ; - chan->active_req =NULL ; - chan->cl = cl; -init_completion (&chan->tx_complete); - -if (chan->txdone_method ==TXDONE_BY_POLL && cl->knows_txdone) - chan->txdone_method =TXDONE_BY_ACK ; - -spin_unlock_irqrestore (&chan->lock, flags); - -if (pchan->plat_irq >0 ) { -int rc; - - rc =devm_request_irq (dev, pchan->plat_irq, pcc_mbox_irq,0 , -MBOX_IRQ_NAME , chan); -if (unlikely (rc)) { -dev_err (dev,"failed to register PCC interrupt %d\n" , - pchan->plat_irq); -pcc_mbox_free_channel (&pchan->chan); -return ERR_PTR (rc); - } - } + rc =mbox_bind_client (chan, cl); +if (rc) +return ERR_PTR (rc);return &pchan->chan; }
@@ -333,23 +310,12 @@ EXPORT_SYMBOL_GPL(pcc_mbox_request_channel);*/ void pcc_mbox_free_channel (struct pcc_mbox_chan *pchan) { -struct pcc_chan_info *pchan_info =to_pcc_chan_info (pchan);struct mbox_chan *chan = pchan->mchan; -unsigned long flags;if (!chan || !chan->cl)return ; -if (pchan_info->plat_irq >0 ) -devm_free_irq (chan->mbox->dev, pchan_info->plat_irq, chan); - -spin_lock_irqsave (&chan->lock, flags); - chan->cl =NULL ; - chan->active_req =NULL ; -if (chan->txdone_method ==TXDONE_BY_ACK ) - chan->txdone_method =TXDONE_BY_POLL ; - -spin_unlock_irqrestore (&chan->lock, flags); +mbox_free_channel (chan); }EXPORT_SYMBOL_GPL (pcc_mbox_free_channel);
@@ -377,8 +343,48 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)return pcc_chan_reg_read_modify_write (&pchan->db); } +/** +* pcc_startup - Called from Mailbox Controller code. Used here +* to request the interrupt. +* @chan: Pointer to Mailbox channel to startup. +* +* Return: Err if something failed else 0 for success. +*/ +static int pcc_startup (struct mbox_chan *chan) +{ +struct pcc_chan_info *pchan = chan->con_priv; +int rc; + +if (pchan->plat_irq >0 ) { + rc =devm_request_irq (chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq,0 , +MBOX_IRQ_NAME , chan); +if (unlikely (rc)) { +dev_err (chan->mbox->dev,"failed to register PCC interrupt %d\n" , + pchan->plat_irq); +return rc; + } + } + +return 0 ; +} + +/** +* pcc_shutdown - Called from Mailbox Controller code. Used here +* to free the interrupt. +* @chan: Pointer to Mailbox channel to shutdown. +*/ +static void pcc_shutdown (struct mbox_chan *chan) +{ +struct pcc_chan_info *pchan = chan->con_priv; + +if (pchan->plat_irq >0 ) +devm_free_irq (chan->mbox->dev, pchan->plat_irq, chan); +} +static const struct mbox_chan_ops pcc_chan_ops = { .send_data = pcc_send_data, + .startup = pcc_startup, + .shutdown = pcc_shutdown, };/**
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 509/568 mailbox: pcc: Add support for platform notification handling
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huisong Li <[email protected]>
[ Upstream commit 60c40b06fa68694dd08a1a0038ea8b9de3f3b1ca ]
Currently, PCC driver doesn't support the processing of platform notification for type 4 PCC subspaces.
According to ACPI specification, if platform sends a notification to OSPM, it must clear the command complete bit and trigger platform interrupt. OSPM needs to check whether the command complete bit is cleared, clear platform interrupt, process command, and then set the command complete and ring doorbell to the Platform.
Let us stash the value of the pcc type and use the same while processing the interrupt of the channel. We also need to set the command complete bit and ring doorbell in the interrupt handler for the type 4 channel to complete the communication flow after processing the notification from the Platform.
Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register")
--- drivers/mailbox/pcc.c | 50 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 9 deletions(-)
drivers/mailbox/pcc.c +41 -9
@@ -91,6 +91,7 @@ struct pcc_chan_reg {* @cmd_update: PCC register bundle for the command complete update register * @error: PCC register bundle for the error status register * @plat_irq: platform interrupt +* @type: PCC subspace type */ struct pcc_chan_info {struct pcc_mbox_chan chan;
@@ -100,12 +101,15 @@ struct pcc_chan_info {struct pcc_chan_reg cmd_update;struct pcc_chan_reg error;int plat_irq; +u8 type; };#define to_pcc_chan_info (c) container_of(c, struct pcc_chan_info, chan)static struct pcc_chan_info *chan_info;static int pcc_chan_count; +static int pcc_send_data (struct mbox_chan *chan,void *data); +/* * PCC can be used with perf critical drivers such as CPPC * So it makes sense to locally cache the virtual address and
@@ -221,6 +225,34 @@ static int pcc_map_interrupt(u32 interrupt, u32 flags)return acpi_register_gsi (NULL , interrupt, trigger, polarity); } +static bool pcc_mbox_cmd_complete_check (struct pcc_chan_info *pchan) +{ +u64 val; +int ret; + + ret =pcc_chan_reg_read (&pchan->cmd_complete, &val); +if (ret) +return false; + +if (!pchan->cmd_complete.gas) +return true; + +/* +* Judge if the channel respond the interrupt based on the value of +* command complete. +*/ + val &= pchan->cmd_complete.status_mask; +/* +* If this is PCC slave subspace channel, and the command complete +* bit 0 indicates that Platform is sending a notification and OSPM +* needs to respond this interrupt to process this command. +*/ +if (pchan->type ==ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE ) +return !val; + +return !!val; +} +/** * pcc_mbox_irq - PCC mailbox interrupt handler * @irq: interrupt number
@@ -236,17 +268,9 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)int ret; pchan = chan->con_priv; - - ret =pcc_chan_reg_read (&pchan->cmd_complete, &val); -if (ret) +if (!pcc_mbox_cmd_complete_check (pchan))return IRQ_NONE ; -if (val) {/* Ensure GAS exists and value is non-zero */ - val &= pchan->cmd_complete.status_mask; -if (!val) -return IRQ_NONE ; - } - ret =pcc_chan_reg_read (&pchan->error, &val);if (ret)return IRQ_NONE ;
@@ -262,6 +286,13 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)mbox_chan_received_data (chan,NULL ); +/* +* The PCC slave subspace channel needs to set the command complete bit +* and ring doorbell after processing message. +*/ +if (pchan->type ==ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE ) +pcc_send_data (chan,NULL ); +return IRQ_HANDLED ; }
@@ -698,6 +729,7 @@ static int pcc_mbox_probe(struct platform_device *pdev)pcc_parse_subspace_shmem (pchan, pcct_entry); + pchan->type = pcct_entry->type; pcct_entry = (struct acpi_subtable_header *) ((unsigned long ) pcct_entry + pcct_entry->length); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 510/568 mailbox: pcc: Support shared interrupt for multiple subspaces
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huisong Li <[email protected]>
[ Upstream commit 3db174e478cb0bb34888c20a531608b70aec9c1f ]
If the platform acknowledge interrupt is level triggered, then it can be shared by multiple subspaces provided each one has a unique platform interrupt ack preserve and ack set masks.
If it can be shared, then we can request the irq with IRQF_SHARED and IRQF_ONESHOT flags. The first one indicating it can be shared and the latter one to keep the interrupt disabled until the hardirq handler finished.
Further, since there is no way to detect if the interrupt is for a given channel as the interrupt ack preserve and ack set masks are for clearing the interrupt and not for reading the status(in case Irq Ack register may be write-only on some platforms), we need a way to identify if the given channel is in use and expecting the interrupt.
PCC type0, type1 and type5 do not support shared level triggered interrupt. The methods of determining whether a given channel for remaining types should respond to an interrupt are as follows:
- type2: Whether the interrupt belongs to a given channel is only determined by the status field in Generic Communications Channel Shared Memory Region, which is done in rx_callback of PCC client.
- type3: This channel checks chan_in_use flag first and then checks the command complete bit(value '1' indicates that the command has been completed).
- type4: Platform ensure that the default value of the command complete bit corresponding to the type4 channel is '1'. This command complete bit is '0' when receive a platform notification.
The new field, 'chan_in_use' is used by the type only support the communication from OSPM to Platform (like type3) and should be completely ignored by other types so as to avoid too many type unnecessary checks in IRQ handler.
Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register")
--- drivers/mailbox/pcc.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-)
drivers/mailbox/pcc.c +40 -3
@@ -92,6 +92,13 @@ struct pcc_chan_reg {* @error: PCC register bundle for the error status register * @plat_irq: platform interrupt * @type: PCC subspace type +* @plat_irq_flags: platform interrupt flags +* @chan_in_use: this flag is used just to check if the interrupt needs +* handling when it is shared. Since only one transfer can occur +* at a time and mailbox takes care of locking, this flag can be +* accessed without a lock. Note: the type only support the +* communication from OSPM to Platform, like type3, use it, and +* other types completely ignore it. */ struct pcc_chan_info {struct pcc_mbox_chan chan;
@@ -102,6 +109,8 @@ struct pcc_chan_info {struct pcc_chan_reg error;int plat_irq;u8 type; +unsigned int plat_irq_flags; +bool chan_in_use; };#define to_pcc_chan_info (c) container_of(c, struct pcc_chan_info, chan)
@@ -225,6 +234,12 @@ static int pcc_map_interrupt(u32 interrupt, u32 flags)return acpi_register_gsi (NULL , interrupt, trigger, polarity); } +static bool pcc_chan_plat_irq_can_be_shared (struct pcc_chan_info *pchan) +{ +return (pchan->plat_irq_flags &ACPI_PCCT_INTERRUPT_MODE ) == +ACPI_LEVEL_SENSITIVE ; +} +static bool pcc_mbox_cmd_complete_check (struct pcc_chan_info *pchan) {u64 val;
@@ -242,6 +257,7 @@ static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)* command complete. */ val &= pchan->cmd_complete.status_mask; +/* * If this is PCC slave subspace channel, and the command complete * bit 0 indicates that Platform is sending a notification and OSPM
@@ -268,6 +284,10 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)int ret; pchan = chan->con_priv; +if (pchan->type ==ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE && + !pchan->chan_in_use) +return IRQ_NONE ; +if (!pcc_mbox_cmd_complete_check (pchan))return IRQ_NONE ;
@@ -289,9 +309,12 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)/* * The PCC slave subspace channel needs to set the command complete bit * and ring doorbell after processing message. +* +* The PCC master subspace channel clears chan_in_use to free channel. */ if (pchan->type ==ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE )pcc_send_data (chan,NULL ); + pchan->chan_in_use = false;return IRQ_HANDLED ; }
@@ -371,7 +394,11 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)if (ret)return ret; -return pcc_chan_reg_read_modify_write (&pchan->db); + ret =pcc_chan_reg_read_modify_write (&pchan->db); +if (!ret && pchan->plat_irq >0 ) + pchan->chan_in_use = true; + +return ret; }/**
@@ -384,11 +411,14 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)static int pcc_startup (struct mbox_chan *chan) {struct pcc_chan_info *pchan = chan->con_priv; +unsigned long irqflags;int rc;if (pchan->plat_irq >0 ) { - rc =devm_request_irq (chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq,0 , -MBOX_IRQ_NAME , chan); + irqflags =pcc_chan_plat_irq_can_be_shared (pchan) ? +IRQF_SHARED |IRQF_ONESHOT :0 ; + rc =devm_request_irq (chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq, + irqflags,MBOX_IRQ_NAME , chan);if (unlikely (rc)) {dev_err (chan->mbox->dev,"failed to register PCC interrupt %d\n" , pchan->plat_irq);
@@ -494,6 +524,7 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan, pcct_ss->platform_interrupt);return -EINVAL ; } + pchan->plat_irq_flags = pcct_ss->flags;if (pcct_ss->header.type ==ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2 ) {struct acpi_pcct_hw_reduced_type2 *pcct2_ss = (void *)pcct_ss;
@@ -515,6 +546,12 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan, "PLAT IRQ ACK"); } +if (pcc_chan_plat_irq_can_be_shared (pchan) && + !pchan->plat_irq_ack.gas) { +pr_err ("PCC subspace has level IRQ with no ACK register\n" ); +return -EINVAL ; + } +return ret; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 511/568 ACPI: PCC: Add PCC shared memory region command and status bitfields
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sudeep Holla <[email protected]>
[ Upstream commit 55d235ebb684b993b3247740c1c8e273f8af4a54 ]
Define the common macros to use when referring to various bitfields in the PCC generic communications channel command and status fields.
Currently different drivers that need to use these bitfields have defined these locally. This common macro is intended to consolidate and replace those.
Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register")
--- include/acpi/pcc.h | 13 +++++++++++++ 1 file changed, 13 insertions(+)
include/acpi/pcc.h +13 -0
@@ -18,7 +18,20 @@ struct pcc_mbox_chan {u16 min_turnaround_time; }; +/* Generic Communications Channel Shared Memory Region */ +#define PCC_SIGNATURE 0x50434300 +/* Generic Communications Channel Command Field */ +#define PCC_CMD_GENERATE_DB_INTR BIT(15) +/* Generic Communications Channel Status Field */ +#define PCC_STATUS_CMD_COMPLETE BIT(0) +#define PCC_STATUS_SCI_DOORBELL BIT(1) +#define PCC_STATUS_ERROR BIT(2) +#define PCC_STATUS_PLATFORM_NOTIFY BIT(3) +/* Initiator Responder Communications Channel Flags */ +#define PCC_CMD_COMPLETION_NOTIFY BIT(0) +#define MAX_PCC_SUBSPACES 256 +#ifdef CONFIG_PCC extern struct pcc_mbox_chan *pcc_mbox_request_channel (struct mbox_client *cl,int subspace_id);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 512/568 mailbox: pcc: Check before sending MCTP PCC response ACK
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adam Young <[email protected]>
[ Upstream commit 7f9e19f207be0c534d517d65e01417ba968cdd34 ]
Type 4 PCC channels have an option to send back a response to the platform when they are done processing the request. The flag to indicate whether or not to respond is inside the message body, and thus is not available to the pcc mailbox.
If the flag is not set, still set command completion bit after processing message.
In order to read the flag, this patch maps the shared buffer to virtual memory. To avoid duplication of mapping the shared buffer is then made available to be used by the driver that uses the mailbox.
Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register")
--- drivers/mailbox/pcc.c | 61 +++++++++++++++++++++++++++++++++++++------ include/acpi/pcc.h | 7 +++++ 2 files changed, 60 insertions(+), 8 deletions(-)
drivers/mailbox/pcc.c +53 -8
@@ -269,6 +269,35 @@ static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)return !!val; } +static void check_and_ack (struct pcc_chan_info *pchan,struct mbox_chan *chan) +{ +struct acpi_pcct_ext_pcc_shared_memory pcc_hdr; + +if (pchan->type !=ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE ) +return ; +/* If the memory region has not been mapped, we cannot +* determine if we need to send the message, but we still +* need to set the cmd_update flag before returning. +*/ +if (pchan->chan.shmem ==NULL ) { +pcc_chan_reg_read_modify_write (&pchan->cmd_update); +return ; + } +memcpy_fromio (&pcc_hdr, pchan->chan.shmem, +sizeof (struct acpi_pcct_ext_pcc_shared_memory )); +/* +* The PCC slave subspace channel needs to set the command complete bit +* after processing message. If the PCC_ACK_FLAG is set, it should also +* ring the doorbell. +* +* The PCC master subspace channel clears chan_in_use to free channel. +*/ +if (le32_to_cpup (&pcc_hdr.flags) &PCC_ACK_FLAG_MASK ) +pcc_send_data (chan,NULL ); +else +pcc_chan_reg_read_modify_write (&pchan->cmd_update); +} +/** * pcc_mbox_irq - PCC mailbox interrupt handler * @irq: interrupt number
@@ -306,14 +335,7 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)mbox_chan_received_data (chan,NULL ); -/* -* The PCC slave subspace channel needs to set the command complete bit -* and ring doorbell after processing message. -* -* The PCC master subspace channel clears chan_in_use to free channel. -*/ -if (pchan->type ==ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE ) -pcc_send_data (chan,NULL ); +check_and_ack (pchan, chan); pchan->chan_in_use = false;return IRQ_HANDLED ;
@@ -365,14 +387,37 @@ EXPORT_SYMBOL_GPL(pcc_mbox_request_channel);void pcc_mbox_free_channel (struct pcc_mbox_chan *pchan) {struct mbox_chan *chan = pchan->mchan; +struct pcc_chan_info *pchan_info; +struct pcc_mbox_chan *pcc_mbox_chan;if (!chan || !chan->cl)return ; + pchan_info = chan->con_priv; + pcc_mbox_chan = &pchan_info->chan; +if (pcc_mbox_chan->shmem) { +iounmap (pcc_mbox_chan->shmem); + pcc_mbox_chan->shmem =NULL ; + }mbox_free_channel (chan); }EXPORT_SYMBOL_GPL (pcc_mbox_free_channel); +int pcc_mbox_ioremap (struct mbox_chan *chan) +{ +struct pcc_chan_info *pchan_info; +struct pcc_mbox_chan *pcc_mbox_chan; + +if (!chan || !chan->cl) +return -1 ; + pchan_info = chan->con_priv; + pcc_mbox_chan = &pchan_info->chan; + pcc_mbox_chan->shmem =ioremap (pcc_mbox_chan->shmem_base_addr, + pcc_mbox_chan->shmem_size); +return 0 ; +} +EXPORT_SYMBOL_GPL (pcc_mbox_ioremap); +/** * pcc_send_data - Called from Mailbox Controller code. Used * here only to ring the channel doorbell. The PCC client
include/acpi/pcc.h +7 -0
@@ -12,6 +12,7 @@struct pcc_mbox_chan {struct mbox_chan *mchan;u64 shmem_base_addr; +void __iomem *shmem;u64 shmem_size;u32 latency;u32 max_access_rate;
@@ -31,11 +32,13 @@ struct pcc_mbox_chan {#define PCC_CMD_COMPLETION_NOTIFY BIT(0)#define MAX_PCC_SUBSPACES 256 +#define PCC_ACK_FLAG_MASK 0x1#ifdef CONFIG_PCC extern struct pcc_mbox_chan *pcc_mbox_request_channel (struct mbox_client *cl,int subspace_id);extern void pcc_mbox_free_channel (struct pcc_mbox_chan *chan); +extern int pcc_mbox_ioremap (struct mbox_chan *chan);#else static inline struct pcc_mbox_chan *pcc_mbox_request_channel (struct mbox_client *cl,int subspace_id)
@@ -43,6 +46,10 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)return ERR_PTR (-ENODEV ); }static inline void pcc_mbox_free_channel (struct pcc_mbox_chan *chan) { } +static inline int pcc_mbox_ioremap (struct mbox_chan *chan) +{ +return 0 ; +};#endif #endif /* _PCC_H */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 513/568 mailbox: pcc: Refactor error handling in irq handler into separate function
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sudeep Holla <[email protected]>
[ Upstream commit 3a675f50415b95f2ae10bfd932e2154ba1a08ee7 ]
The existing error handling logic in pcc_mbox_irq() is intermixed with the main flow of the function. The command complete check and the complete complete update/acknowledgment are nicely factored into separate functions.
Moves error detection and clearing logic into a separate function called:pcc_mbox_error_check_and_clear() by extracting error-handling logic from pcc_mbox_irq().
This ensures error checking and clearing are handled separately and it improves maintainability by keeping the IRQ handler focused on processing events.
Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register")
--- drivers/mailbox/pcc.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-)
drivers/mailbox/pcc.c +20 -10
@@ -269,6 +269,25 @@ static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)return !!val; } +static int pcc_mbox_error_check_and_clear (struct pcc_chan_info *pchan) +{ +u64 val; +int ret; + + ret =pcc_chan_reg_read (&pchan->error, &val); +if (ret) +return ret; + + val &= pchan->error.status_mask; +if (val) { + val &= ~pchan->error.status_mask; +pcc_chan_reg_write (&pchan->error, val); +return -EIO ; + } + +return 0 ; +} +static void check_and_ack (struct pcc_chan_info *pchan,struct mbox_chan *chan) {struct acpi_pcct_ext_pcc_shared_memory pcc_hdr;
@@ -309,8 +328,6 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) {struct pcc_chan_info *pchan;struct mbox_chan *chan = p; -u64 val; -int ret; pchan = chan->con_priv; if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE &&
@@ -320,15 +337,8 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)if (!pcc_mbox_cmd_complete_check (pchan))return IRQ_NONE ; - ret =pcc_chan_reg_read (&pchan->error, &val); -if (ret) +if (pcc_mbox_error_check_and_clear (pchan))return IRQ_NONE ; - val &= pchan->error.status_mask; -if (val) { - val &= ~pchan->error.status_mask; -pcc_chan_reg_write (&pchan->error, val); -return IRQ_NONE ; - }if (pcc_chan_reg_read_modify_write (&pchan->plat_irq_ack))return IRQ_NONE ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 514/568 mailbox: pcc: dont zero error register
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamie Iles <[email protected]>
[ Upstream commit ff0e4d4c97c94af34cc9cad37b5a5cdbe597a3b0 ]
The error status mask for a type 3/4 subspace is used for reading the error status, and the bitwise inverse is used for clearing the error with the intent being to preserve any of the non-error bits. However, we were previously applying the mask to extract the status and then applying the inverse to the result which ended up clearing all bits.
Instead, store the inverse mask in the preserve mask and then use that on the original value read from the error status so that only the error is cleared.
--- drivers/mailbox/pcc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/mailbox/pcc.c +4 -4
@@ -278,9 +278,8 @@ static int pcc_mbox_error_check_and_clear(struct pcc_chan_info *pchan)if (ret)return ret; - val &= pchan->error.status_mask; -if (val) { - val &= ~pchan->error.status_mask; +if (val & pchan->error.status_mask) { + val &= pchan->error.preserve_mask;pcc_chan_reg_write (&pchan->error, val);return -EIO ; }
@@ -662,7 +661,8 @@ static int pcc_parse_subspace_db_reg(struct pcc_chan_info *pchan, ret =pcc_chan_reg_init (&pchan->error, &pcct_ext->error_status_register, -0 ,0 , pcct_ext->error_status_mask, + ~pcct_ext->error_status_mask,0 , + pcct_ext->error_status_mask,"Error Status" ); }return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 515/568 spi: bcm63xx: fix premature CS deassertion on RX-only transactions
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hang Zhou <[email protected]>
[ Upstream commit fd9862f726aedbc2f29a29916cabed7bcf5cadb6 ]
On BCM6358 (and also observed on BCM6368) the controller appears to only generate as many SPI clocks as bytes that have been written into the TX FIFO. For RX-only transfers the driver programs the transfer length in SPI_MSG_CTL but does not write anything into the FIFO, so chip select is deasserted early and the RX transfer segment is never fully clocked in.
A concrete failing case is a three-transfer MAC address read from SPI-NOR:
- TX 0x03 (read command)
- TX 3-byte address
- RX 6 bytes (MAC)
In contrast, a two-transfer JEDEC-ID read (0x9f + 6-byte RX) works because the driver uses prepend_len and writes dummy bytes into the TX FIFO for the RX part.
Fix this by writing 0xff dummy bytes into the TX FIFO for RX-only segments so that the number of bytes written to the FIFO matches the total message length seen by the controller.
--- drivers/spi/spi-bcm63xx.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/spi/spi-bcm63xx.c +14 -0
@@ -257,6 +257,20 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,if (t->rx_buf) { do_rx = true; + +/* +* In certain hardware implementations, there appears to be a +* hidden accumulator that tracks the number of bytes written into +* the hardware FIFO, and this accumulator overrides the length in +* the SPI_MSG_CTL register. +* +* Therefore, for read-only transfers, we need to write some dummy +* value into the FIFO to keep the accumulator tracking the correct +* length. +*/ +if (!t->tx_buf) +memset_io (bs->tx_io + len,0xFF , t->len); +/* prepend is half-duplex write only */ if (t == first) prepend_len =0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 516/568 Revert "perf/x86: Always store regs->ip in perf_callchain_kernel()"
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Olsa <[email protected]>
commit 6d08340d1e354787d6c65a8c3cdd4d41ffb8a5ed upstream.
This reverts commit 83f44ae0f8afcc9da659799db8693f74847e66b3.
Currently we store initial stacktrace entry twice for non-HW ot_regs, which means callers that fail perf_hw_regs(regs) condition in perf_callchain_kernel.
It's easy to reproduce this bpftrace:
# bpftrace -e 'tracepoint:sched:sched_process_exec { print(kstack()); }'
Attaching 1 probe... bprm_execve+1767
bprm_execve+1767
do_execveat_common.isra.0+425
__x64_sys_execve+56
do_syscall_64+133
entry_SYSCALL_64_after_hwframe+118When perf_callchain_kernel calls unwind_start with first_frame, AFAICS we do not skip regs->ip, but it's added as part of the unwind process. Hence reverting the extra perf_callchain_store for non-hw regs leg.
I was not able to bisect this, so I'm not really sure why this was needed in v5.2 and why it's not working anymore, but I could see double entries as far as v5.10.
I did the test for both ORC and framepointer unwind with and without the this fix and except for the initial entry the stacktraces are the same.
--- arch/x86/events/core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
arch/x86/events/core.c +5 -5
@@ -2794,13 +2794,13 @@ perf_callchain_kernel(struct perf_callchreturn ; } -if (perf_callchain_store (entry, regs->ip)) -return ; - -if (perf_hw_regs (regs)) +if (perf_hw_regs (regs)) { +if (perf_callchain_store (entry, regs->ip)) +return ;unwind_start (&state, current, regs,NULL ); -else + }else {unwind_start (&state, current,NULL , (void *)regs->sp); + }for (; !unwind_done (&state);unwind_next_frame (&state)) { addr =unwind_get_return_address (&state);
Greg Kroah-Hartman
maintainerPATCH 517/568 iio: imu: st_lsm6dsx: fix array size for st_lsm6dsx_settings fields
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Francesco Lavra <[email protected]>
commit 3af0c1fb1cdc351b64ff1a4bc06d491490c1f10a upstream.
The decimator and batch fields of struct st_lsm6dsx_settings are arrays indexed by sensor type, not by sensor hardware identifier; moreover, the batch field is only used for the accelerometer and gyroscope.
Change the array size for decimator from ST_LSM6DSX_MAX_ID to ST_LSM6DSX_ID_MAX, and change the array size for batch from ST_LSM6DSX_MAX_ID to 2; move the enum st_lsm6dsx_sensor_id definition so that the ST_LSM6DSX_ID_MAX value is usable within the struct st_lsm6dsx_settings definition.
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +11 -11
@@ -232,6 +232,15 @@ struct st_lsm6dsx_event_settings {u8 wakeup_src_x_mask; }; +enum st_lsm6dsx_sensor_id { +ST_LSM6DSX_ID_GYRO , +ST_LSM6DSX_ID_ACC , +ST_LSM6DSX_ID_EXT0 , +ST_LSM6DSX_ID_EXT1 , +ST_LSM6DSX_ID_EXT2 , +ST_LSM6DSX_ID_MAX +}; +enum st_lsm6dsx_ext_sensor_id {ST_LSM6DSX_ID_MAGN , };
@@ -315,23 +324,14 @@ struct st_lsm6dsx_settings {struct st_lsm6dsx_reg drdy_mask;struct st_lsm6dsx_odr_table_entry odr_table[2 ];struct st_lsm6dsx_fs_table_entry fs_table[2 ]; -struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID ]; -struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID ]; +struct st_lsm6dsx_reg decimator[ST_LSM6DSX_ID_MAX ]; +struct st_lsm6dsx_reg batch[2 ];struct st_lsm6dsx_fifo_ops fifo_ops;struct st_lsm6dsx_hw_ts_settings ts_settings;struct st_lsm6dsx_shub_settings shub_settings;struct st_lsm6dsx_event_settings event_settings; }; -enum st_lsm6dsx_sensor_id { -ST_LSM6DSX_ID_GYRO , -ST_LSM6DSX_ID_ACC , -ST_LSM6DSX_ID_EXT0 , -ST_LSM6DSX_ID_EXT1 , -ST_LSM6DSX_ID_EXT2 , -ST_LSM6DSX_ID_MAX , -}; -enum st_lsm6dsx_fifo_mode {ST_LSM6DSX_FIFO_BYPASS =0x0 ,ST_LSM6DSX_FIFO_CONT =0x6 ,
Greg Kroah-Hartman
maintainerPATCH 518/568 iio:common:ssp_sensors: Fix an error handling path ssp_probe()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
commit 21553258b94861a73d7f2cf15469d69240e1170d upstream.
If an error occurs after a successful mfd_add_devices() call, it should be undone by a corresponding mfd_remove_devices() call, as already done in the remove function.
--- drivers/iio/common/ssp_sensors/ssp_dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/iio/common/ssp_sensors/ssp_dev.c +3 -1
@@ -503,7 +503,7 @@ static int ssp_probe(struct spi_device * ret =spi_setup (spi);if (ret <0 ) {dev_err (&spi->dev,"Failed to setup spi\n" ); -return ret; + goto err_setup_spi; } data->fw_dl_state =SSP_FW_DL_STATE_NONE ;
@@ -568,6 +568,8 @@ err_read_reg: err_setup_irq:mutex_destroy (&data->pending_lock);mutex_destroy (&data->comm_lock); +err_setup_spi: +mfd_remove_devices (&spi->dev);dev_err (&spi->dev,"Probe failed!\n" );
Greg Kroah-Hartman
maintainerPATCH 519/568 iio: accel: bmc150: Fix irq assumption regression
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <[email protected]>
commit 3aa385a9c75c09b59dcab2ff76423439d23673ab upstream.
The code in bmc150-accel-core.c unconditionally calls bmc150_accel_set_interrupt() in the iio_buffer_setup_ops, such as on the runtime PM resume path giving a kernel splat like this if the device has no interrupts:
Unable to handle kernel NULL pointer dereference at virtual address 00000001 when read
PC is at bmc150_accel_set_interrupt+0x98/0x194
LR is at __pm_runtime_resume+0x5c/0x64
(...)
Call trace: bmc150_accel_set_interrupt from bmc150_accel_buffer_postenable+0x40/0x108 bmc150_accel_buffer_postenable from __iio_update_buffers+0xbe0/0xcbc __iio_update_buffers from enable_store+0x84/0xc8 enable_store from kernfs_fop_write_iter+0x154/0x1b4
This bug seems to have been in the driver since the beginning, but it only manifests recently, I do not know why.
Store the IRQ number in the state struct, as this is a common pattern in other drivers, then use this to determine if we have IRQ support or not.
--- drivers/iio/accel/bmc150-accel-core.c | 5 +++++ drivers/iio/accel/bmc150-accel.h | 1 + 2 files changed, 6 insertions(+)
drivers/iio/accel/bmc150-accel-core.c +5 -0
@@ -569,6 +569,10 @@ static int bmc150_accel_set_interrupt(stconst struct bmc150_accel_interrupt_info *info = intr->info;int ret; +/* We do not always have an IRQ */ +if (data->irq <=0 ) +return 0 ; +if (state) {if (atomic_inc_return (&intr->users) >1 )return 0 ;
@@ -1756,6 +1760,7 @@ int bmc150_accel_core_probe(struct devic }if (irq >0 ) { + data->irq = irq; ret = devm_request_threaded_irq(dev, irq, bmc150_accel_irq_handler, bmc150_accel_irq_thread_handler,
drivers/iio/accel/bmc150-accel.h +1 -0
@@ -57,6 +57,7 @@ enum bmc150_accel_trigger_id {struct bmc150_accel_data {struct regmap *regmap; +int irq;struct regulator_bulk_data regulators[2 ];struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS ];struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS ];
Greg Kroah-Hartman
maintainerPATCH 520/568 iio: accel: fix ADXL355 startup race condition
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Valek Andrej <[email protected]>
commit c92c1bc408e9e11ae3c7011b062fdd74c09283a3 upstream.
There is an race-condition where device is not full working after SW reset. Therefore it's necessary to wait some time after reset and verify shadow registers values by reading and comparing the values before/after reset. This mechanism is described in datasheet at least from revision D.
--- drivers/iio/accel/adxl355_core.c | 44 ++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-)
drivers/iio/accel/adxl355_core.c +39 -5
@@ -56,6 +56,8 @@#define ADXL355_POWER_CTL_DRDY_MSK BIT(2)#define ADXL355_SELF_TEST_REG 0x2E#define ADXL355_RESET_REG 0x2F +#define ADXL355_BASE_ADDR_SHADOW_REG 0x50 +#define ADXL355_SHADOW_REG_COUNT 5#define ADXL355_DEVID_AD_VAL 0xAD#define ADXL355_DEVID_MST_VAL 0x1D
@@ -238,7 +240,12 @@ static void adxl355_fill_3db_frequency_tstatic int adxl355_setup (struct adxl355_data *data) {unsigned int regval; +int retries =5 ;/* the number is chosen based on empirical reasons */ int ret; + u8 *shadow_regs __free(kfree) = kzalloc(ADXL355_SHADOW_REG_COUNT, GFP_KERNEL); + +if (!shadow_regs) +return -ENOMEM ; ret =regmap_read (data->regmap,ADXL355_DEVID_AD_REG , ®val);if (ret)
@@ -267,14 +274,41 @@ static int adxl355_setup(struct adxl355_return -ENODEV ; } -/* -* Perform a software reset to make sure the device is in a consistent -* state after start-up. -*/ - ret =regmap_write (data->regmap,ADXL355_RESET_REG ,ADXL355_RESET_CODE ); +/* Read shadow registers to be compared after reset */ + ret =regmap_bulk_read (data->regmap, +ADXL355_BASE_ADDR_SHADOW_REG , + shadow_regs,ADXL355_SHADOW_REG_COUNT );if (ret)return ret; +do { +if (--retries ==0 ) { +dev_err (data->dev,"Shadow registers mismatch\n" ); +return -EIO ; + } + +/* +* Perform a software reset to make sure the device is in a consistent +* state after start-up. +*/ + ret =regmap_write (data->regmap,ADXL355_RESET_REG , +ADXL355_RESET_CODE ); +if (ret) +return ret; + +/* Wait at least 5ms after software reset */ +usleep_range (5000 ,10000 ); + +/* Read shadow registers for comparison */ + ret =regmap_bulk_read (data->regmap, +ADXL355_BASE_ADDR_SHADOW_REG , + data->buffer.buf, +ADXL355_SHADOW_REG_COUNT ); +if (ret) +return ret; + }while (memcmp (shadow_regs, data->buffer.buf, +ADXL355_SHADOW_REG_COUNT )); + ret =regmap_update_bits (data->regmap,ADXL355_POWER_CTL_REG ,ADXL355_POWER_CTL_DRDY_MSK ,FIELD_PREP (ADXL355_POWER_CTL_DRDY_MSK ,1 ));
Greg Kroah-Hartman
maintainerPATCH 521/568 iio: adc: ad7280a: fix ad7280_store_balance_timer()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit bd886cdcbf9e746f61c74035a3acd42e9108e115 upstream.
Use correct argument to iio_str_to_fixpoint() to parse 3 decimal places.
iio_str_to_fixpoint() has a bit of an unintuitive API where the fract_mult parameter is the multiplier of the first decimal place as if it was already an integer. So to get 3 decimal places, fract_mult must be 100 rather than 1000.
--- drivers/iio/adc/ad7280a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/ad7280a.c +1 -1
@@ -540,7 +540,7 @@ static ssize_t ad7280_store_balance_timeint val, val2;int ret; - ret =iio_str_to_fixpoint (buf,1000 , &val, &val2); + ret =iio_str_to_fixpoint (buf,100 , &val, &val2);if (ret)return ret;
Greg Kroah-Hartman
maintainerPATCH 522/568 MIPS: mm: Prevent a TLB shutdown on initial uniquification
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maciej W. Rozycki <[email protected]>
commit 9f048fa487409e364cf866c957cf0b0d782ca5a3 upstream.
Depending on the particular CPU implementation a TLB shutdown may occur if multiple matching entries are detected upon the execution of a TLBP or the TLBWI/TLBWR instructions. Given that we don't know what entries we have been handed we need to be very careful with the initial TLB setup and avoid all these instructions.
Therefore read all the TLB entries one by one with the TLBR instruction, bypassing the content addressing logic, and truncate any large pages in place so as to avoid a case in the second step where an incoming entry for a large page at a lower address overlaps with a replacement entry chosen at another index. Then preinitialize the TLB using addresses outside our usual unique range and avoiding clashes with any entries received, before making the usual call to local_flush_tlb_all().
This fixes (at least) R4x00 cores if TLBP hits multiple matching TLB entries (SGI IP22 PROM for examples sets up all TLBs to the same virtual address).
--- arch/mips/mm/tlb-r4k.c | 102 ++++++++++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 38 deletions(-)
arch/mips/mm/tlb-r4k.c +64 -38
@@ -15,6 +15,7 @@#include <linux/mm.h> #include <linux/hugetlb.h> #include <linux/export.h> +#include <linux/sort.h> #include <asm/cpu.h> #include <asm/cpu-type.h>
@@ -498,55 +499,79 @@ static int __init set_ntlb(char *str)__setup ("ntlb=" , set_ntlb); -/* Initialise all TLB entries with unique values */ + +/* Comparison function for EntryHi VPN fields. */ +static int r4k_vpn_cmp (const void *a,const void *b) +{ +long v = *(unsigned long *)a - *(unsigned long *)b; +int s =sizeof (long ) >sizeof (int ) ?sizeof (long ) *8 -1 :0 ; +return s ? (v !=0 ) | v >> s : v; +} + +/* +* Initialise all TLB entries with unique values that do not clash with +* what we have been handed over and what we'll be using ourselves. +*/ static void r4k_tlb_uniquify (void ) { -int entry =num_wired_entries (); +unsigned long tlb_vpns[1 <<MIPS_CONF1_TLBS_SIZE ]; +int tlbsize = current_cpu_data.tlbsize; +int start =num_wired_entries (); +unsigned long vpn_mask; +int cnt, ent, idx, i; + + vpn_mask =GENMASK (cpu_vmbits -1 ,13 ); + vpn_mask |=IS_ENABLED (CONFIG_64BIT ) ?3ULL <<62 :1 <<31 ;htw_stop (); -write_c0_entrylo0 (0 ); -write_c0_entrylo1 (0 ); -while (entry < current_cpu_data.tlbsize) { -unsigned long asid_mask =cpu_asid_mask (¤t_cpu_data); -unsigned long asid =0 ; -int idx; +for (i = start, cnt =0 ; i < tlbsize; i++, cnt++) { +unsigned long vpn; -/* Skip wired MMID to make ginvt_mmid work */ -if (cpu_has_mmid) - asid =MMID_KERNEL_WIRED +1 ; +write_c0_index (i); +mtc0_tlbr_hazard (); +tlb_read (); +tlb_read_hazard (); + vpn =read_c0_entryhi (); + vpn &= vpn_mask &PAGE_MASK ; + tlb_vpns[cnt] = vpn; -/* Check for match before using UNIQUE_ENTRYHI */ -do { -if (cpu_has_mmid) { -write_c0_memorymapid (asid); -write_c0_entryhi (UNIQUE_ENTRYHI (entry)); - }else { -write_c0_entryhi (UNIQUE_ENTRYHI (entry) | asid); - } -mtc0_tlbw_hazard (); -tlb_probe (); -tlb_probe_hazard (); - idx =read_c0_index (); -/* No match or match is on current entry */ -if (idx <0 || idx == entry) -break ; -/* -* If we hit a match, we need to try again with -* a different ASID. -*/ - asid++; - }while (asid < asid_mask); - -if (idx >=0 && idx != entry) -panic ("Unable to uniquify TLB entry %d" , idx); - -write_c0_index (entry); +/* Prevent any large pages from overlapping regular ones. */ +write_c0_pagemask (read_c0_pagemask () &PM_DEFAULT_MASK );mtc0_tlbw_hazard ();tlb_write_indexed (); - entry++; +tlbw_use_hazard (); } +sort (tlb_vpns, cnt,sizeof (tlb_vpns[0 ]), r4k_vpn_cmp,NULL ); + +write_c0_pagemask (PM_DEFAULT_MASK ); +write_c0_entrylo0 (0 ); +write_c0_entrylo1 (0 ); + + idx =0 ; + ent = tlbsize; +for (i = start; i < tlbsize; i++) +while (1 ) { +unsigned long entryhi, vpn; + + entryhi =UNIQUE_ENTRYHI (ent); + vpn = entryhi & vpn_mask &PAGE_MASK ; + +if (idx >= cnt || vpn < tlb_vpns[idx]) { +write_c0_entryhi (entryhi); +write_c0_index (i); +mtc0_tlbw_hazard (); +tlb_write_indexed (); + ent++; +break ; + }else if (vpn == tlb_vpns[idx]) { + ent++; + }else { + idx++; + } + } +tlbw_use_hazard ();htw_start ();flush_micro_tlb ();
@@ -592,6 +617,7 @@ static void r4k_tlb_configure(void)/* From this point on the ARC firmware is dead. */ r4k_tlb_uniquify (); +local_flush_tlb_all ();/* Did I tell you that ARC SUCKS? */ }
Greg Kroah-Hartman
maintainerPATCH 523/568 MIPS: mm: kmalloc tlb_vpn array to avoid stack overflow
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Bogendoerfer <[email protected]>
commit 841ecc979b18d3227fad5e2d6a1e6f92688776b5 upstream.
Owing to Config4.MMUSizeExt and VTLB/FTLB MMU features later MIPSr2+ cores can have more than 64 TLB entries. Therefore allocate an array for uniquification instead of placing too an small array on the stack.
--- arch/mips/mm/tlb-r4k.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
arch/mips/mm/tlb-r4k.c +16 -2
@@ -12,6 +12,7 @@#include <linux/init.h> #include <linux/sched.h> #include <linux/smp.h> +#include <linux/memblock.h> #include <linux/mm.h> #include <linux/hugetlb.h> #include <linux/export.h>
@@ -512,17 +513,26 @@ static int r4k_vpn_cmp(const void *a, co* Initialise all TLB entries with unique values that do not clash with * what we have been handed over and what we'll be using ourselves. */ -static void r4k_tlb_uniquify (void ) +static void __ref r4k_tlb_uniquify (void ) { -unsigned long tlb_vpns[1 <<MIPS_CONF1_TLBS_SIZE ];int tlbsize = current_cpu_data.tlbsize; +bool use_slab =slab_is_available ();int start =num_wired_entries (); +phys_addr_t tlb_vpn_size; +unsigned long *tlb_vpns;unsigned long vpn_mask;int cnt, ent, idx, i; vpn_mask =GENMASK (cpu_vmbits -1 ,13 ); vpn_mask |=IS_ENABLED (CONFIG_64BIT ) ?3ULL <<62 :1 <<31 ; + tlb_vpn_size = tlbsize *sizeof (*tlb_vpns); + tlb_vpns = (use_slab ? +kmalloc (tlb_vpn_size,GFP_KERNEL ) : +memblock_alloc_raw (tlb_vpn_size,sizeof (*tlb_vpns))); +if (WARN_ON (!tlb_vpns)) +return ;/* Pray local_flush_tlb_all() is good enough. */ +htw_stop ();for (i = start, cnt =0 ; i < tlbsize; i++, cnt++) {
@@ -575,6 +585,10 @@ static void r4k_tlb_uniquify(void)tlbw_use_hazard ();htw_start ();flush_micro_tlb (); +if (use_slab) +kfree (tlb_vpns); +else +memblock_free (tlb_vpns, tlb_vpn_size); }/*
Greg Kroah-Hartman
maintainerPATCH 524/568 ALSA: usb-audio: Add DSD quirk for LEAK Stereo 230
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Zhaldak <[email protected]>
commit c83fc13960643c4429cd9dfef1321e6430a81b47 upstream.
Integrated amplifier LEAK Stereo 230 by IAG Limited has built-in ESS9038Q2M DAC served by XMOS controller. It supports both DSD Native and DSD-over-PCM (DoP) operational modes. But it doesn't work properly by default and tries DSD-to-PCM conversion. USB quirks below allow it to operate as designed.
Add DSD_RAW quirk flag for IAG Limited devices (vendor ID 0x2622) Add DSD format quirk for LEAK Stereo 230 (USB ID 0x2622:0x0061)
--- sound/usb/quirks.c | 3 +++ 1 file changed, 3 insertions(+)
sound/usb/quirks.c +3 -0
@@ -1926,6 +1926,7 @@ u64 snd_usb_interface_dsd_format_quirks(case USB_ID (0x249c ,0x9326 ):/* M2Tech Young MkIII */ case USB_ID (0x2616 ,0x0106 ):/* PS Audio NuWave DAC */ case USB_ID (0x2622 ,0x0041 ):/* Audiolab M-DAC+ */ +case USB_ID (0x2622 ,0x0061 ):/* LEAK Stereo 230 */ case USB_ID (0x278b ,0x5100 ):/* Rotel RC-1590 */ case USB_ID (0x27f7 ,0x3002 ):/* W4S DAC-2v2SE */ case USB_ID (0x29a2 ,0x0086 ):/* Mutec MC3+ USB */
@@ -2309,6 +2310,8 @@ static const struct usb_audio_quirk_flag QUIRK_FLAG_DSD_RAW),VENDOR_FLG (0x25ce ,/* Mytek devices */ QUIRK_FLAG_DSD_RAW ), +VENDOR_FLG (0x2622 ,/* IAG Limited devices */ +QUIRK_FLAG_DSD_RAW ),VENDOR_FLG (0x278b ,/* Rotel? */ QUIRK_FLAG_DSD_RAW ), VENDOR_FLG(0x292b, /* Gustard/Ess based devices */
Greg Kroah-Hartman
maintainerPATCH 525/568 atm/fore200e: Fix possible data race in fore200e_open()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gui-Dong Han <[email protected]>
commit 82fca3d8a4a34667f01ec2351a607135249c9cff upstream.
Protect access to fore200e->available_cell_rate with rate_mtx lock in the error handling path of fore200e_open() to prevent a data race.
The field fore200e->available_cell_rate is a shared resource used to track available bandwidth. It is concurrently accessed by fore200e_open(), fore200e_close(), and fore200e_change_qos().
In fore200e_open(), the lock rate_mtx is correctly held when subtracting vcc->qos.txtp.max_pcr from available_cell_rate to reserve bandwidth. However, if the subsequent call to fore200e_activate_vcin() fails, the function restores the reserved bandwidth by adding back to available_cell_rate without holding the lock.
This introduces a race condition because available_cell_rate is a global device resource shared across all VCCs. If the error path in fore200e_open() executes concurrently with operations like fore200e_close() or fore200e_change_qos() on other VCCs, a read-modify-write race occurs.
Specifically, the error path reads the rate without the lock. If another CPU acquires the lock and modifies the rate (e.g., releasing bandwidth in fore200e_close()) between this read and the subsequent write, the error path will overwrite the concurrent update with a stale value. This results in incorrect bandwidth accounting.
--- drivers/atm/fore200e.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/atm/fore200e.c +2 -0
@@ -1377,7 +1377,9 @@ fore200e_open(struct atm_vcc *vcc) vcc->dev_data =NULL ; +mutex_lock (&fore200e->rate_mtx); fore200e->available_cell_rate += vcc->qos.txtp.max_pcr; +mutex_unlock (&fore200e->rate_mtx);kfree (fore200e_vcc);return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 526/568 can: sja1000: fix max irq loop handling
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Mühlbacher <[email protected]>
commit 30db4451c7f6aabcada029b15859a76962ec0cf8 upstream.
Reading the interrupt register SJA1000_IR causes all of its bits to be reset. If we ever reach the condition of handling more than SJA1000_MAX_IRQ IRQs, we will have read the register and reset all its bits but without actually handling the interrupt inside of the loop body.
This may, among other issues, cause us to never netif_wake_queue() again after a transmission interrupt.
--- drivers/net/can/sja1000/sja1000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/can/sja1000/sja1000.c +2 -2
@@ -521,8 +521,8 @@ irqreturn_t sja1000_interrupt(int irq, vif (priv->read_reg (priv,SJA1000_IER ) ==IRQ_OFF ) goto out; -while ((isrc = priv->read_reg (priv,SJA1000_IR )) && - (n <SJA1000_MAX_IRQ )) { +while ((n <SJA1000_MAX_IRQ ) && + (isrc = priv->read_reg (priv,SJA1000_IR ))) { status = priv->read_reg (priv,SJA1000_SR );/* check for absent controller due to hw unplug */
Greg Kroah-Hartman
maintainerPATCH 527/568 can: sun4i_can: sun4i_can_interrupt(): fix max irq loop handling
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Kleine-Budde <[email protected]>
commit 76544beea7cfe5bcce6d60f53811657b88ec8be1 upstream.
Reading the interrupt register SUN4I_REG_INT_ADDR causes all of its bits to be reset. If we ever reach the condition of handling more than SUN4I_CAN_MAX_IRQ IRQs, we will have read the register and reset all its bits but without actually handling the interrupt inside of the loop body.
This may, among other issues, cause us to never netif_wake_queue() again after a transmission interrupt.
--- drivers/net/can/sun4i_can.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/can/sun4i_can.c +2 -2
@@ -658,8 +658,8 @@ static irqreturn_t sun4i_can_interrupt(iu8 isrc, status;int n =0 ; -while ((isrc =readl (priv->base +SUN4I_REG_INT_ADDR )) && - (n <SUN4I_CAN_MAX_IRQ )) { +while ((n <SUN4I_CAN_MAX_IRQ ) && + (isrc =readl (priv->base +SUN4I_REG_INT_ADDR ))) { n++; status =readl (priv->base +SUN4I_REG_STA_ADDR );
Greg Kroah-Hartman
maintainerPATCH 528/568 dm-verity: fix unreliable memory allocation
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
commit fe680d8c747f4e676ac835c8c7fb0f287cd98758 upstream.
GFP_NOWAIT allocation may fail anytime. It needs to be changed to GFP_NOIO. There's no need to handle an error because mempool_alloc with GFP_NOIO can't fail.
--- drivers/md/dm-verity-fec.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/md/dm-verity-fec.c +1 -5
@@ -330,11 +330,7 @@ static int fec_alloc_bufs(struct dm_veriif (fio->bufs[n])continue ; - fio->bufs[n] =mempool_alloc (&v->fec->prealloc_pool,GFP_NOWAIT ); -if (unlikely (!fio->bufs[n])) { -DMERR ("failed to allocate FEC buffer" ); -return -ENOMEM ; - } + fio->bufs[n] =mempool_alloc (&v->fec->prealloc_pool,GFP_NOIO ); }/* try to allocate the maximum number of buffers */
Greg Kroah-Hartman
maintainerPATCH 529/568 drivers/usb/dwc3: fix PCI parent check
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamie Iles <[email protected]>
commit 40f8d17eed7533ed2bbb5e3cc680049b19411b2e upstream.
The sysdev_is_parent check was being used to infer PCI devices that have the DMA mask set from the PCI capabilities, but sysdev_is_parent is also used for non-PCI ACPI devices in which case the DMA mask would be the bus default or as set by the _DMA method.
Without this fix the DMA mask would default to 32-bits and so allocation would fail if there was no DRAM below 4GB.
--- drivers/usb/dwc3/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/dwc3/core.c +2 -1
@@ -25,6 +25,7 @@#include <linux/of.h> #include <linux/of_graph.h> #include <linux/acpi.h> +#include <linux/pci.h> #include <linux/pinctrl/consumer.h> #include <linux/reset.h> #include <linux/bitfield.h>
@@ -1996,7 +1997,7 @@ static int dwc3_probe(struct platform_deplatform_set_drvdata (pdev, dwc);dwc3_cache_hwparams (dwc); -if (!dwc->sysdev_is_parent && +if (!dev_is_pci (dwc->sysdev) &&DWC3_GHWPARAMS0_AWIDTH (dwc->hwparams.hwparams0) ==64 ) { ret =dma_set_mask_and_coherent (dwc->sysdev,DMA_BIT_MASK (64 ));if (ret)
Greg Kroah-Hartman
maintainerPATCH 530/568 smb: client: fix memory leak in cifs_construct_tcon()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <[email protected]>
commit 3184b6a5a24ec9ee74087b2a550476f386df7dc2 upstream.
When having a multiuser mount with domain= specified and using cifscreds, cifs_set_cifscreds() will end up setting @ctx->domainname, so it needs to be freed before leaving cifs_construct_tcon().
This fixes the following memory leak reported by kmemleak:
mount.cifs //srv/share /mnt -o domain=ZELDA,multiuser,... su - testuser
cifscreds add -d ZELDA -u testuser
...
ls /mnt/1
...
umount /mnt
echo scan > /sys/kernel/debug/kmemleak
cat /sys/kernel/debug/kmemleak
unreferenced object 0xffff8881203c3f08 (size 8):
comm "ls", pid 5060, jiffies 4307222943
hex dump (first 8 bytes):
5a 45 4c 44 41 00 cc cc ZELDA...
backtrace (crc d109a8cf):
__kmalloc_node_track_caller_noprof+0x572/0x710
kstrdup+0x3a/0x70
cifs_sb_tlink+0x1209/0x1770 [cifs]
cifs_get_fattr+0xe1/0xf50 [cifs]
cifs_get_inode_info+0xb5/0x240 [cifs]
cifs_revalidate_dentry_attr+0x2d1/0x470 [cifs]
cifs_getattr+0x28e/0x450 [cifs]
vfs_getattr_nosec+0x126/0x180
vfs_statx+0xf6/0x220
do_statx+0xab/0x110
__x64_sys_statx+0xd5/0x130
do_syscall_64+0xbb/0x380
entry_SYSCALL_64_after_hwframe+0x77/0x7f--- fs/smb/client/connect.c | 1 + 1 file changed, 1 insertion(+)
fs/smb/client/connect.c +1 -0
@@ -4417,6 +4417,7 @@ cifs_construct_tcon(struct cifs_sb_info out:kfree (ctx->username); +kfree (ctx->domainname);kfree_sensitive (ctx->password);kfree (ctx);
Greg Kroah-Hartman
maintainerPATCH 531/568 thunderbolt: Add support for Intel Wildcat Lake
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alan Borzeszkowski <[email protected]>
commit 3575254546a27210a4b661ea37fbbfb836c0815d upstream.
Intel Wildcat Lake derives its Thunderbolt/USB4 controller from Lunar Lake platform. Add Wildcat Lake PCI ID to the driver list of supported devices.
--- drivers/thunderbolt/nhi.c | 2 ++ drivers/thunderbolt/nhi.h | 1 + 2 files changed, 3 insertions(+)
drivers/thunderbolt/nhi.c +2 -0
@@ -1491,6 +1491,8 @@ static struct pci_device_id nhi_ids[] = .driver_data = (kernel_ulong_t)&icl_nhi_ops }, { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_PTL_P_NHI1), .driver_data = (kernel_ulong_t)&icl_nhi_ops }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_WCL_NHI0), + .driver_data = (kernel_ulong_t)&icl_nhi_ops }, { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI) }, { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI) },
drivers/thunderbolt/nhi.h +1 -0
@@ -75,6 +75,7 @@ extern const struct tb_nhi_ops icl_nhi_o#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_BRIDGE 0x15ef#define PCI_DEVICE_ID_INTEL_ADL_NHI0 0x463e#define PCI_DEVICE_ID_INTEL_ADL_NHI1 0x466d +#define PCI_DEVICE_ID_INTEL_WCL_NHI0 0x4d33#define PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI 0x5781#define PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI 0x5784#define PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HUB_80G_BRIDGE 0x5786
Greg Kroah-Hartman
maintainerPATCH 532/568 slimbus: ngd: Fix reference count leak in qcom_slim_ngd_notify_slaves
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miaoqian Lin <[email protected]>
commit 96cf8500934e0ce2a6c486f1dbc3b1fff12f7a5e upstream.
The function qcom_slim_ngd_notify_slaves() calls of_slim_get_device() which internally uses device_find_child() to obtain a device reference. According to the device_find_child() documentation,
the caller must drop the reference with put_device() after use.
Found via static analysis and this is similar to commit 4e65bda8273c ("ASoC: wcd934x: fix error handling in wcd934x_codec_parse_data()")
--- drivers/slimbus/qcom-ngd-ctrl.c | 1 + 1 file changed, 1 insertion(+)
drivers/slimbus/qcom-ngd-ctrl.c +1 -0
@@ -1164,6 +1164,7 @@ static void qcom_slim_ngd_notify_slaves(if (slim_get_logical_addr (sbdev))dev_err (ctrl->dev,"Failed to get logical address\n" ); +put_device (&sbdev->dev); } }
Greg Kroah-Hartman
maintainerPATCH 533/568 firmware: stratix10-svc: fix bug in saving controller data
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Khairul Anuar Romli <[email protected]>
commit d0fcf70c680e4d1669fcb3a8632f41400b9a73c2 upstream.
Fix the incorrect usage of platform_set_drvdata and dev_set_drvdata. They both are of the same data and overrides each other. This resulted in the rmmod of the svc driver to fail and throw a kernel panic for kthread_stop and fifo free.
--- drivers/firmware/stratix10-svc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/firmware/stratix10-svc.c +4 -3
@@ -133,6 +133,7 @@ struct stratix10_svc_data {* @complete_status: state for completion * @svc_fifo_lock: protect access to service message data queue * @invoke_fn: function to issue secure monitor call or hypervisor call +* @svc: manages the list of client svc drivers * * This struct is used to create communication channels for service clients, to * handle secure monitor or hypervisor call.
@@ -149,6 +150,7 @@ struct stratix10_svc_controller {struct completion complete_status;spinlock_t svc_fifo_lock;svc_invoke_fn *invoke_fn; +struct stratix10_svc *svc; };/**
@@ -1191,6 +1193,7 @@ static int stratix10_svc_drv_probe(struc ret = -ENOMEM ; goto err_free_kfifo; } + controller->svc = svc; svc->stratix10_svc_rsu =platform_device_alloc (STRATIX10_RSU ,0 );if (!svc->stratix10_svc_rsu) {
@@ -1218,8 +1221,6 @@ static int stratix10_svc_drv_probe(struc goto err_unregister_dev; } -dev_set_drvdata (dev, svc); -pr_info ("Intel Service Layer Driver Initialized\n" );return 0 ;
@@ -1235,8 +1236,8 @@ err_destroy_pool:static int stratix10_svc_drv_remove (struct platform_device *pdev) { -struct stratix10_svc *svc =dev_get_drvdata (&pdev->dev);struct stratix10_svc_controller *ctrl =platform_get_drvdata (pdev); +struct stratix10_svc *svc = ctrl->svc;platform_device_unregister (svc->intel_svc_fcs);platform_device_unregister (svc->stratix10_svc_rsu);
Greg Kroah-Hartman
maintainerPATCH 534/568 serial: amba-pl011: prefer dma_mapping_error() over explicit address checking
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miaoqian Lin <[email protected]>
commit eb4917f557d43c7a1c805dd73ffcdfddb2aba39a upstream.
Check for returned DMA addresses using specialized dma_mapping_error() helper which is generally recommended for this purpose by Documentation/core-api/dma-api.rst:
"In some circumstances dma_map_single(), ...
will fail to create a mapping. A driver can check for these errors by testing the returned DMA address with dma_mapping_error()."
Found via static analysis and this is similar to commit fa0308134d26 ("ALSA: memalloc: prefer dma_mapping_error() over explicit address checking")
--- drivers/tty/serial/amba-pl011.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/amba-pl011.c +1 -1
@@ -635,7 +635,7 @@ static int pl011_dma_tx_refill(struct ua dmatx->len = count; dmatx->dma =dma_map_single (dma_dev->dev, dmatx->buf, count,DMA_TO_DEVICE ); -if (dmatx->dma ==DMA_MAPPING_ERROR ) { +if (dma_mapping_error (dma_dev->dev, dmatx->dma)) { uap->dmatx.queued = false;dev_dbg (uap->port.dev,"unable to map TX DMA\n" );return -EBUSY ;
Greg Kroah-Hartman
maintainerPATCH 535/568 most: usb: fix double free on late probe failure
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit baadf2a5c26e802a46573eaad331b427b49aaa36 upstream.
The MOST subsystem has a non-standard registration function which frees the interface on registration failures and on deregistration.
This unsurprisingly leads to bugs in the MOST drivers, and a couple of recent changes turned a reference underflow and use-after-free in the USB driver into several double free and a use-after-free on late probe failures.
--- drivers/most/most_usb.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
drivers/most/most_usb.c +5 -9
@@ -1058,7 +1058,7 @@ hdm_probe(struct usb_interface *interfac ret =most_register_interface (&mdev->iface);if (ret) - goto err_free_busy_urbs; +return ret;mutex_lock (&mdev->io_mutex); if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 ||
@@ -1068,8 +1068,7 @@ hdm_probe(struct usb_interface *interfacif (!mdev->dci) {mutex_unlock (&mdev->io_mutex);most_deregister_interface (&mdev->iface); - ret = -ENOMEM ; - goto err_free_busy_urbs; +return -ENOMEM ; } mdev->dci->dev.init_name ="dci" ;
@@ -1078,18 +1077,15 @@ hdm_probe(struct usb_interface *interfac mdev->dci->dev.release = release_dci;if (device_register (&mdev->dci->dev)) {mutex_unlock (&mdev->io_mutex); +put_device (&mdev->dci->dev);most_deregister_interface (&mdev->iface); - ret = -ENOMEM ; - goto err_free_dci; +return -ENOMEM ; } mdev->dci->usb_device = mdev->usb_device; }mutex_unlock (&mdev->io_mutex);return 0 ; -err_free_dci: -put_device (&mdev->dci->dev); -err_free_busy_urbs: -kfree (mdev->busy_urbs); + err_free_ep_address:kfree (mdev->ep_address); err_free_cap:
Greg Kroah-Hartman
maintainerPATCH 536/568 usb: cdns3: Fix double resource release in cdns3_pci_probe
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miaoqian Lin <[email protected]>
commit 1ec39d2cd88dac2e7cdbac248762f1f057971c5d upstream.
The driver uses pcim_enable_device() to enable the PCI device, the device will be automatically disabled on driver detach through the managed device framework. The manual pci_disable_device() calls in the error paths are therefore redundant and should be removed.
Found via static anlaysis and this is similar to commit 99ca0b57e49f ("thermal: intel: int340x: processor: Fix warning during module unload").
--- drivers/usb/cdns3/cdns3-pci-wrap.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
drivers/usb/cdns3/cdns3-pci-wrap.c +1 -4
@@ -101,10 +101,8 @@ static int cdns3_pci_probe(struct pci_de wrap =pci_get_drvdata (func); }else { wrap =kzalloc (sizeof (*wrap),GFP_KERNEL ); -if (!wrap) { -pci_disable_device (pdev); +if (!wrap)return -ENOMEM ; - } } res = wrap->dev_res;
@@ -163,7 +161,6 @@ static int cdns3_pci_probe(struct pci_de/* register platform device */ wrap->plat_dev =platform_device_register_full (&plat_info);if (IS_ERR (wrap->plat_dev)) { -pci_disable_device (pdev); err =PTR_ERR (wrap->plat_dev);kfree (wrap);return err;
Greg Kroah-Hartman
maintainerPATCH 537/568 usb: gadget: f_eem: Fix memory leak in eem_unwrap
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuen-Han Tsai <[email protected]>
commit e4f5ce990818d37930cd9fb0be29eee0553c59d9 upstream.
The existing code did not handle the failure case of usb_ep_queue in the command path, potentially leading to memory leaks.
Improve error handling to free all allocated resources on usb_ep_queue failure. This patch continues to use goto logic for error handling, as the existing error handling is complex and not easily adaptable to auto-cleanup helpers.
kmemleak results:
unreferenced object 0xffffff895a512300 (size 240):
backtrace:
slab_post_alloc_hook+0xbc/0x3a4
kmem_cache_alloc+0x1b4/0x358
skb_clone+0x90/0xd8
eem_unwrap+0x1cc/0x36c
unreferenced object 0xffffff8a157f4000 (size 256):
backtrace:
slab_post_alloc_hook+0xbc/0x3a4
__kmem_cache_alloc_node+0x1b4/0x2dc
kmalloc_trace+0x48/0x140
dwc3_gadget_ep_alloc_request+0x58/0x11c
usb_ep_alloc_request+0x40/0xe4
eem_unwrap+0x204/0x36c
unreferenced object 0xffffff8aadbaac00 (size 128):
backtrace:
slab_post_alloc_hook+0xbc/0x3a4
__kmem_cache_alloc_node+0x1b4/0x2dc
__kmalloc+0x64/0x1a8
eem_unwrap+0x218/0x36c
unreferenced object 0xffffff89ccef3500 (size 64):
backtrace:
slab_post_alloc_hook+0xbc/0x3a4
__kmem_cache_alloc_node+0x1b4/0x2dc
kmalloc_trace+0x48/0x140
eem_unwrap+0x238/0x36c--- drivers/usb/gadget/function/f_eem.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/usb/gadget/function/f_eem.c +6 -1
@@ -479,8 +479,13 @@ static int eem_unwrap(struct gether *por req->complete = eem_cmd_complete; req->zero =1 ; req->context = ctx; -if (usb_ep_queue (port->in_ep, req,GFP_ATOMIC )) +if (usb_ep_queue (port->in_ep, req,GFP_ATOMIC )) {DBG (cdev,"echo response queue fail\n" ); +kfree (ctx); +kfree (req->buf); +usb_ep_free_request (ep, req); +dev_kfree_skb_any (skb2); + }break ;case 1 :/* echo response */
Greg Kroah-Hartman
maintainerPATCH 538/568 usb: storage: Fix memory leak in USB bulk transport
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Desnes Nunes <[email protected]>
commit 41e99fe2005182139b1058db71f0d241f8f0078c upstream.
A kernel memory leak was identified by the 'ioctl_sg01' test from Linux Test Project (LTP). The following bytes were mainly observed: 0x53425355.
When USB storage devices incorrectly skip the data phase with status data, the code extracts/validates the CSW from the sg buffer, but fails to clear it afterwards. This leaves status protocol data in srb's transfer buffer, such as the US_BULK_CS_SIGN 'USBS' signature observed here. Thus, this can lead to USB protocols leaks to user space through SCSI generic (/dev/sg*) interfaces, such as the one seen here when the LTP test requested 512 KiB.
Fix the leak by zeroing the CSW data in srb's transfer buffer immediately after the validation of devices that skip data phase.
Note: Differently from CVE-2018-1000204, which fixed a big leak by zero- ing pages at allocation time, this leak occurs after allocation, when USB protocol data is written to already-allocated sg pages.
--- drivers/usb/storage/transport.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
drivers/usb/storage/transport.c +16 -0
@@ -1204,7 +1204,23 @@ int usb_stor_Bulk_transport(struct scsi_ US_BULK_CS_WRAP_LEN && bcs->Signature == cpu_to_le32(US_BULK_CS_SIGN)) { +unsigned char buf[US_BULK_CS_WRAP_LEN ]; +usb_stor_dbg (us,"Device skipped data phase\n" ); + +/* +* Devices skipping data phase might leave CSW data in srb's +* transfer buffer. Zero it to prevent USB protocol leakage. +*/ + sg =NULL ; + offset =0 ; +memset (buf,0 ,sizeof (buf)); +if (usb_stor_access_xfer_buf (buf, +US_BULK_CS_WRAP_LEN , srb, &sg, + &offset,TO_XFER_BUF ) != +US_BULK_CS_WRAP_LEN ) +usb_stor_dbg (us,"Failed to clear CSW data\n" ); +scsi_set_resid (srb, transfer_length); goto skipped_data_phase; }
Greg Kroah-Hartman
maintainerPATCH 539/568 USB: storage: Remove subclass and protocol overrides from Novatek quirk
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alan Stern <[email protected]>
commit df5fde297e617041449f603ed5f646861c80000b upstream.
A report from Oleg Smirnov indicates that the unusual_devs quirks entry for the Novatek camera does not need to override the subclass and protocol parameters:
[3266355.209532] usb 1-3: new high-speed USB device number 10 using xhci_hcd
[3266355.333031] usb 1-3: New USB device found, idVendor=0603, idProduct=8611, bcdDevice= 1.00
[3266355.333040] usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[3266355.333043] usb 1-3: Product: YICARCAM
[3266355.333045] usb 1-3: Manufacturer: XIAO-YI
[3266355.333047] usb 1-3: SerialNumber: 966110000000100
[3266355.338621] usb-storage 1-3:1.0: USB Mass Storage device detected
[3266355.338817] usb-storage 1-3:1.0: Quirks match for vid 0603 pid 8611: 4000
[3266355.338821] usb-storage 1-3:1.0: This device (0603,8611,0100 S 06 P 50) has unneeded SubClass and Protocol entries in unusual_devs.h (kernel 6.16.10-arch1-1)
Please send a copy of this message to<[email protected]> and <[email protected]>
The overrides are harmless but they do provoke the driver into logging this annoying message. Update the entry to remove the unneeded entries.
--- drivers/usb/storage/unusual_devs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/storage/unusual_devs.h +1 -1
@@ -938,7 +938,7 @@ UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0xUNUSUAL_DEV (0x0603 ,0x8611 ,0x0000 ,0xffff ,"Novatek" ,"NTK96550-based camera" , -USB_SC_SCSI ,USB_PR_BULK ,NULL , +USB_SC_DEVICE ,USB_PR_DEVICE ,NULL , US_FL_BULK_IGNORE_TAG ),/*
Greg Kroah-Hartman
maintainerPATCH 540/568 usb: storage: sddr55: Reject out-of-bound new_pba
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tianchu Chen <[email protected]>
commit b59d4fda7e7d0aff1043a7f742487cb829f5aac1 upstream.
Discovered by Atuin - Automated Vulnerability Discovery Engine.
new_pba comes from the status packet returned after each write. A bogus device could report values beyond the block count derived from info->capacity, letting the driver walk off the end of pba_to_lba[] and corrupt heap memory.
Reject PBAs that exceed the computed block count and fail the transfer so we avoid touching out-of-range mapping entries.
--- drivers/usb/storage/sddr55.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/usb/storage/sddr55.c +6 -0
@@ -469,6 +469,12 @@ static int sddr55_write_data(struct us_d new_pba = (status[3 ] + (status[4 ] <<8 ) + (status[5 ] <<16 )) >> info->blockshift; +/* check if device-reported new_pba is out of range */ +if (new_pba >= (info->capacity >> (info->blockshift + info->pageshift))) { + result =USB_STOR_TRANSPORT_FAILED ; + goto leave; + } +/* check status for error */ if (status[0 ] ==0xff && status[1 ] ==0x4 ) { info->pba_to_lba[new_pba] =BAD_BLOCK ;
Greg Kroah-Hartman
maintainerPATCH 541/568 usb: uas: fix urb unmapping issue when the uas device is remove during ongoing data transfer
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Owen Gu <[email protected]>
commit 26d56a9fcb2014b99e654127960aa0a48a391e3c upstream.
When a UAS device is unplugged during data transfer, there is a probability of a system panic occurring. The root cause is an access to an invalid memory address during URB callback handling. Specifically, this happens when the dma_direct_unmap_sg() function is called within the usb_hcd_unmap_urb_for_dma() interface, but the sg->dma_address field is 0 and the sg data structure has already been freed.
The SCSI driver sends transfer commands by invoking uas_queuecommand_lck() in uas.c, using the uas_submit_urbs() function to submit requests to USB. Within the uas_submit_urbs() implementation, three URBs (sense_urb, data_urb, and cmd_urb) are sequentially submitted. Device removal may occur at any point during uas_submit_urbs execution, which may result in URB submission failure. However, some URBs might have been successfully submitted before the failure, and uas_submit_urbs will return the -ENODEV error code in this case. The current error handling directly calls scsi_done(). In the SCSI driver, this eventually triggers scsi_complete() to invoke scsi_end_request() for releasing the sgtable. The successfully submitted URBs, when being unlinked to giveback, call usb_hcd_unmap_urb_for_dma() in hcd.c, leading to exceptions during sg unmapping operations since the sg data structure has already been freed.
This patch modifies the error condition check in the uas_submit_urbs() function. When a UAS device is removed but one or more URBs have already been successfully submitted to USB, it avoids immediately invoking scsi_done() and save the cmnd to devinfo->cmnd array. If the successfully submitted URBs is completed before devinfo->resetting being set, then the scsi_done() function will be called within uas_try_complete() after all pending URB operations are finalized. Otherwise, the scsi_done() function will be called within uas_zap_pending(), which is executed after usb_kill_anchored_urbs().
The error handling only takes effect when uas_queuecommand_lck() calls uas_submit_urbs() and returns the error value -ENODEV . In this case, the device is disconnected, and the flow proceeds to uas_disconnect(), where uas_zap_pending() is invoked to call uas_try_complete().
--- drivers/usb/storage/uas.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/usb/storage/uas.c +5 -0
@@ -697,6 +697,10 @@ static int uas_queuecommand_lck(struct s* of queueing, no matter how fatal the error */ if (err == -ENODEV ) { +if (cmdinfo->state & (COMMAND_INFLIGHT |DATA_IN_URB_INFLIGHT | +DATA_OUT_URB_INFLIGHT )) + goto out; +set_host_byte (cmnd,DID_NO_CONNECT );scsi_done (cmnd); goto zombie;
@@ -710,6 +714,7 @@ static int uas_queuecommand_lck(struct suas_add_work (cmnd); } +out: devinfo->cmnd[idx] = cmnd; zombie:spin_unlock_irqrestore (&devinfo->lock, flags);
Greg Kroah-Hartman
maintainerPATCH 542/568 usb: dwc3: Fix race condition between concurrent dwc3_remove_requests() call paths
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manish Nagar <[email protected]>
commit e4037689a366743c4233966f0e74bc455820d316 upstream.
This patch addresses a race condition caused by unsynchronized execution of multiple call paths invoking dwc3_remove_requests(), leading to premature freeing of USB requests and subsequent crashes.
Three distinct execution paths interact with dwc3_remove_requests():
Path 1:
Triggered via dwc3_gadget_reset_interrupt() during USB reset handling. The call stack includes:
- dwc3_ep0_reset_state()
- dwc3_ep0_stall_and_restart()
- dwc3_ep0_out_start()
- dwc3_remove_requests()
- dwc3_gadget_del_and_unmap_request()
Path 2:
Also initiated from dwc3_gadget_reset_interrupt(), but through dwc3_stop_active_transfers(). The call stack includes:
- dwc3_stop_active_transfers()
- dwc3_remove_requests()
- dwc3_gadget_del_and_unmap_request()
Path 3:
Occurs independently during adb root execution, which triggers USB function unbind and bind operations. The sequence includes:
- gserial_disconnect()
- usb_ep_disable()
- dwc3_gadget_ep_disable()
- dwc3_remove_requests() with -ESHUTDOWN status
Path 3 operates asynchronously and lacks synchronization with Paths 1 and 2. When Path 3 completes, it disables endpoints and frees 'out' requests. If Paths 1 or 2 are still processing these requests, accessing freed memory leads to a crash due to use-after-free conditions.
To fix this added check for request completion and skip processing if already completed and added the request status for ep0 while queue.
--- drivers/usb/dwc3/ep0.c | 1 + drivers/usb/dwc3/gadget.c | 7 +++++++ 2 files changed, 8 insertions(+)
drivers/usb/dwc3/ep0.c +1 -0
@@ -92,6 +92,7 @@ static int __dwc3_gadget_ep0_queue(struc req->request.actual =0 ; req->request.status = -EINPROGRESS ; req->epnum = dep->number; + req->status =DWC3_REQUEST_STATUS_QUEUED ;list_add_tail (&req->list, &dep->pending_list);
drivers/usb/dwc3/gadget.c +7 -0
@@ -229,6 +229,13 @@ void dwc3_gadget_giveback(struct dwc3_ep {struct dwc3 *dwc = dep->dwc; +/* +* The request might have been processed and completed while the +* spinlock was released. Skip processing if already completed. +*/ +if (req->status ==DWC3_REQUEST_STATUS_COMPLETED ) +return ; +dwc3_gadget_del_and_unmap_request (dep, req, status); req->status =DWC3_REQUEST_STATUS_COMPLETED ;
Greg Kroah-Hartman
maintainerPATCH 543/568 xhci: dbgtty: Fix data corruption when transmitting data form DbC to host
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Nyman <[email protected]>
commit f6bb3b67be9af0cfb90075c60850b6af5338a508 upstream.
Data read from a DbC device may be corrupted due to a race between ongoing write and write request completion handler both queuing new transfer blocks (TRBs) if there are remining data in the kfifo.
TRBs may be in incorrct order compared to the data in the kfifo.
Driver fails to keep lock between reading data from kfifo into a dbc request buffer, and queuing the request to the transfer ring.
This allows completed request to re-queue itself in the middle of an ongoing transfer loop, forcing itself between a kfifo read and request TRB write of another request
cpu0 cpu1 (re-queue completed req2)
lock(port_lock)dbc_start_tx()kfifo_out(fifo, req1->buffer)unlock(port_lock)
lock(port_lock)
dbc_write_complete(req2)
dbc_start_tx()
kfifo_out(fifo, req2->buffer)
unlock(port_lock)
lock(port_lock)
req2->trb = ring->enqueue;
ring->enqueue++
unlock(port_lock)lock(port_lock)req1->trb = ring->enqueue;
ring->enqueue++unlock(port_lock)
In the above scenario a kfifo containing "12345678" would read "1234" to req1 and "5678" to req2, but req2 is queued before req1 leading to data being transmitted as "56781234"
Solve this by adding a flag that prevents starting a new tx if we are already mid dbc_start_tx() during the unlocked part.
The already running dbc_do_start_tx() will make sure the newly completed request gets re-queued as it is added to the request write_pool while holding the lock.
--- drivers/usb/host/xhci-dbgcap.h | 1 + drivers/usb/host/xhci-dbgtty.c | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-)
drivers/usb/host/xhci-dbgcap.h +1 -0
@@ -113,6 +113,7 @@ struct dbc_port {unsigned int tx_boundary;bool registered; +bool tx_running; };struct dbc_driver {
drivers/usb/host/xhci-dbgtty.c +16 -1
@@ -47,7 +47,7 @@ dbc_kfifo_to_req(struct dbc_port *port,return len; } -static int dbc_start_tx (struct dbc_port *port) +static int dbc_do_start_tx (struct dbc_port *port) __releases(&port->port_lock) __acquires(&port->port_lock) {
@@ -57,6 +57,8 @@ static int dbc_start_tx(struct dbc_portbool do_tty_wake = false;struct list_head *pool = &port->write_pool; + port->tx_running = true; +while (!list_empty (pool)) { req = list_entry(pool->next, struct dbc_request, list_pool); len =dbc_kfifo_to_req (port, req->buf);
@@ -77,12 +79,25 @@ static int dbc_start_tx(struct dbc_port } } + port->tx_running = false; +if (do_tty_wake && port->port.tty)tty_wakeup (port->port.tty);return status; } +/* must be called with port->port_lock held */ +static int dbc_start_tx (struct dbc_port *port) +{ +lockdep_assert_held (&port->port_lock); + +if (port->tx_running) +return -EBUSY ; + +return dbc_do_start_tx (port); +} + static void dbc_start_rx(struct dbc_port *port) __releases(&port->port_lock) __acquires(&port->port_lock)
Greg Kroah-Hartman
maintainerPATCH 544/568 xhci: dbgtty: fix device unregister
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Łukasz Bartosik <[email protected]>
commit 1f73b8b56cf35de29a433aee7bfff26cea98be3f upstream.
When DbC is disconnected then xhci_dbc_tty_unregister_device() is called. However if there is any user space process blocked on write to DbC terminal device then it will never be signalled and thus stay blocked indifinitely.
This fix adds a tty_vhangup() call in xhci_dbc_tty_unregister_device(). The tty_vhangup() wakes up any blocked writers and causes subsequent write attempts to DbC terminal device to fail.
--- drivers/usb/host/xhci-dbgtty.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/usb/host/xhci-dbgtty.c +6 -0
@@ -519,6 +519,12 @@ static void xhci_dbc_tty_unregister_deviif (!port->registered)return ; +/* +* Hang up the TTY. This wakes up any blocked +* writers and causes subsequent writes to fail. +*/ +tty_vhangup (port->port.tty); +tty_unregister_device (dbc_tty_driver, port->minor);xhci_dbc_tty_exit_port (port); port->registered = false;
Greg Kroah-Hartman
maintainerPATCH 545/568 USB: serial: ftdi_sio: add support for u-blox EVK-M101
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksandr Suvorov <[email protected]>
commit 2d8ab771d5316de64f3bb920b82575c58eb00b1b upstream.
The U-Blox EVK-M101 enumerates as 1546:0506 [1] with four FTDI interfaces:
- EVK-M101 current sensors
- EVK-M101 I2C
- EVK-M101 UART
- EVK-M101 port D
Only the third USB interface is a UART. This change lets ftdi_sio probe the VID/PID and registers only interface #3 as a TTY, leaving the rest available for other drivers.
[1]
usb 5-1.3: new high-speed USB device number 11 using xhci_hcd
usb 5-1.3: New USB device found, idVendor=1546, idProduct=0506, bcdDevice= 8.00 usb 5-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0 usb 5-1.3: Product: EVK-M101
usb 5-1.3: Manufacturer: u-blox AG
Datasheet: https://content.u-blox.com/sites/default/files/documents/EVK-M10_UserGuide_UBX-21003949.pdf
--- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio_ids.h | 1 + 2 files changed, 2 insertions(+)
drivers/usb/serial/ftdi_sio.c +1 -0
@@ -1074,6 +1074,7 @@ static const struct usb_device_id id_tab/* U-Blox devices */ { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ZED_PID) }, { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ODIN_PID) }, + { USB_DEVICE_INTERFACE_NUMBER(UBLOX_VID, UBLOX_EVK_M101_PID, 2) },/* FreeCalypso USB adapters */ { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_BUF_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
drivers/usb/serial/ftdi_sio_ids.h +1 -0
@@ -1614,6 +1614,7 @@#define UBLOX_VID 0x1546#define UBLOX_C099F9P_ZED_PID 0x0502#define UBLOX_C099F9P_ODIN_PID 0x0503 +#define UBLOX_EVK_M101_PID 0x0506/* * GMC devices
Greg Kroah-Hartman
maintainerPATCH 546/568 USB: serial: option: add support for Rolling RW101R-GL
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vanillan Wang <[email protected]>
commit 523bf0a59e674b52e4b5607a2aba655fbfa20ff2 upstream.
- VID:PID 33f8:0301, RW101R-GL for laptop debug M.2 cards (with MBIM interface for Linux/Chrome OS)
0x0301: mbim, pipe
T: Bus=04 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 2 Spd=5000 MxCh= 0 D: Ver= 3.20 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs= 1 P: Vendor=33f8 ProdID=0301 Rev=05.04 S: Manufacturer=Rolling Wireless S.a.r.l. S: Product=Rolling RW101R-GL Module S: SerialNumber=3ec4efdf C: #Ifs= 3 Cfg#= 1 Atr=a0 MxPwr=896mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=0f(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
- VID:PID 33f8:01a8, RW101R-GL for laptop debug M.2 cards (with MBIM interface for Linux/Chrome OS)
0x01a8: mbim, diag, AT, ADB, pipe1, pipe2
T: Bus=04 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 2 Spd=5000 MxCh= 0 D: Ver= 3.20 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs= 1 P: Vendor=33f8 ProdID=01a8 Rev=05.04 S: Manufacturer=Rolling Wireless S.a.r.l. S: Product=Rolling RW101R-GL Module S: SerialNumber=3ec4efdf C: #Ifs= 7 Cfg#= 1 Atr=a0 MxPwr=896mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=0f(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) E: Ad=03(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=86(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 6 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=05(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=88(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=89(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
- VID:PID 33f8:0302, RW101R-GL for laptop debug M.2 cards (with MBIM interface for Linux/Chrome OS)
0x0302: mbim, pipe
T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 6 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=33f8 ProdID=0302 Rev=05.04 S: Manufacturer=Rolling Wireless S.a.r.l. S: Product=Rolling RW101R-GL Module S: SerialNumber=3ec4efdf C: #Ifs= 3 Cfg#= 1 Atr=a0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
- VID:PID 33f8:01a9, RW101R-GL for laptop debug M.2 cards (with MBIM interface for Linux/Chrome OS)
0x01a9: mbim, diag, AT, ADB, pipe1, pipe2
T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=33f8 ProdID=01a9 Rev=05.04 S: Manufacturer=Rolling Wireless S.a.r.l. S: Product=Rolling RW101R-GL Module S: SerialNumber=3ec4efdf C: #Ifs= 7 Cfg#= 1 Atr=a0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 6 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
--- drivers/usb/serial/option.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/usb/serial/option.c +8 -2
@@ -2424,12 +2424,18 @@ static const struct usb_device_id option { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ { USB_DEVICE(0x33f8, 0x0104), /* Rolling RW101-GL (laptop RMNET) */ .driver_info = RSVD(4) | RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0115, 0xff), /* Rolling RW135-GL (laptop MBIM) */ + .driver_info = RSVD(5) }, { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a2, 0xff) }, /* Rolling RW101-GL (laptop MBIM) */ { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a3, 0xff) }, /* Rolling RW101-GL (laptop MBIM) */ { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a4, 0xff), /* Rolling RW101-GL (laptop MBIM) */ .driver_info = RSVD(4) }, - { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0115, 0xff), /* Rolling RW135-GL (laptop MBIM) */ - .driver_info = RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a8, 0xff), /* Rolling RW101R-GL (laptop MBIM) */ + .driver_info = RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a9, 0xff), /* Rolling RW101R-GL (laptop MBIM) */ + .driver_info = RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0301, 0xff) }, /* Rolling RW101R-GL (laptop MBIM) */ + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0302, 0xff) }, /* Rolling RW101R-GL (laptop MBIM) */ { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0802, 0xff), /* Rolling RW350-GL (laptop MBIM) */ .driver_info = RSVD(5) }, { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for Global */
Greg Kroah-Hartman
maintainerPATCH 547/568 drm: sti: fix device leaks at component probe
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 620a8f131154250f6a64a07d049a4f235d6451a5 upstream.
Make sure to drop the references taken to the vtg devices by of_find_device_by_node() when looking up their driver data during component probe.
Note that holding a reference to a platform device does not prevent its driver data from going away so there is no point in keeping the reference after the lookup helper returns.
--- drivers/gpu/drm/sti/sti_vtg.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/sti/sti_vtg.c +6 -1
@@ -143,12 +143,17 @@ struct sti_vtg {struct sti_vtg *of_vtg_find (struct device_node *np) {struct platform_device *pdev; +struct sti_vtg *vtg; pdev =of_find_device_by_node (np);if (!pdev)return NULL ; -return (struct sti_vtg *)platform_get_drvdata (pdev); + vtg =platform_get_drvdata (pdev); + +put_device (&pdev->dev); + +return vtg; }static void vtg_reset (struct sti_vtg *vtg)
Greg Kroah-Hartman
maintainerPATCH 548/568 drm/amd/display: Check NULL before accessing
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
commit 3ce62c189693e8ed7b3abe551802bbc67f3ace54 upstream.
[WHAT]
IGT kms_cursor_legacy's long-nonblocking-modeset-vs-cursor-atomic fails with NULL pointer dereference. This can be reproduced with both an eDP panel and a DP monitors connected.
BUG: kernel NULL pointer dereference, address: 0000000000000000 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: Oops: 0000 [#1] SMP NOPTI CPU: 13 UID: 0 PID: 2960 Comm: kms_cursor_lega Not tainted 6.16.0-99-custom #8 PREEMPT(voluntary) Hardware name: AMD ........ RIP: 0010:dc_stream_get_scanoutpos+0x34/0x130 [amdgpu] Code: 57 4d 89 c7 41 56 49 89 ce 41 55 49 89 d5 41 54 49 89 fc 53 48 83 ec 18 48 8b 87 a0 64 00 00 48 89 75 d0 48 c7 c6 e0 41 30 c2 <48> 8b 38 48 8b 9f 68 06 00 00 e8 8d d7 fd ff 31 c0 48 81 c3 e0 02 RSP: 0018:ffffd0f3c2bd7608 EFLAGS: 00010292 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffd0f3c2bd7668 RDX: ffffd0f3c2bd7664 RSI: ffffffffc23041e0 RDI: ffff8b32494b8000 RBP: ffffd0f3c2bd7648 R08: ffffd0f3c2bd766c R09: ffffd0f3c2bd7760 R10: ffffd0f3c2bd7820 R11: 0000000000000000 R12: ffff8b32494b8000 R13: ffffd0f3c2bd7664 R14: ffffd0f3c2bd7668 R15: ffffd0f3c2bd766c FS: 000071f631b68700(0000) GS:ffff8b399f114000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 00000001b8105000 CR4: 0000000000f50ef0
PKRU: 55555554
Call Trace: <TASK> dm_crtc_get_scanoutpos+0xd7/0x180 [amdgpu] amdgpu_display_get_crtc_scanoutpos+0x86/0x1c0 [amdgpu] ? __pfx_amdgpu_crtc_get_scanout_position+0x10/0x10[amdgpu] amdgpu_crtc_get_scanout_position+0x27/0x50 [amdgpu] drm_crtc_vblank_helper_get_vblank_timestamp_internal+0xf7/0x400 drm_crtc_vblank_helper_get_vblank_timestamp+0x1c/0x30 drm_crtc_get_last_vbltimestamp+0x55/0x90 drm_crtc_next_vblank_start+0x45/0xa0 drm_atomic_helper_wait_for_fences+0x81/0x1f0 ...
--- drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/display/dc/core/dc_stream.c +8 -3
@@ -619,9 +619,14 @@ bool dc_stream_get_scanoutpos(const stru {uint8_t i;bool ret = false; -struct dc *dc = stream->ctx->dc; -struct resource_context *res_ctx = - &dc->current_state->res_ctx; +struct dc *dc; +struct resource_context *res_ctx; + +if (!stream->ctx) +return false; + + dc = stream->ctx->dc; + res_ctx = &dc->current_state->res_ctx;for (i =0 ; i <MAX_PIPES ; i++) {struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg;
Greg Kroah-Hartman
maintainerPATCH 549/568 net: dsa: microchip: common: Fix checks on irq_find_mapping()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bastien Curutchet (Schneider Electric) <[email protected]>
commit 7b3c09e1667977edee11de94a85e2593a7c15e87 upstream.
irq_find_mapping() returns a positive IRQ number or 0 if no IRQ is found but it never returns a negative value. However, on each irq_find_mapping() call, we verify that the returned value isn't negative.
Fix the irq_find_mapping() checks to enter error paths when 0 is returned. Return -EINVAL in such cases.
--- drivers/net/dsa/microchip/ksz_common.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/dsa/microchip/ksz_common.c +4 -4
@@ -1693,8 +1693,8 @@ static int ksz_irq_phy_setup(struct ksz_if (BIT (phy) & ds->phys_mii_mask) { irq =irq_find_mapping (dev->ports[phy].pirq.domain,PORT_SRC_PHY_INT ); -if (irq <0 ) { - ret = irq; +if (!irq) { + ret = -EINVAL ; goto out; } ds->slave_mii_bus->irq[phy] = irq;
@@ -1918,8 +1918,8 @@ static int ksz_pirq_setup(struct ksz_devsnprintf (pirq->name,sizeof (pirq->name),"port_irq-%d" , p); pirq->irq_num =irq_find_mapping (dev->girq.domain, p); -if (pirq->irq_num <0 ) -return pirq->irq_num; +if (!pirq->irq_num) +return -EINVAL ;return ksz_irq_common_setup (dev, pirq); }
Greg Kroah-Hartman
maintainerPATCH 550/568 libceph: fix potential use-after-free in have_mon_and_osd_map()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Dryomov <[email protected]>
commit 076381c261374c587700b3accf410bdd2dba334e upstream.
The wait loop in __ceph_open_session() can race with the client receiving a new monmap or osdmap shortly after the initial map is received. Both ceph_monc_handle_map() and handle_one_map() install a new map immediately after freeing the old one
kfree(monc->monmap);
monc->monmap = monmap;
ceph_osdmap_destroy(osdc->osdmap);
osdc->osdmap = newmap;under client->monc.mutex and client->osdc.lock respectively, but because neither is taken in have_mon_and_osd_map() it's possible for client->monc.monmap->epoch and client->osdc.osdmap->epoch arms in
client->monc.monmap && client->monc.monmap->epoch &&
client->osdc.osdmap && client->osdc.osdmap->epoch;condition to dereference an already freed map. This happens to be reproducible with generic/395 and generic/397 with KASAN enabled:
BUG: KASAN: slab-use-after-free in have_mon_and_osd_map+0x56/0x70
Read of size 4 at addr ffff88811012d810 by task mount.ceph/13305
CPU: 2 UID: 0 PID: 13305 Comm: mount.ceph Not tainted 6.14.0-rc2-build2+ #1266
...
Call Trace:
<TASK>
have_mon_and_osd_map+0x56/0x70
ceph_open_session+0x182/0x290
ceph_get_tree+0x333/0x680
vfs_get_tree+0x49/0x180
do_new_mount+0x1a3/0x2d0
path_mount+0x6dd/0x730
do_mount+0x99/0xe0
__do_sys_mount+0x141/0x180
do_syscall_64+0x9f/0x100
entry_SYSCALL_64_after_hwframe+0x76/0x7e
</TASK>
Allocated by task 13305:
ceph_osdmap_alloc+0x16/0x130
ceph_osdc_init+0x27a/0x4c0
ceph_create_client+0x153/0x190
create_fs_client+0x50/0x2a0
ceph_get_tree+0xff/0x680
vfs_get_tree+0x49/0x180
do_new_mount+0x1a3/0x2d0
path_mount+0x6dd/0x730
do_mount+0x99/0xe0
__do_sys_mount+0x141/0x180
do_syscall_64+0x9f/0x100
entry_SYSCALL_64_after_hwframe+0x76/0x7e
Freed by task 9475:
kfree+0x212/0x290
handle_one_map+0x23c/0x3b0
ceph_osdc_handle_map+0x3c9/0x590
mon_dispatch+0x655/0x6f0
ceph_con_process_message+0xc3/0xe0
ceph_con_v1_try_read+0x614/0x760
ceph_con_workfn+0x2de/0x650
process_one_work+0x486/0x7c0
process_scheduled_works+0x73/0x90
worker_thread+0x1c8/0x2a0
kthread+0x2ec/0x300
ret_from_fork+0x24/0x40
ret_from_fork_asm+0x1a/0x30Rewrite the wait loop to check the above condition directly with client->monc.mutex and client->osdc.lock taken as appropriate. While at it, improve the timeout handling (previously mount_timeout could be exceeded in case wait_event_interruptible_timeout() slept more than once) and access client->auth_err under client->monc.mutex to match how it's set in finish_auth().
monmap_show() and osdmap_show() now take the respective lock before accessing the map as well.
--- net/ceph/ceph_common.c | 53 +++++++++++++++++++++++++++++-------------------- net/ceph/debugfs.c | 14 +++++++++--- 2 files changed, 42 insertions(+), 25 deletions(-)
net/ceph/ceph_common.c +32 -21
@@ -786,41 +786,52 @@ void ceph_reset_client_addr(struct ceph_EXPORT_SYMBOL (ceph_reset_client_addr);/* -* true if we have the mon map (and have thus joined the cluster) -*/ -static bool have_mon_and_osd_map (struct ceph_client *client) -{ -return client->monc.monmap && client->monc.monmap->epoch && - client->osdc.osdmap && client->osdc.osdmap->epoch; -} - -/* * mount: join the ceph cluster, and open root directory. */ int __ceph_open_session (struct ceph_client *client,unsigned long started) { -unsigned long timeout = client->options->mount_timeout; -long err; +DEFINE_WAIT_FUNC (wait, woken_wake_function); +long timeout =ceph_timeout_jiffies (client->options->mount_timeout); +bool have_monmap, have_osdmap; +int err;/* open session, and wait for mon and osd maps */ err =ceph_monc_open_session (&client->monc);if (err <0 )return err; -while (!have_mon_and_osd_map (client)) { -if (timeout &&time_after_eq (jiffies, started + timeout)) -return -ETIMEDOUT ; +add_wait_queue (&client->auth_wq, &wait); +for (;;) { +mutex_lock (&client->monc.mutex); + err = client->auth_err; + have_monmap = client->monc.monmap && client->monc.monmap->epoch; +mutex_unlock (&client->monc.mutex); + +down_read (&client->osdc.lock); + have_osdmap = client->osdc.osdmap && client->osdc.osdmap->epoch; +up_read (&client->osdc.lock); + +if (err || (have_monmap && have_osdmap)) +break ; + +if (signal_pending (current)) { + err = -ERESTARTSYS ; +break ; + } + +if (!timeout) { + err = -ETIMEDOUT ; +break ; + }/* wait */ dout ("mount waiting for mon_map\n" ); - err =wait_event_interruptible_timeout (client->auth_wq, -have_mon_and_osd_map (client) || (client->auth_err <0 ), -ceph_timeout_jiffies (timeout)); -if (err <0 ) -return err; -if (client->auth_err <0 ) -return client->auth_err; + timeout =wait_woken (&wait,TASK_INTERRUPTIBLE , timeout); } +remove_wait_queue (&client->auth_wq, &wait); + +if (err) +return err;pr_info ("client%llu fsid %pU\n" ,ceph_client_gid (client), &client->fsid);
net/ceph/debugfs.c +10 -4
@@ -36,8 +36,9 @@ static int monmap_show(struct seq_file *int i;struct ceph_client *client = s->private; +mutex_lock (&client->monc.mutex);if (client->monc.monmap ==NULL ) -return 0 ; + goto out_unlock;seq_printf (s,"epoch %d\n" , client->monc.monmap->epoch);for (i =0 ; i < client->monc.monmap->num_mon; i++) {
@@ -48,6 +49,9 @@ static int monmap_show(struct seq_file *ENTITY_NAME (inst->name), ceph_pr_addr(&inst->addr)); } + +out_unlock: +mutex_unlock (&client->monc.mutex);return 0 ; }
@@ -56,13 +60,14 @@ static int osdmap_show(struct seq_file *int i;struct ceph_client *client = s->private;struct ceph_osd_client *osdc = &client->osdc; -struct ceph_osdmap *map = osdc->osdmap; +struct ceph_osdmap *map;struct rb_node *n; +down_read (&osdc->lock); + map = osdc->osdmap;if (map ==NULL ) -return 0 ; + goto out_unlock; -down_read (&osdc->lock);seq_printf (s,"epoch %u barrier %u flags 0x%x\n" , map->epoch, osdc->epoch_barrier, map->flags);
@@ -131,6 +136,7 @@ static int osdmap_show(struct seq_file *seq_printf (s,"]\n" ); } +out_unlock:up_read (&osdc->lock);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 551/568 libceph: prevent potential out-of-bounds writes in handle_auth_session_key()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: ziming zhang <[email protected]>
commit 7fce830ecd0a0256590ee37eb65a39cbad3d64fc upstream.
The len field originates from untrusted network packets. Boundary checks have been added to prevent potential out-of-bounds writes when decrypting the connection secret or processing service tickets.
[ idryomov: changelog ]
--- net/ceph/auth_x.c | 2 ++ 1 file changed, 2 insertions(+)
net/ceph/auth_x.c +2 -0
@@ -631,6 +631,7 @@ static int handle_auth_session_key(struc/* connection secret */ ceph_decode_32_safe (p, end, len, e_inval); +ceph_decode_need (p, end, len, e_inval);dout ("%s connection secret blob len %d\n" , __func__, len);if (len >0 ) { dp = *p +ceph_x_encrypt_offset ();
@@ -648,6 +649,7 @@ static int handle_auth_session_key(struc/* service tickets */ ceph_decode_32_safe (p, end, len, e_inval); +ceph_decode_need (p, end, len, e_inval);dout ("%s service tickets blob len %d\n" , __func__, len);if (len >0 ) { ret = ceph_x_proc_ticket_reply(ac, &th->session_key,
Greg Kroah-Hartman
maintainerPATCH 552/568 libceph: replace BUG_ON with bounds check for map->max_osd
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: ziming zhang <[email protected]>
commit ec3797f043756a94ea2d0f106022e14ac4946c02 upstream.
OSD indexes come from untrusted network packets. Boundary checks are added to validate these against map->max_osd.
[ idryomov: drop BUG_ON in ceph_get_primary_affinity(), minor cosmetic
edits ]
--- net/ceph/osdmap.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
net/ceph/osdmap.c +11 -7
@@ -1504,8 +1504,6 @@ static int decode_new_primary_temp(voidu32 ceph_get_primary_affinity (struct ceph_osdmap *map,int osd) { -BUG_ON (osd >= map->max_osd); -if (!map->osd_primary_affinity)return CEPH_OSD_DEFAULT_PRIMARY_AFFINITY ;
@@ -1514,8 +1512,6 @@ u32 ceph_get_primary_affinity(struct cepstatic int set_primary_affinity (struct ceph_osdmap *map,int osd,u32 aff) { -BUG_ON (osd >= map->max_osd); -if (!map->osd_primary_affinity) {int i;
@@ -1577,6 +1573,8 @@ static int decode_new_primary_affinity(vceph_decode_32_safe (p, end, osd, e_inval);ceph_decode_32_safe (p, end, aff, e_inval); +if (osd >= map->max_osd) + goto e_inval; ret =set_primary_affinity (map, osd, aff);if (ret)
@@ -1879,7 +1877,9 @@ static int decode_new_up_state_weight(voceph_decode_need (p, end,2 *sizeof (u32), e_inval); osd =ceph_decode_32 (p); w =ceph_decode_32 (p); -BUG_ON (osd >= map->max_osd); +if (osd >= map->max_osd) + goto e_inval; +osdmap_info (map,"osd%d weight 0x%x %s\n" , osd, w, w ==CEPH_OSD_IN ?"(in)" : (w ==CEPH_OSD_OUT ?"(out)" :"" ));
@@ -1905,13 +1905,15 @@ static int decode_new_up_state_weight(vou32 xorstate; osd =ceph_decode_32 (p); +if (osd >= map->max_osd) + goto e_inval; +if (struct_v >=5 ) xorstate =ceph_decode_32 (p);else xorstate =ceph_decode_8 (p);if (xorstate ==0 ) xorstate =CEPH_OSD_UP ; -BUG_ON (osd >= map->max_osd);if ((map->osd_state[osd] &CEPH_OSD_UP ) && (xorstate &CEPH_OSD_UP ))osdmap_info (map,"osd%d down\n" , osd);
@@ -1937,7 +1939,9 @@ static int decode_new_up_state_weight(vostruct ceph_entity_addr addr; osd =ceph_decode_32 (p); -BUG_ON (osd >= map->max_osd); +if (osd >= map->max_osd) + goto e_inval; +if (struct_v >=7 ) ret =ceph_decode_entity_addrvec (p, end, msgr2, &addr);else
Greg Kroah-Hartman
maintainerPATCH 553/568 nfsd: Replace clamp_t in nfsd4_get_drc_mem()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
A recent change to clamp_t() in 6.1.y caused fs/nfsd/nfs4state.c to fail to compile with gcc-9. The code in nfsd4_get_drc_mem() was written with the assumption that when "max < min",
clamp(val, min, max)
would return max. This assumption is not documented as an API promise and the change caused a compile failure if it could be statically determined that "max < min".
The relevant code was no longer present upstream when commit 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()") landed there, so there is no upstream change to nfsd4_get_drc_mem() to backport.
There is no clear case that the existing code in nfsd4_get_drc_mem() is functioning incorrectly. The goal of this patch is to permit the clean application of commit 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()"), and any commits that depend on it, to LTS kernels without affecting the ability to compile those kernels. This is done by open-coding the __clamp() macro sans the built-in type checking.
Stable-dep-of: 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()")
Reviewed_by: David Laight <[email protected]>
--- fs/nfsd/nfs4state.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
Changes since Neil's post:
* Editorial changes to the commit message
* Attempt to address David's review comments
* Applied to linux-6.12.y, passed NFSD upstream CI suite
This patch is intended to be applied to linux-6.12.y, and should apply cleanly to other LTS kernels since nfsd4_get_drc_mem hasn't changed since v5.4.
fs/nfsd/nfs4state.c +4 -2
@@ -1823,8 +1823,10 @@ static u32 nfsd4_get_drc_mem(struct nfsd*/ scale_factor = max_t(unsigned int, 8, nn->nfsd_serv->sv_nrthreads); - avail = clamp_t(unsigned long, avail, slotsize, - total_avail/scale_factor); +if (avail > total_avail / scale_factor) + avail = total_avail / scale_factor; +else if (avail < slotsize) + avail = slotsize; num =min_t (int, num, avail / slotsize); num =max_t (int, num,1 ); nfsd_drc_mem_used += num * slotsize;
Greg Kroah-Hartman
maintainerPATCH 554/568 usb: renesas_usbhs: Convert to platform remove callback returning void
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
[ Upstream commit 456a91ce7de4b9157fd5013c1e4dd8dd3c6daccb ]
The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new() which already returns void. Eventually after all drivers are converted, .remove_new() is renamed to .remove().
Trivially convert this driver from always returning zero in the remove callback to the void returning variant.
Stable-dep-of: eb9ac779830b ("usb: renesas_usbhs: Fix synchronous external abort on unbind")
--- drivers/usb/renesas_usbhs/common.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/usb/renesas_usbhs/common.c +2 -4
@@ -790,7 +790,7 @@ probe_pm_disable:return ret; } -static int usbhs_remove (struct platform_device *pdev) +static void usbhs_remove (struct platform_device *pdev) {struct usbhs_priv *priv =usbhs_pdev_to_priv (pdev);
@@ -810,8 +810,6 @@ static int usbhs_remove(struct platform_usbhs_mod_remove (priv);usbhs_fifo_remove (priv);usbhs_pipe_remove (priv); - -return 0 ; }static __maybe_unused int usbhsc_suspend (struct device *dev)
@@ -856,7 +854,7 @@ static struct platform_driver renesas_us .of_match_table = of_match_ptr(usbhs_of_match), }, .probe = usbhs_probe, - .remove = usbhs_remove, + .remove_new = usbhs_remove, };module_platform_driver (renesas_usbhs_driver);
Greg Kroah-Hartman
maintainerPATCH 555/568 usb: renesas_usbhs: Fix synchronous external abort on unbind
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudiu Beznea <[email protected]>
[ Upstream commit eb9ac779830b2235847b72cb15cf07c7e3333c5e ]
A synchronous external abort occurs on the Renesas RZ/G3S SoC if unbind is executed after the configuration sequence described above:
modprobe usb_f_ecm
modprobe libcomposite
modprobe configfs
cd /sys/kernel/config/usb_gadget
mkdir -p g1
cd g1
echo "0x1d6b" > idVendor
echo "0x0104" > idProduct
mkdir -p strings/0x409
echo "0123456789" > strings/0x409/serialnumber echo "Renesas." > strings/0x409/manufacturer echo "Ethernet Gadget" > strings/0x409/product mkdir -p functions/ecm.usb0
mkdir -p configs/c.1
mkdir -p configs/c.1/strings/0x409
echo "ECM" > configs/c.1/strings/0x409/configuration
if [ ! -L configs/c.1/ecm.usb0 ]; then
ln -s functions/ecm.usb0 configs/c.1
fi
echo 11e20000.usb > UDC
echo 11e20000.usb > /sys/bus/platform/drivers/renesas_usbhs/unbind
The displayed trace is as follows:
Internal error: synchronous external abort: 0000000096000010 [#1] SMP CPU: 0 UID: 0 PID: 188 Comm: sh Tainted: G M 6.17.0-rc7-next-20250922-00010-g41050493b2bd #55 PREEMPT Tainted: [M]=MACHINE_CHECK Hardware name: Renesas SMARC EVK version 2 based on r9a08g045s33 (DT) pstate: 604000c5 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : usbhs_sys_function_pullup+0x10/0x40 [renesas_usbhs] lr : usbhsg_update_pullup+0x3c/0x68 [renesas_usbhs] sp : ffff8000838b3920 x29: ffff8000838b3920 x28: ffff00000d585780 x27: 0000000000000000 x26: 0000000000000000 x25: 0000000000000000 x24: ffff00000c3e3810 x23: ffff00000d5e5c80 x22: ffff00000d5e5d40 x21: 0000000000000000 x20: 0000000000000000 x19: ffff00000d5e5c80 x18: 0000000000000020 x17: 2e30303230316531 x16: 312d7968703a7968 x15: 3d454d414e5f4344 x14: 000000000000002c x13: 0000000000000000 x12: 0000000000000000 x11: ffff00000f358f38 x10: ffff00000f358db0 x9 : ffff00000b41f418 x8 : 0101010101010101 x7 : 7f7f7f7f7f7f7f7f x6 : fefefeff6364626d x5 : 8080808000000000 x4 : 000000004b5ccb9d x3 : 0000000000000000 x2 : 0000000000000000 x1 : ffff800083790000 x0 : ffff00000d5e5c80 Call trace: usbhs_sys_function_pullup+0x10/0x40 [renesas_usbhs] (P) usbhsg_pullup+0x4c/0x7c [renesas_usbhs] usb_gadget_disconnect_locked+0x48/0xd4 gadget_unbind_driver+0x44/0x114 device_remove+0x4c/0x80 device_release_driver_internal+0x1c8/0x224 device_release_driver+0x18/0x24 bus_remove_device+0xcc/0x10c device_del+0x14c/0x404 usb_del_gadget+0x88/0xc0 usb_del_gadget_udc+0x18/0x30 usbhs_mod_gadget_remove+0x24/0x44 [renesas_usbhs] usbhs_mod_remove+0x20/0x30 [renesas_usbhs] usbhs_remove+0x98/0xdc [renesas_usbhs] platform_remove+0x20/0x30 device_remove+0x4c/0x80 device_release_driver_internal+0x1c8/0x224 device_driver_detach+0x18/0x24 unbind_store+0xb4/0xb8 drv_attr_store+0x24/0x38 sysfs_kf_write+0x7c/0x94 kernfs_fop_write_iter+0x128/0x1b8 vfs_write+0x2ac/0x350 ksys_write+0x68/0xfc __arm64_sys_write+0x1c/0x28 invoke_syscall+0x48/0x110 el0_svc_common.constprop.0+0xc0/0xe0 do_el0_svc+0x1c/0x28 el0_svc+0x34/0xf0 el0t_64_sync_handler+0xa0/0xe4 el0t_64_sync+0x198/0x19c Code: 7100003f 1a9f07e1 531c6c22 f9400001 (79400021) ---[ end trace 0000000000000000 ]--- note: sh[188] exited with irqs disabled note: sh[188] exited with preempt_count 1
The issue occurs because usbhs_sys_function_pullup(), which accesses the IP registers, is executed after the USBHS clocks have been disabled. The problem is reproducible on the Renesas RZ/G3S SoC starting with the addition of module stop in the clock enable/disable APIs. With module stop functionality enabled, a bus error is expected if a master accesses a module whose clock has been stopped and module stop activated.
Disable the IP clocks at the end of remove.
--- drivers/usb/renesas_usbhs/common.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/usb/renesas_usbhs/common.c +7 -7
@@ -798,18 +798,18 @@ static void usbhs_remove(struct platformflush_delayed_work (&priv->notify_hotplug_work); -/* power off */ -if (!usbhs_get_dparam (priv, runtime_pwctrl)) -usbhsc_power_ctrl (priv,0 ); - -pm_runtime_disable (&pdev->dev); -usbhs_platform_call (priv, hardware_exit, pdev); -usbhsc_clk_put (priv);reset_control_assert (priv->rsts);usbhs_mod_remove (priv);usbhs_fifo_remove (priv);usbhs_pipe_remove (priv); + +/* power off */ +if (!usbhs_get_dparam (priv, runtime_pwctrl)) +usbhsc_power_ctrl (priv,0 ); + +usbhsc_clk_put (priv); +pm_runtime_disable (&pdev->dev); }static __maybe_unused int usbhsc_suspend (struct device *dev)
Greg Kroah-Hartman
maintainerPATCH 556/568 iio: adc: rtq6056: Correct the sign bit index
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChiYuan Huang <[email protected]>
[ Upstream commit 9b45744bf09fc2a3287e05287141d6e123c125a7 ]
The vshunt/current reported register is a signed 16bit integer. The sign bit index should be '15', not '16'.
--- drivers/iio/adc/rtq6056.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/rtq6056.c +1 -1
@@ -171,7 +171,7 @@ static int rtq6056_adc_read_channel(struif (addr ==RTQ6056_REG_BUSVOLT || addr ==RTQ6056_REG_POWER ) *val = regval;else - *val =sign_extend32 (regval,16 ); + *val =sign_extend32 (regval,15 );return IIO_VAL_INT ; }
Greg Kroah-Hartman
maintainerPATCH 557/568 net: macb: fix unregister_netdev call order in macb_remove()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: luoguangfei <[email protected]>
[ Upstream commit 01b9128c5db1b470575d07b05b67ffa3cb02ebf1 ]
When removing a macb device, the driver calls phy_exit() before unregister_netdev(). This leads to a WARN from kernfs:
------------[ cut here ]------------
kernfs: can not remove 'attached_dev', no directory
WARNING: CPU: 1 PID: 27146 at fs/kernfs/dir.c:1683
Call trace:
kernfs_remove_by_name_ns+0xd8/0xf0
sysfs_remove_link+0x24/0x58
phy_detach+0x5c/0x168
phy_disconnect+0x4c/0x70
phylink_disconnect_phy+0x6c/0xc0 [phylink]
macb_close+0x6c/0x170 [macb]
...
macb_remove+0x60/0x168 [macb]
platform_remove+0x5c/0x80
...The warning happens because the PHY is being exited while the netdev is still registered. The correct order is to unregister the netdev before shutting down the PHY and cleaning up the MDIO bus.
Fix this by moving unregister_netdev() ahead of phy_exit() in macb_remove().
--- drivers/net/ethernet/cadence/macb_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/cadence/macb_main.c +1 -1
@@ -5068,11 +5068,11 @@ static int macb_remove(struct platform_dif (dev) { bp =netdev_priv (dev); +unregister_netdev (dev);phy_exit (bp->sgmii_phy);mdiobus_unregister (bp->mii_bus);mdiobus_free (bp->mii_bus); -unregister_netdev (dev);tasklet_kill (&bp->hresp_err_tasklet);pm_runtime_disable (&pdev->dev);pm_runtime_dont_use_autosuspend (&pdev->dev);
Greg Kroah-Hartman
maintainerPATCH 558/568 selftests: mptcp: join: endpoints: longer transfer
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Matthieu Baerts (NGI0)" <[email protected]>
[ Upstream commit 6457595db9870298ee30b6d75287b8548e33fe19 ]
In rare cases, when the test environment is very slow, some userspace tests can fail because some expected events have not been seen.
Because the tests are expecting a long on-going connection, and they are not waiting for the end of the transfer, it is fine to make the connection longer. This connection will be killed at the end, after the verifications, so making it longer doesn't change anything, apart from avoid it to end before the end of the verifications
To play it safe, all endpoints tests not waiting for the end of the transfer are now sharing a longer file (128KB) at slow speed.
[ Conflicts in mptcp_join.sh because commit 0c93af1f8907 ("selftests:
mptcp: drop test_linkfail parameter") is not in this version. It moved the 4th parameter to an env var. To fix the conflicts, the new value simply needs to be added as the 4th argument instead of an env var. ]
--- tools/testing/selftests/net/mptcp/mptcp_join.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_join.sh +4 -4
@@ -3313,7 +3313,7 @@ endpoint_tests() pm_nl_set_limits $ns1 2 2 pm_nl_set_limits $ns2 2 2 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal - run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow 2>/dev/null & + run_tests $ns1 $ns2 10.0.1.1 128 0 0 slow 2>/dev/null & wait_mpj $ns1 pm_nl_check_endpoint 1 "creation" \
@@ -3336,7 +3336,7 @@ endpoint_tests() pm_nl_set_limits $ns2 0 3 pm_nl_add_endpoint $ns2 10.0.1.2 id 1 dev ns2eth1 flags subflow pm_nl_add_endpoint $ns2 10.0.2.2 id 2 dev ns2eth2 flags subflow - run_tests $ns1 $ns2 10.0.1.1 4 0 0 speed_5 2>/dev/null & + run_tests $ns1 $ns2 10.0.1.1 128 0 0 speed_5 2>/dev/null & local tests_pid=$! wait_mpj $ns2
@@ -3401,7 +3401,7 @@ endpoint_tests() # broadcast IP: no packet for this address will be received on ns1 pm_nl_add_endpoint $ns1 224.0.0.1 id 2 flags signal pm_nl_add_endpoint $ns1 10.0.1.1 id 42 flags signal - run_tests $ns1 $ns2 10.0.1.1 4 0 0 speed_5 2>/dev/null & + run_tests $ns1 $ns2 10.0.1.1 128 0 0 speed_5 2>/dev/null & local tests_pid=$! wait_mpj $ns2
@@ -3464,7 +3464,7 @@ endpoint_tests() # broadcast IP: no packet for this address will be received on ns1 pm_nl_add_endpoint $ns1 224.0.0.1 id 2 flags signal pm_nl_add_endpoint $ns2 10.0.3.2 id 3 flags subflow - run_tests $ns1 $ns2 10.0.1.1 4 0 0 speed_20 2>/dev/null & + run_tests $ns1 $ns2 10.0.1.1 128 0 0 speed_20 2>/dev/null & local tests_pid=$! wait_attempt_fail $ns2
Greg Kroah-Hartman
maintainerPATCH 559/568 mptcp: fix duplicate reset on fastclose
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
commit ae155060247be8dcae3802a95bd1bdf93ab3215d upstream.
The CI reports sporadic failures of the fastclose self-tests. The root cause is a duplicate reset, not carrying the relevant MPTCP option. In the failing scenario the bad reset is received by the peer before the fastclose one, preventing the reception of the latter.
Indeed there is window of opportunity at fastclose time for the following race:
mptcp_do_fastclose
__mptcp_close_ssk
__tcp_close()
tcp_set_state() [1]
tcp_send_active_reset() [2]After [1] the stack will send reset to in-flight data reaching the now closed port. Such reset may race with [2].
Address the issue explicitly sending a single reset on fastclose before explicitly moving the subflow to close status.
[ Conflicts in protocol.c, because commit bbd49d114d57 ("mptcp:
consolidate transition to TCP_CLOSE in mptcp_do_fastclose()") is not in this version. It introduced a new line in the context. The same modification can still be applied.
Also, tcp_send_active_reset() doesn't take a 3rd argument (sk_rst_reason) in this version, see commit 5691276b39da ("rstreason:
prepare for active reset"). This argument is only helpful for tracing, it is fine to drop it. ]
--- net/mptcp/protocol.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-)
net/mptcp/protocol.c +21 -13
@@ -2440,7 +2440,6 @@ bool __mptcp_retransmit_pending_data(str/* flags for __mptcp_close_ssk() */ #define MPTCP_CF_PUSH BIT(1) -#define MPTCP_CF_FASTCLOSE BIT(2)/* be sure to send a reset only if the caller asked for it, also * clean completely the subflow status when the subflow reaches
@@ -2451,7 +2450,7 @@ static void __mptcp_subflow_disconnect(s unsigned int flags) {if (((1 << ssk->sk_state) & (TCPF_CLOSE |TCPF_LISTEN )) || - (flags &MPTCP_CF_FASTCLOSE )) { + subflow->send_fastclose) {/* The MPTCP code never wait on the subflow sockets, TCP-level * disconnect should never fail */
@@ -2498,14 +2497,8 @@ static void __mptcp_close_ssk(struct soclock_sock_nested (ssk,SINGLE_DEPTH_NESTING ); -if ((flags &MPTCP_CF_FASTCLOSE ) && !__mptcp_check_fallback (msk)) { -/* be sure to force the tcp_close path -* to generate the egress reset -*/ - ssk->sk_lingertime =0 ; -sock_set_flag (ssk,SOCK_LINGER ); - subflow->send_fastclose =1 ; - } +if (subflow->send_fastclose && ssk->sk_state !=TCP_CLOSE ) +tcp_set_state (ssk,TCP_CLOSE ); need_push = (flags &MPTCP_CF_PUSH ) &&__mptcp_retransmit_pending_data (sk);if (!dispose_it) {
@@ -2794,9 +2787,24 @@ static void mptcp_do_fastclose(struct sostruct mptcp_subflow_context *subflow, *tmp;struct mptcp_sock *msk =mptcp_sk (sk); -mptcp_for_each_subflow_safe (msk, subflow, tmp) -__mptcp_close_ssk (sk,mptcp_subflow_tcp_sock (subflow), - subflow,MPTCP_CF_FASTCLOSE ); +/* Explicitly send the fastclose reset as need */ +if (__mptcp_check_fallback (msk)) +return ; + +mptcp_for_each_subflow_safe (msk, subflow, tmp) { +struct sock *ssk =mptcp_subflow_tcp_sock (subflow); + +lock_sock (ssk); + +/* Some subflow socket states don't allow/need a reset.*/ +if ((1 << ssk->sk_state) & (TCPF_LISTEN |TCPF_CLOSE )) + goto unlock; + + subflow->send_fastclose =1 ; +tcp_send_active_reset (ssk, ssk->sk_allocation); +unlock: +release_sock (ssk); + } }static void mptcp_worker (struct work_struct *work)
Greg Kroah-Hartman
maintainerPATCH 560/568 mptcp: Fix proto fallback detection with BPF
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <[email protected]>
commit c77b3b79a92e3345aa1ee296180d1af4e7031f8f upstream.
The sockmap feature allows bpf syscall from userspace, or based on bpf sockops, replacing the sk_prot of sockets during protocol stack processing with sockmap's custom read/write interfaces.
'''tcp_rcv_state_process()
syn_recv_sock()/subflow_syn_recv_sock()
tcp_init_transfer(BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB)
bpf_skops_established <== sockops
bpf_sock_map_update(sk) <== call bpf helper
tcp_bpf_update_proto() <== update sk_prot'''
When the server has MPTCP enabled but the client sends a TCP SYN without MPTCP, subflow_syn_recv_sock() performs a fallback on the subflow, replacing the subflow sk's sk_prot with the native sk_prot. '''subflow_syn_recv_sock()
subflow_ulp_fallback()
subflow_drop_ctx()
mptcp_subflow_ops_undo_override()
'''
Then, this subflow can be normally used by sockmap, which replaces the native sk_prot with sockmap's custom sk_prot. The issue occurs when the user executes accept::mptcp_stream_accept::mptcp_fallback_tcp_ops(). Here, it uses sk->sk_prot to compare with the native sk_prot, but this is incorrect when sockmap is used, as we may incorrectly set sk->sk_socket->ops.
This fix uses the more generic sk_family for the comparison instead.
Additionally, this also prevents a WARNING from occurring:
result from ./scripts/decode_stacktrace.sh:
------------[ cut here ]------------ WARNING: CPU: 0 PID: 337 at net/mptcp/protocol.c:68 mptcp_stream_accept \ (net/mptcp/protocol.c:4005) Modules linked in:
...
PKRU: 55555554
Call Trace: <TASK>
do_accept (net/socket.c:1989)__sys_accept4 (net/socket.c:2028 net/socket.c:2057) __x64_sys_accept (net/socket.c:2067)x64_sys_call (arch/x86/entry/syscall_64.c:41)do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
RIP: 0033:0x7f87ac92b83d ---[ end trace 0000000000000000 ]---
[ Conflicts in protocol.c, because commit 8e2b8a9fa512 ("mptcp: don't
overwrite sock_ops in mptcp_is_tcpsk()") is not in this version. It changes the logic on how and where the sock_ops is overridden in case of passive fallback. To fix this, mptcp_is_tcpsk() is modified to use the family, but first, a check of the protocol is required to continue returning 'false' in case of MPTCP socket. ]
--- net/mptcp/protocol.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
net/mptcp/protocol.c +7 -2
@@ -79,8 +79,13 @@ static u64 mptcp_wnd_end(const struct mpstatic bool mptcp_is_tcpsk (struct sock *sk) {struct socket *sock = sk->sk_socket; +unsigned short family; -if (unlikely (sk->sk_prot == &tcp_prot)) { +if (likely (sk->sk_protocol ==IPPROTO_MPTCP )) +return false; + + family =READ_ONCE (sk->sk_family); +if (unlikely (family ==AF_INET )) {/* we are being invoked after mptcp_accept() has * accepted a non-mp-capable flow: sk is a tcp_sk, * not an mptcp one.
@@ -91,7 +96,7 @@ static bool mptcp_is_tcpsk(struct sock * sock->ops = &inet_stream_ops;return true;#if IS_ENABLED (CONFIG_MPTCP_IPV6 ) - } else if (unlikely(sk->sk_prot == &tcpv6_prot)) { + } else if (unlikely(family == AF_INET6)) { sock->ops = &inet6_stream_ops;return true;#endif